views:

86

answers:

3

I have a div with position:fixed that is my container div for some menus. I've set it to top:0px, bottom:0px to always fill the viewport. Inside that div I want to have 2 other divs, the lower one of which contains lots of lines and has overflow:auto. I would expect that it would be contained within the container div, but if there are too many lines it simply expands outside the fixed div. Below is my code and a screenshot to clarify:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<head>
    <title>MyPlan</title>
    <meta name="X-UA-COMPATIBLE" value="IE=8" />
    <style type="text/css">
        #outerfixed { position:fixed;  width:200px;  background-color:blue; padding:5px; top:0px; bottom:30px;}
        #innerstatic1 { width:100%; background-color:yellow; height:100px;}
        #innerstatic2 { overflow:auto; background-color:red; width:100%;}
    </style>
</head>
<body>
    <div id="outerfixed">
        <h3>OUTERFIXED</h3>
        <div id="innerstatic1">
            <h3>INNERSTATIC1</h3>
        </div>
        <div id="innerstatic2">
            <h3>INNERSTATIC2</h3>
            line<br />
                        ...lots of lines
            line<br />
        </div>
    </div>
</body>
</html>

alt text

Is there any way for me to do this? Again, I want #innerstatic2 to be properly contained within #outerfixed and get scrollbars if it gets bigger than the space it has inside #outerfixed.

I know there are some possibilites to hack around this by also fixing #innerstatic2, but I would really like it to be within the flow inside #outerfixed if possible, so that if I move #outerfixed somewhere, the inner element would come with it.

EDIT: I know I can set overflow:auto on the #outerfixed and get a scrollbar on the whole thing, but I specifically want a scrollbar just on #innerstatic2, it is a grid and I want to scroll just the grid.

Anyone? Possible?

A: 

It is the container div who has to be with the overflow:auto attribute. In this case, the #outerfixed div

Alejandro Martin
Sorry, I should have been more clear. I explicitly want the scrollbar to only be on the #innerstatic2 element. It is a grid and I want to scroll only the grid, not the whole container.
Einar Egilsson
+3  A: 

There's a two-step solution for this, but it comes at something of a cost:

  1. Add overflow-y: scroll; to the css for #innerstatic2.
  2. define a height (or max-height) for #innerstatic2, otherwise it won't overflow, it'll just keep increasing its height (the default for a div is height: auto).


Edited because I just can't stop myself, sometimes.

I've posted a demo on jsbin to show a jQuery implementation of this, which will calculate a height for you (it's not generalised, so it'll only work with your current html).

(function($) {
  $.fn.innerstaticHeight = function() {
        var heightOfOuterfixed = $('#outerfixed').height(),
        offset = $('#innerstatic2').offset(),
        topOfInnerstatic2 = offset.top,
        potentialHeight = heightOfOuterfixed - topOfInnerstatic2;

        $('#innerstatic2').css('height',potentialHeight);
  }
})(jQuery);

$(document).ready(
    function() {
        $('#innerstatic2').innerstaticHeight();
    }
);
David Thomas
Thank you for the answer. Actually this is pretty much what we have today, calculate the right height for #innerstatic2 and set with jquery. But this is causing problems with a third party component that calculates some sizes incorrectly when we mess with this in document ready, so that's why I really wanted a pure CSS solution.
Einar Egilsson
So, is there no way to force scroll on #innerstatic2 by setting the height on #outerfixed? From what I've tried it seems not, #innerstatic2 just flows outside if I set an explicit height on #outerfixed, but is that because it is position:fixed?
Einar Egilsson
It could be. You can also add `overflow: hidden` to the css for `#outerfixed`, but that doesn't *look* particularly pretty, unfortunately.
David Thomas
+1  A: 

The only way I figure, is to set innerstatic2 to absolute position (so you can use top and bottom to size it in relation to outerfixed), then inside innerstatic2 create another div where you put your text in. Then you give innerstatic2 the "overflow: auto;" indication. The drawback of this method, that innerstatic2 does not move down, when innerstatic1 grows, since it has to be position absolutely. If it needs to move, it must be "position: relative", but then you need to set a fixed height for it. So either way you have to settle for a compromise.

Once all browsers support the newer CSS3 features, like the calculation support, there will be better options to do this, without these drawbacks.

Eric J. Francois