How to stretch a div to the viewport bottom without using absolute positioning?


Tags: html,css,position,css-position,viewport

Problem :

How to stretch a div (not the size of the viewport) to the viewport bottom without using absolute positioning?

If I use absolute positioning to stretch my "main" div to the bottom on the viewport, then any newly added elements above main, say a nav bar, won't get re-positioned by the browser automatically since the "main" div with no longer be in the normal flow.

And I really don't want to be recalculating top & bottom positions of affected elements every time I add/remove a dynamic div (or other containing) in the normal flow if I have to go the absolute route.

fiddle


HTML:

<div id="wrapper">
    <div id="header">
        HEADER<br>
        <input id="btnNavBar" type="button" value="add/remove nav bar"/>
    </div>
    <div id="main">
        MAIN CONTENT NEEDS TO STRETCH TO BOTTOM OF VIEWPORT, BUT NOT BE ABSOLUTE SO THAT IT WILL AUTOMATICALLY ADJUST FOR ANY NEWLY ADDED DYNAMIC ELEMENTS ABOVE IT SINCE IT'LL STILL BE IN THE NORMAL FLOW.
    </div>
</div>

CSS:

html, body {
    height: 100%;
    margin: 0px;
}
#wrapper {
    height: 100%;
    background-color: black;
}
#header {
    height: 50px;
    text-align: center;
    background-color: red;
}
#main {
    background-color: gray;
    height: 100%;
}
/* UNCOMMENT THIS SECTION TO MAKE THE STRETCHING WORK WITH ABSOLUTE POSITIONING, 
    BUT NOT FOR ANY NEWLY ADDED ELEMENTS */
/*#wrapper {
    position: relative;
}
#main {
    height: auto;
    position: absolute;
    bottom: 0px;
    top: 50px;
}*/

JS:

$('#btnNavBar').click(function(){
    var $navBar = $('#navBar');
    if ($navBar.length == 0)
    {
        $('<div>').prop('id','navBar').css({'height':'20px', 
            'background-color':'yellow', 'text-align':'center'})
            .text('Dynamically Added Nav Bar').insertAfter('#header');
    }
    else
        $navBar.remove();
});


Solution :

add this to your CSS

#wrapper:before
{
    content: '';
    float: left;
    height: 100%;
}
#main:after
{
    content: '';
    display: block;
    clear: both;
}

and remove the height:100% from #main

Working Fiddle

Tested on: IE10, IE9, IE8, FF, Chrome.

  1. didn't change your markup
  2. didn't use absolute positioning
  3. didn't use Script (Pure CSS solution)
  4. fluid layout
  5. cross-browser

    CSS Howto..

    How to let Fancybox Next and Previous button stay visible

    CSS - How do you make text overflow out both ends of a div?

    how to let dropdown menu align-right?

    How to create a horizontal calendar with nested lists?

    How to stretch background image of a table cell with CSS?

    How to make image stretch to a specific paragraph?

    How do I stick my footer to bottom of the page with Google Chrome?

    How can I hide text in this jquery slider?

    How to make my div's shrink dynamically, and not hide certain content?

    How to make an overflow hidden only for box-shadow

    How to solve this Jquery problem

    How to set width and text-align for button with CSS

    FontAwesome icon showing as black box. What CSS is needed to display icon?

    How to add multiple css rules at once through Dev-Tools or Firebug

    How to use css in one page only?

    How does Bootstrap's Jumbotron example create space in navbar elements

    How to design the web page for minimum format loss when pasting into MS Word

    How to Layout a Watermark Image that is transparent along with a banner image and content div?

    How to prevent css missing when exporting some html to excel file?

    How do I remove the white space around my html forms?

    How to use google font

    How to set inline css width using model values in c#, mvc

    How to avoid a th element from inheriting properties from a tr element in IE6/7

    How to fill an element 100% vertically with children only with CSS?

    CSS - How to position a fixed sidebar div relatively to a centered content div

    How to Make Image Do All 3: Cover (left-to-right), Resize, and Scroll

    How can i make 3 independently scrollable columns

    css margin-left propery - how to specify for various browsers [closed]

    how to make jquery transition smoothly

    How to create border corner spacing in CSS