3

I'm trying to put together a simple 3 row layout in CSS. It needs:

  • A main container div (100% width, 100% height) which holds...
    • A sticky header (fixed height of 48px)
    • A middle section that fills all remaining space in-between the header and footer
    • A sticky footer (initial height of 62px, but can change after page-load via javascript)

Here's what I've got so far:

HTML

<body>
    <div id="container">
        <div id="headContainer">
            ...
        </div>
        <div id="bodyContainer">
            Stuff goes here
        </div>
        <div id="footContainer">
            ...
        </div>
    </div>
 </body>

CSS

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
    margin: 0;
    padding: 0;
    border: 0;
    font-size: 100%;
    font: inherit;
    vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
    display: block;
}
body {
    line-height: 1;
}
ol, ul {
    list-style: none;
}
blockquote, q {
    quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
    content: '';
    content: none;
}
table {
    border-collapse: collapse;
    border-spacing: 0;
}

body {
    background-color:#2c3e50;
}

div#container {
    height:100%;
    width:100%;
}

div#headContainer {
    background-color:#e74c3c;
    height:48px;
    width:100%;
    z-index:1;
}

div#bodyContainer {
    overflow:auto;
    width:100%;
    top:48px;
    position:absolute;
    background-color:#FFFFFF;
}

div#footContainer {
    background-color:#c0392b;
    width:100%;
    position:absolute;
    bottom:0;
    padding:11px 18px;
    box-sizing:border-box;
    -moz-box-sizing:border-box; /* Firefox */
    -webkit-box-sizing:border-box; /* Safari */
}

http://jsfiddle.net/MsKaj/2/

I'm struggling to work out how I get the 'bodyContainer' to fill the available space between the header and footer. If the footer was a fixed size, this would be a lot easier!

Any tips?

Mike
  • 105
  • 3
  • 8
  • Do you want a sticky footer in the sense that it will stay at the bottom of the screen and not scroll with the page? – CaribouCode Oct 07 '13 at 08:58
  • Yes. All content will be within the bodyContainer, which should be scroll-able. The header and footer should remain at the top and bottom of the page respectively. – Mike Oct 07 '13 at 09:02
  • @Coop I have that problem!! How can it be done ​​so that it moves with the scroll? Thanks – ɐsɹǝʌ ǝɔıʌ Oct 07 '13 at 09:13
  • possible duplicate of [How do I use CSS to position a fixed variable height header and a scrollable content box?](http://stackoverflow.com/questions/6414384/how-do-i-use-css-to-position-a-fixed-variable-height-header-and-a-scrollable-con) – isherwood Oct 09 '13 at 21:19
  • This is a very common question on SO. You actually get better results searching Google and picking out the SO questions in the results. – isherwood Oct 09 '13 at 21:19
  • possible duplicate of [How can a variable-height sticky footer be defined in pure CSS?](http://stackoverflow.com/questions/10825879/how-can-a-variable-height-sticky-footer-be-defined-in-pure-css) – Dan Dascalescu Oct 25 '14 at 00:24

3 Answers3

2

All other solutions here are out of date and either resort to JavaScript, or don't support a variable height footer.

With the advent of the CSS flex model, solving the variable-height sticky footer problem becomes very, very easy: while mostly known for laying out content in the horizontal direction, Flexbox actually works just as well for vertical layout problems. All you have to do is wrap the vertical sections in a flex container and choose which ones you want to expand. They'll automatically take up all the available space in their container.

Note how simple the markup and the CSS are. No table hacks or anything.

The flex model is supported by all major browsers as well as allegedly IE11+, though my IE doesn't render this snippet correctly yet.

html, body {
  height: 100%;
}

#headContainer {
  background: yellow;
  height: 100px;  /* can be variable as well */
}

#wrapper {
  display: flex;  /* use the flex model */
  min-height: 100%;
  flex-direction: column;  /* learn more: http://philipwalton.github.io/solved-by-flexbox/demos/sticky-footer/ */
}

#bodyContainer {
  flex: 1;
  border: 1px solid orange;
}

#footContainer {
  background: lime;
}
<div id="wrapper">
  <div id="headContainer">Title</div>
  <div id="bodyContainer">Stuff goes here</div>
  <div id="footContainer">
    Footer<br/>
    of<br/>
    variable<br/>
    height<br/>
  </div>
</div>
Dan Dascalescu
  • 143,271
  • 52
  • 317
  • 404
-2

Put:

height: 100%;

on div#bodyContainer

Also, consider applying position: fixed; to the header and footer and fixing them to the top of the screen and the bottom of the screen respectively...

Pat Dobson
  • 3,249
  • 2
  • 19
  • 32
  • Thanks Pat. Adding 100% height to the bodyContainer pushes it beneath the footer because of the top offset I've given it so that it sits beneath the header. I'll mess around with the fixed positioning now. – Mike Oct 07 '13 at 09:01
  • Just add a margin-bottom to your content that's the same height as your sticky footer . . . – Pat Dobson Oct 07 '13 at 09:11
  • 1
    The footer is dynamic in height. It can change after page load via jQuery. When it does get taller, I need it to squash the bodyContainer up. – Mike Oct 07 '13 at 09:23
  • If the footer height changes dynamically on page load, simply apply the dynamic height at the same time to the bottom margin of the main content . . . – Pat Dobson Oct 07 '13 at 09:30
  • It doesn't change on page load, but could change afterwards. I know I could use javascript to set the bottom position of the bodyContainer to match the height of the footer if the footer height changes - but I was hoping for a CSS based solution. – Mike Oct 07 '13 at 10:36
-2

You can make it like this (with fixed header and footer)

HTML:

<div class="header">header</div>
<div class="content">content</div>
<div class="footer">footer</div>

CSS:

html, body {
    margin: 0;
    padding: 0;
    height: 100%;
}
.header, .footer {
    position: fixed;
    width: 100%;
    height: 48px;
    left: 0;
    background: lightgreen;
}
.header {
    top: 0;
}
.footer {
    height: 62px;
    bottom: 0px;
}
.content {
    min-height: 100%;
    background: lightblue;
    padding: 48px 0 62px 0;
    box-sizing: border-box;
    -moz-box-sizing: border-box;
}

And a DEMO.

GreyRoofPigeon
  • 17,833
  • 4
  • 36
  • 59
  • Thanks! In this example, we're assuming the footer is a fixed size, which it isn't. I need the 'content' div to use all available space between the header and footer, whatever size the footer may happen to be. – Mike Oct 07 '13 at 09:25
  • You are using JS to alter the content, can't you change the footer size and padding with that same function?? – GreyRoofPigeon Oct 07 '13 at 09:26
  • 1
    I could do. It's probably the route I'll take now, but I was hoping for a CSS based solution! – Mike Oct 07 '13 at 10:37
  • Bases on the conditions I think this isn't possible with CSS only. – GreyRoofPigeon Oct 07 '13 at 12:01
  • @LinkinTED: yep, it's possible with CSS only, and it's [very simple](http://stackoverflow.com/a/26558073/1269037). – Dan Dascalescu Oct 25 '14 at 00:22
  • @Dan Dascalescu Check the date of the answer. And do note that the flex property isn't fully supported cross browser – GreyRoofPigeon Oct 25 '14 at 04:54