Scrolling nested divs
April 4, 2008 10:38 AM   Subscribe

Is it possible, with HTML and CSS, to nest a two divs, such that the inner div has a height relative to the outer div so that other content in the outer div can display?

Sorry if that wasn't clear. Here's a longer and hopefully clearer explanation of the problem:

I presently have some code that takes a list, of arbitrary length, and displays it inside a div with position:fixed. A "Close" button sits below the list inside the div. This works great when the list is short, but sometimes the list is too long and continues below the bottom of the browser window. Since the position is fixed, there's no way to scroll down to see more of it.

My first thought was to set a max-width for the div and set its overflow to 'scroll'. This works, but then you have to scroll to get to the 'Close' button.

I'd like to have it so that the list is in a div inside the first div, and is scrollable, but the 'Close' button is visible regardless of the scroll position. The problem I'm having is that if I set the max-height of the inner div to a percentage, it's completely ignored and the list spills out past the bottom of the outer div. If I set the max-height to an absolute value (say 20em) then it works fine, but I'd like to keep it relative to avoid it being unnecessarily small on a large monitor.

This is the HTML I'm using now (with the spill problem):

<div id='outer'>
<div id="inner">
The list goes in here
</div>
<button id="close" onclick="close_box()">Close</button>
</div>


With this CSS:
div#outer {
max-height: 75%;
}
div#inner {
max-height: 85%;
overflow-y: scroll;
}
posted by Godbert to Computers & Internet (12 answers total) 2 users marked this as a favorite
 
Not-thinking-filter: Can you put the close button at the top?
posted by unixrat at 11:00 AM on April 4, 2008


I'm sorry, I still can't picture the problem. Is there any way you can get some screenshots? You mentioned that the list was position: fixed, but I don't see that in your sample CSS. You are testing your code in Firefox, right? Old versions of IE hate max-height.
posted by theiconoclast31 at 11:34 AM on April 4, 2008


Take the close button out of the flow by absolutely positioning it.

Set out to 'relative' and then it becomes the parent, not the entire browser window.


#outer { position: relative; }
#close { position: absolute; bottom: 0; }

posted by kamelhoecker at 11:46 AM on April 4, 2008


div#outer {
position: fixed;
height: 75%;
width: 75%;
}
div#inner {
overflow-y: auto;
position: absolute;
top: 0px;
bottom: 24px; /* leaves room at the bottom for the button */
}
#close {
position: absolute;
bottom: 0;
}


I subbed height for max-height. Don’t know if that will make a significant diff in your situation. max-height isn’t consistently supported in different browsers.
posted by breaks the guidelines? at 11:48 AM on April 4, 2008


What breaks the guidelines? said about max-height. Oh how I wish it worked well and consistantly...

Have you considered using JS either for your positioning or for sizing things? This seems like a situation where it would be acceptable, and you'd get a lot more control.
posted by Artw at 11:55 AM on April 4, 2008


unixrat: Moving the close button to the top is my option of last resort. I'd prefer to keep at the bottom, if at all possible, and I'm not sure that putting it at the top really solves all the problems, as the inner div would still have scroll issues. This could be worked around making the outer div the one that scrolls, but then the button isn't always visible.

theiconoclast31: I put a screenshot of the result of my try up: here. The end of the gray background is the bottom of div#outer; I'd like to get div#inner to also end there, and have scrollbars if necessary ("overflow-y: auto", basically, though my example shows "overflow-y: scroll").
In trying to simplify things a little bit, I did forget to include the position: fixed part; div#outer also has CSS class 'box' which gives it "position: fixed; left: 10px; top: 10px;". Yes, this is being done in Firefox; it's a personal thing of mine, so cross-browser compatibility isn't a big issue, and IE fails at so much else of this I don't want to put in all the effort to hack it to make it work in IE.

kamelhoecker: In this case, the reason I don't want to make #outer relative, and the reason it's "position: fixed" in the first place, is that it's something meant to pop up over the 'background' of the main content.

breaks the guidelines?: I tried using that CSS and both divs basically disappeared off the top of the browser; all I would see was about half of the 'Close' button.
posted by Godbert at 12:11 PM on April 4, 2008


Well, I tried just changing 'max-height' to 'height' in the original code, and now it works great for the case when it scrolls, but not so well for the case when it doesn't need to (the outer div takes up 75% of the vertical space). Naturally, replacing that with 'max-height' brings back the unwanted behavior.
posted by Godbert at 12:19 PM on April 4, 2008


Be sure to set a min-height if you must use max-height.
posted by breaks the guidelines? at 12:22 PM on April 4, 2008


is it be possible to set the divs to not be fixed?

Try this: float:left on the outer div and inner one. position them both relative, then set the overflow on the outer div to be hidden. This should allow you to get the scroll bars you need on the viewport. I am personally not comfortable with fixed position divs, I usually use flowing liquid layouts. Hope it helps!
posted by joelf at 12:23 PM on April 4, 2008


Also, isolate your problems; test the code on a page that only contains the elements you’re working with. Integration comes later.
posted by breaks the guidelines? at 12:24 PM on April 4, 2008


I'd also recommend using a reset and buildup code.

I've made my own here. it might help
posted by joelf at 12:25 PM on April 4, 2008


Have you tried kamelhoecker's suggestion yet?

I would put the button in a div, position it absolutely at the bottom of the parent, give it a background color to match the parent. Then I would add a bottom margin on the inner div that matches the height of the absolutely positioned div, so that when you scroll all the way to the bottom, no content is obscured.
posted by misterbrandt at 1:30 PM on April 4, 2008


« Older Insteon, Z-Wave and Zigbee, oh my. (Which...   |   Life and Dead(wood) Connection Newer »
This thread is closed to new comments.