Flexible Height Div with Max-Height?

Ok, I have a bit of a CSS conundrum that I’ve revisited numerous times but without resolution. On an internal web application I’ve developed, I have a lightbox-style popup div that presents a form to the user. The height of the popup div is flexible, as in it grows with the height of the content until the content exceeds the maximum height specified on the absolutely positioned container (84%), in which case a scrollbar appears. The problem is that the header and footer are meant to be fixed, but the currently implementation causes the header and footer to be at the top and bottom of the content respectively, so when one scrolls down, the close button goes out of view, and vice versa for the save button at the bottom. There’s no way around this in the current implementation.

I’ve tried other implementations, but I’ve so far found no way to achieve both a fixed header and footer as well as maintaining the flexible height (up to a maximum).

Here are two examples. One has flexible height but with scrolling header and footer (represented as blue div’s), while the second example allows the header and footer to be fixed, but requires that the container always takes up 84% of the window, even if there’s hardly any content. Be sure to play with the amount of content in the body div so you can see the behaviour of each under different conditions.

I essentially want the best of both worlds. The first example would be perfect, if only the container shrunk when there wasn’t much content, and vice versa, the second example would otherwise be perfect, if only the header and footer were fixed.

Here’s hoping there’s a CSS trick to accomplish what I’ve after without reverting to an ugly JavaScript solution.

Thanks

Maybe I missed the mark. And I kinda sort of had to cheat anyway ( I used box-sizing), but hopefully this helps:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
	<head>
		<title></title>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<style type="text/css">
				body, html {height:100%}
				body, html, h2, h3 {margin:0; padding:0}
				.outter{
					position: relative;
					margin: -1px 25%;
					top:8%;
					height: 84%;
					overflow: auto;
					padding:50px  0;
					-moz-box-sizing: border-box ;
					-webkit-box-sizing: border-box;
					box-sizing: border-box;
					border: 1px solid pink;
					min-height: 4em;
 				}
				.content {
 					overflow: auto;
					height: 100%;
				}
				h2,h3{position: absolute; background: pink; width: 100%;  height: 50px}
				h2{top:0}
				h3{bottom:0}
		</style>
	</head>
	<body>
			<div class="outter">
				<div class="content">
					<h2>Representing the fixed header</h2>
					Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.lorem
					<h3>Representing the fixed Footer</h3>
				</div>
			</div>
	</body>
</html>

The premise here being that you need an outer container to place everything on the screen, and to serve as a positioning reference for the FIXED HEIGHT header and footer. This outer container is your over all height (84%). We make room for the header and footer by adding padding. Of course , the padding would have foobarred the height of the outer container :confused: , which is why I used box-sizing. Then you need an INNER container that is set to height:100% and overflow:auto. and finally content…

If the content is more than 100% of the height of the inner container then it will overflow and thus you get scroll bars as needed.

Thanks Dresden, but I already have a solution that achieves what yours achieves as linked to in my original post. The problem is that the overlaying div always consumes 84% height, even if the contents only needs a fraction of that. Because this overlay is used for other things like alerts, etc, it’s unfortunately not an acceptable solution, hence why I’m on these forums.

Hi,

Did you mean something like this:


<!DOCTYPE html>
<html>
<head>
<style>
html, body {
	height: 100%;
	padding: 0;
	margin: 0;
}
#container {
	position: absolute;
	width: 600px;
	margin-left: -300px;
	left: 50%;
	top: 8%;
	border: 5px black solid;
	box-shadow: 0px 0px 15px rgba(0,0,0,0.75);
	box-sizing: border-box;
	max-height: 84%;
	overflow-y: scroll;
}
#header, #footer {
	position:absolute;
	top:0;
	left:0;
	height: 34px;
	width: 582px;
}
#footer {
	top:auto;
	bottom:0;
}
.inner {
	position:fixed;
	width:582px;
	background:blue;
	height:34px;
}
#body {
	background: pink;
	padding:34px 0
}
</style>
</head>
<body>
<div id="container">
		<div id="header">
				<div class="inner">Header</div>
		</div>
		<div id="body"> start Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				Hello<br/>
				finish<br/>
		</div>
		<div id="footer">
				<div class="inner">Footer</div>
		</div>
</div>
</body>
</html>

Not ie6 compatible of course.

Thanks Paul, that seems to do what I’m after. Now to sit down and see what sort of black magic you’ve used to achieve it :). I should have mentioned that the only requirement is IE8 compatibility. It’s for internal use so as long as it works in all modern browsers and IE8, it’s a pass.

So it seems it’s the use of “position: fixed” on the headers and footers that makes this work. This goes against my assumptions of how “position: fixed” worked. I thought that position fixed automatically sent elements to the top left of the viewport unless position properties (top, bottom, left, right) were specified. It seems instead, what happens is that fixed elements without explicit CSS positioning are first positioned relative to the document flow. It then seems their offset (relative to the viewport) from where they appear in the document flow is maintained as the viewport scrolls. Very interesting.

Yes positioned elements are always placed in relation to the viewport. However, if you don’t explicitly position them then they are auto positioned meaning that they become fixed at that exact point that they were in the flow of the document. So the secret is to make sure the element is where you want it to be and then apply fixed positioning to the inner element.

You must though make sure that the fixed element never goes outside the viewport or you won’t be able to scroll to it.