How to place a DIV to fill all the available space between the DIV header and DIV footer?

Say I have a parent div. Inside, there are three child DIVs: header, content, and footer. The header is attached to the top of the parent and fills it horizontally. The footer is attached to the bottom of the parent and fills it horizontally. Content should fill the entire space between the header and footer.

The parent must have a fixed width and height. The contents of the DIV should fill all the free space between the header and footer. When the content content of the DIV exceeds the space between the header and footer, the content of the DIV should display scroll bars and allow scrolling so that the contents of the footer are never closed and the footer is obscure content.

Now comes the tricky part: you don't know the height of the header or footer in advance (for example, the header and footer are populated dynamically). How to post content without using JavaScript ?

Example:

<div style="position : relative; width : 200px; height : 200px; background-color : #e0e0ff; overflow : hidden;"> <div style="background-color: #80ff80; position : absolute; left : 0; right : 0; top : 0;"> header </div> <div style="background-color: #8080ff; overflow : auto; position : absolute;"> content (how to position it?) </div> <div style="background-color: #ff8080; position : absolute; bottom : 0px; left :0; right : 0;"> footer </div> </div> 

To clarify this event , the target layout that I am trying to achieve will be used in a business application. The parent DIV will have a fixed but unknown size (for example, it will be exactly the size of the browser window, the size and size of the browser window by the user). Call the parent DIV screen.

The header will contain a set of filtering controls (such as text fields, drop-down lists and a filter button) that should be moved to the next line if there is not enough horizontal space (therefore, its height can change at any time to accommodate the breaking line). The title should always be visible and attached to the top on the screen.

The footer will contain a set of buttons, for example, in a dialog box. They can also be carried over to the next line if there is not enough space for horizontal display. The footer must be attached to the bottom of the "screen" to be accessible and visible at any time.

The content will contain the contents of the “screen”, such as dialog boxes, etc. If there are too few fields, the rest of the content will be “empty” (in this case, the footer should not start immediately after the content, but still attached to the bottom of the “screen”, which is a fixed size). If there are too many fields, the DIV content will provide a scroll bar for accessing hidden controls (in this case, the DIV content should not stretch below the footer, since the scroll bar will be partially hidden).

I hope this clarifies the issue once again, as my reputation is too low to introduce comments on your reps.

+7
html css
source share
6 answers

I'm going to get downmodded for this, but it sounds like work for a table.

What you are trying to do is set the total height of the three adjacent divs as units, and a 1x3 table with a height of 100% is actually a cleaner solution.

+4
source share

If you can avoid scrolling the main content, you might be better off using the footerStickAlt method to make sure your footer stays at the bottom of the screen or bottom of the content (if the content goes beyond the bottom of the screen).

+1
source share

Pure CSS 1 Solution - Flexbox:

You can create column divs that behave this way using the CSS3 display: flex; property display: flex; ( see W3 specifications )

Using a wrapper, you can align everything in a column with the declaration flex-direction: column; , and then fill the vertical space justify content: space-between; and height: 100vh; . Then all you have to do is make your content element extended with flex: 1 0 0; and give it a scrollbar with overflow-y: auto; .

Note on browser support . Although flexbox is supported by most modern browsers, there are a few more limitations (see http://caniuse.com/#feat=flexbox ). I would recommend using the -webkit- and -ms- .


Working example . See the following snippet and jsfiddle .

 body { display: -webkit-flex; /* Safari 6.1+ */ display: -ms-flex; /* IE 10 */ display: flex; -webkit-flex-direction: column; /* Safari 6.1+ */ -ms-flex-direction: column; /* IE 10 */ flex-direction: column; -webkit-justify-content: space-between; /* Safari 6.1+ */ -ms-justify-content: space-between; /* IE 10 */ justify-content: space-between; /* Header top, footer bottom */ height: 100vh; /* Fill viewport height */ } main { -webkit-flex: 1 0 0; /* Safari 6.1+ */ -ms-flex: 1 0 0; /* IE 10 */ flex: 1 0 0; /* Grow to fill space */ overflow-y: auto; /* Add scrollbar */ height: 100%; /* Needed to fill space in IE */ } header, footer { -webkit-flex: 0 0 auto; /* Safari 6.1+ */ -ms-flex: 0 0 auto; /* IE 10 */ flex: 0 0 auto; } /* Make it look a little nicer */ body { margin: 0; background-color: #8080ff; } header { background-color: #80ff80; } footer { background-color: #ff8080; } p { margin: 1.25rem; } 
 <body> <header> <p>header</p> </header> <main> <article> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pellentesque lobortis augue, in porta arcu dapibus dapibus. Suspendisse vulputate tempus venenatis. Pellentesque ac euismod urna. Donec dui odio, ullamcorper in posuere eu, laoreet sed nisl. Sed vitae vestibulum leo. Maecenas mattis lacus eget nisl malesuada, quis semper urna ornare. Praesent id mauris nec neque aliquet dignissim.</p> <p>Morbi varius dolor at lorem aliquet lacinia. Aliquam id lacinia quam. Sed vel libero felis. Etiam et pellentesque sem. Aenean bibendum, ante quis luctus tincidunt, elit mauris volutpat nisi, et tempus lectus sapien in mauris. Aliquam condimentum nisl ut elit accumsan hendrerit. Morbi mollis turpis est, id tincidunt ipsum rhoncus eget. Fusce in feugiat lacus. Quisque vel massa magna. Mauris varius congue nisl, vitae pellentesque diam ultricies at. Sed ac nibh ac diam tristique venenatis non nec nisl. Vivamus enim eros, pretium at iaculis nec, pharetra non sem. Aenean ac imperdiet odio.</p> <p>Morbi varius dolor at lorem aliquet lacinia. Aliquam id lacinia quam. Sed vel libero felis. Etiam et pellentesque sem. Aenean bibendum, ante quis luctus tincidunt, elit mauris volutpat nisi, et tempus lectus sapien in mauris. Aliquam condimentum nisl ut elit accumsan hendrerit. Morbi mollis turpis est, id tincidunt ipsum rhoncus eget. Fusce in feugiat lacus. Quisque vel massa magna. Mauris varius congue nisl, vitae pellentesque diam ultricies at. Sed ac nibh ac diam tristique venenatis non nec nisl. Vivamus enim eros, pretium at iaculis nec, pharetra non sem. Aenean ac imperdiet odio.</p> </article> </main> <footer> <p>footer</p> </footer> </body> 

For more information on using flexbox, see the following manuals:



Pure CSS Solution 2 - Display Table [Old Solution]:

This can also be done using the CSS property display: table; ( see W3 Specifications ).

HTML:

 <div id="screen"> <div id="header"></div> <div id="content"> <div id="content_frame"> <div id="content_wrap"></div> </div> </div> <div id="footer"></div> </div> 

CSS:

 html, body, #screen, #content, #content_frame { height: 100%; /* Make #screen viewport height and #content fill space */ } #screen { display: table; } #header, #content, #footer { display: table-row; } #content_frame { overflow-y: auto; /* Add scrollbar */ position: relative; } #content_wrap { position: absolute; /* Fix problem with overflow in FF */ } 

The overflow property is not valid for css table elements and their children, so I had to nest the contents. In this case, I had to nest twice and use position: absolute; to make it work in Firefox. Perhaps someone else can come up with a more elegant solution to avoid this "devita".

This is where jsfiddle works.

Warning: This does not work in Opera 12! The content of the div is 100% of the parent height, which causes the rows to overflow the table (as in Firefox).

+1
source share

Absolute positioning is a mess. Try something like this:

HTML:

 <div id="wrapper"> <div id="header"> header </div> <div id="content"> content </div> <div id="footer"> footer </div> </div> 

CSS

 #wrapper { width: 200px; height: 200px; overflow: visible; background: #e0e0ff; } #header { background: #80ff80; } #content { background: #8080ff; } #footer { background: #ff8080; } 

edit: maybe I misunderstood whether you want everything in the box 200x200px, or do you want the box to increase its height to fit the content?

0
source share

Should a parent stay at a fixed height?

 <div style="position : relative; width : 200px; background-color : #e0e0ff; overflow : hidden;"> <div style="float: left; clear: left; background-color: #80ff80;"> header </div> <div style="float: left; clear: left; background-color: #8080ff; overflow : auto; "> content (how to position it?) <BR />taller <BR />taller <BR />taller <BR />taller <BR />taller <BR />taller <BR />taller <BR />taller </div> <div style="float: left; clear: left; background-color: #ff8080;"> footer <BR />taller </div> 

if the parent’s height is corrected, this is the closest I know how to get to it carelessly - it’s still not quite right if these color blocks (as opposed to plain text) are really important and weren’t just for illustrating the borders of DIVs:

 <div style="position : relative; width : 200px; height : 200px; background-color : #e0e0ff; overflow : hidden;"> <div style="float: left; clear: left; background-color: #80ff80; "> header <BR .> taller </div> <div style="float: left; clear: left; background-color: #8080ff; overflow : auto; "> content (how to position it?)<BR /> and another line </div> <div style="background-color: #ff8080; position : absolute; bottom : 0px; left :0; right : 0;"> footer <BR /> taller </div> 

0
source share

Do I need to have a resize center size? If you are just trying to make sure its background (# 8080ff) appears between the header and footer, why not just contain the background div # 8080ff. The background of the header and footer would overlap this, and the rest of the background of the div would be correct.

0
source share

All Articles