Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I have vertically fixed div element?

I would like to have vertically but not horizontally fixed div element. Currently, I am using jQuery to update the position top every time scroll occurs, but I don't want it seeing moving. I would like it to be fixed without moving. Is there a way to do this?

 -----------------
|         |       |
|         |       |
| div A   | div B |
|         |       |
|         |       |
|         |       |
 -----------------

Scrolling down

 -----------------
| div A   |       |
|         |       |
|         | div B |
|         |       |
|         |       |
|         |       |
 -----------------

I would like to be able keep Div B vertically fixed while Div A scrolls down and up. But when I scroll to the right and left, I wand Div A and Div B to move.

I noticed that Twitter uses something similar. Once you click on a tweet, the element on the right that display the tweet detail, is veridically fixed. I am not sure how they are doing it. See the second image, when scrolling down the right panel stays fixed.

enter image description here

Second image:

enter image description here

like image 268
Sam Avatar asked Dec 12 '11 13:12

Sam


People also ask

How do you vertically align a fixed element?

If you need to center the fixed element both horizontally and vertically, set the top, left, and transform properties as follows: top: 50%; left: 50%; transform: translate(-50%, -50%);

How do I keep my div position fixed?

A pinned-down menu. The interesting rule here is the ' position: fixed ', that makes the DIV stay fixed on the screen. The ' top: 50% ' and ' right: 0 ' determine where the DIV is displayed, in this case: 50% down from the top of the window, and a constant 0px from the right.

Does position fixed work on IOS?

CSS position:fixed is Fully Supported on Safari 15, which means that any user who'd be accessing your page through Safari 15 can see it perfectly.


3 Answers

Twitter uses a css property: position: fixed; which sure is the best way to go.

This does exactly what it says it does, it fixes the position. By using the top, right, bottom and left properties you can set the exact position of your div.


Edit 13-12-11 (awesome date!)

The property position: fixed; can not influence a positioning property over one axis only. This means, that you can not scroll left or right, like you want to.

I highly suggest you should either avoid surpassing the screen width, using percentages for your element's width. You can also just stick to your javascript.

You could however go for the method I suggested at first, but change the left property using a scroll event listener so that when you scroll, the left offset is increased or decreased. Because jQuery's bad-ass cross-browser support I'd go for jQuery. I think you can do practically the same with the prototype library, but I'm not familiar with that library.

jQuery (worked in google chrome):

var offset = 400; // left offset of the fixed div (without scrolling)

$(document).scroll(function(e) {
    // b is the fixed div
    $('.b').css({
        'left': offset - $(document).scrollLeft()
    });
});

Have a look at the live demo

You might need to change the document object to another object or selector of your choice.

like image 132
Tim S. Avatar answered Oct 28 '22 12:10

Tim S.


A whole lot of people want this, but unfortunately pure CSS does not offer a way to accomplish this very simple, very useful task. The only way that I have found is to give the div position:fixed. However, as you have found, this fixes the div on both the x and y axes.

This is a big failing in CSS, in my opinion. We really need something like CSS position:fixed-x and position:fixed-y. The only way I have found to do this is to have a piece of JavaScript code that's entered on a SetInterval( ) timeout (I use .10 second) that repositions the div on the axis that needs to change.

In your case (if I read your question correctly) you'd change the top: of DivB at each SetInterval( ) tick, moving DivB down to the position you want it in the viewport. Easy to do and it works, just a needless pain.

You might ask, and rightly, why you (and I) can't do this manipulation when the scroll event fires. The answer is that the scroll event doesn't fire in some versions of IE.

If you can make this depend upon scroll event cross-browserly, that would be a huge advance.

HTH.

like image 24
Pete Wilson Avatar answered Oct 28 '22 11:10

Pete Wilson


This is easily done with the correct markup and CSS. You need a container (div, section, etc.) to contain your two content areas. In the following example, I exploit the way JSFiddle renders the fiddle's content, but the technique is the same outside of JSFiddle.

Live example.

First, we need the markup:

<div id="container">
    <div id="divA">
        <p>This div will scroll.</p>
    </div>
    <div id="divB">
        <p>This div will not scroll.</p>
    </div>
</div>

Next, the CSS:

#container {
    height: 100%;
    postition: relative;
    width: 100%;
}

#divA {
    background: #ccc;
    height: 300%;  /* So we can see scrolling in action */
    left: 0;
    position: absolute;
    top: 0;
    width: 25%;
}

#divB {
    background: #c55;
    height: 100%;
    position: fixed;
    right: 0;
    width: 75%;
}

In this example, I take advantage of the fact that JSFiddle will create a view port of limited size. Thus, I can specify all of my sizes in percentages.

Notice that I set the container's position to relative. This is so that I can set the position model of divA and divB to "absolute" and "fixed" such that they will be positioned according to the box generated by "container". This is the key part of solving your problem.

like image 36
James Sumners Avatar answered Oct 28 '22 12:10

James Sumners