122

So I have a webpage with a header, mainbody, and footer. I want the mainbody to fill 100% of the page (fill 100% in between footer and header) My footer is position absolute with bottom: 0. Everytime I try to set the mainbody to 100% height or change position or something it will also overflow the header. If if set the body to position absolute with top: 40 (cause my header is 40px high), it will just go 40px too far down, creating a scroll bar.

I created a simple html file since i cannot actually post the entire page/css from the actual project. With the sample code, even though the maincontent body fills the screen, it goes 40px too far down (cause of the header I assume).

html,
body {
  margin: 0;
  padding: 0;
}

header {
  height: 40px;
  width: 100%;
  background-color: blue;
}

#maincontent {
  background-color: green;
  height: 100%;
  width: 100%;
}

footer {
  height: 40px;
  width: 100%;
  background-color: grey;
  position: absolute;
  bottom: 0;
}
<html>

<head>
  <title>test</title>
  <link href="style.css" rel="stylesheet" type="text/css">
</head>

<body>
  <header></header>
  <div id="maincontent">

  </div>

  <footer></footer>
</body>

</html>

Anyone knows the answer?

the_legitTDM
  • 353
  • 5
  • 21
user2713516
  • 2,983
  • 5
  • 23
  • 49
  • All is very broad... you want ie5.5 for mac, ie6, ie7, ie8, ie9, current browsers (ie10, chrome, ff, opera, safari), or what? – Chad Sep 06 '13 at 19:36
  • 1
    Just aside note: avoid absolute positioning for website main sections (header,body,footer,etc).. you will get very funny results on mobile browsers and old browsers – evilReiko Sep 06 '13 at 22:31
  • Ill keep it in mind :) – user2713516 Sep 07 '13 at 12:49

10 Answers10

143

These are not necessary

  • remove height in %
  • remove jQuery

Stretch div using bottom & top :

.mainbody{
    position: absolute;
    top: 40px; /* Header Height */
    bottom: 20px; /* Footer Height */
    width: 100%;
}

check my code : http://jsfiddle.net/aslancods/mW9WF/

or check here:

body {
    margin:0;
}

.header {
    height: 40px;
    background-color: red;
}

.mainBody {
    background-color: yellow;
    position: absolute;
    top: 40px;
    bottom: 20px;
    width:100%;
}

.content {
    color:#fff;
}

.footer {
    height: 20px;
    background-color: blue;
    
    position: absolute;
    bottom: 0;
    width:100%;
}
<div class="header" >
    &nbsp;
</div>
<div class="mainBody">
    &nbsp;
    <div class="content" >Hello world</div>
</div>
<div class="footer">
    &nbsp;
</div>
Peter
  • 437
  • 1
  • 4
  • 20
sudhan kantharuban
  • 2,095
  • 1
  • 14
  • 12
  • header & body -> is position : static, mainBody & footer -> position : absolute. right ? did u checked and followed my code, from jsFiddle ? – sudhan kantharuban Sep 06 '13 at 20:14
  • I forgot I still had height: 100%, when I changed it to auto it worked :) – user2713516 Sep 06 '13 at 20:15
  • 7
    This solution only works fine if you know the size of your header and footer. Please look @Mark Murphy's solution if you need it to work independently of the heights of the header and footer. – Aebsubis Jul 17 '15 at 13:03
  • @sudhnk Try add more content and there is issue then scrolling it. http://jsfiddle.net/sgs7yog0/ – FDisk Feb 07 '17 at 09:14
  • This solution has issues. The content extends beyond the footer and the footer scrolls up. Try adding a bunch of content in the jsfiddle link provided. The solution below works great. Tried on chrome and safari. – Landon Poch Mar 30 '18 at 04:30
  • 1
    you should be banned from using colors ... – Ordiel Aug 02 '18 at 22:21
65

No Javascript, no absolute positioning and no fixed heights are required for this one.

Here's an all CSS / CSS only method which doesn't require fixed heights or absolute positioning:

/* Reset */

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}


/* Essentials */

.container {
  display: table;
}

.content {
  display: table-row;
  height: 100%;
}

.content-body {
  display: table-cell;
}


/* Aesthetics */

.container {
  width: 100%;
  height: 100%;
}

.header,
.footer {
  padding: 10px 20px;
  background: #f7f7f7;
}

.content-body {
  padding: 20px;
  background: #e7e7e7;
}
<div class="container">
  <header class="header">
    <p>This is the header</p>
  </header>
  <section class="content">
    <div class="content-body">
      <p>This is the content.</p>
    </div>
  </section>
  <footer class="footer">
    <p>This is the footer.</p>
  </footer>
</div>

The benefit of this method is that the footer and header can grow to match their content and the body will automatically adjust itself. You can also choose to limit their height with css.

meyi
  • 7,574
  • 1
  • 15
  • 28
Mark Murphy
  • 2,834
  • 1
  • 31
  • 29
  • The content area fails to get a scroll bar: http://jsfiddle.net/AzLQY/517/ – Junle Li May 31 '16 at 09:13
  • @JunleLi If you want it to scroll you can do this: http://jsfiddle.net/geprhxxv/1/ – Mark Murphy Jun 01 '16 at 16:39
  • 1
    Thanks for your reply. I want a solution with scroll-able main area and no magic number for header and footer. I do lots of search and give up. Anyway, thank you very much! Your solution is inspiring! :) – Junle Li Jun 01 '16 at 18:36
  • @JunleLi there's no magic numbers in this solution. So it sounds like this is what you're looking for or is that what you meant? – Mark Murphy Jun 01 '16 at 18:39
  • Hi, @Mark. That is a nice way. But it does not work for IE. :( Thanks for your help! – Junle Li Jun 01 '16 at 18:48
59

There is a CSS unit called viewport height / viewport width.

Example

.mainbody{height: 100vh;} similarly html,body{width: 100vw;}

or 90vh = 90% of the viewport height.

**IE9+ and most modern browsers.

joyBlanks
  • 6,419
  • 1
  • 22
  • 47
  • 2
    This is a good solution, but vh is not supported in all modern browsers e.g. iOS 7.1 safari and android chrome < 4.4 – 1800 INFORMATION Jan 05 '15 at 03:02
  • 3
    I see a problem with the vh unit on mobile browsers. The URL bar seems to be calculated into the whole vh. So, when you scroll and the URL bar collapse, it seems like a glitch and the site tries to recalculate. Just presentation wise, it's weak. Anyone with a solution? – Eshwaren Manoharen Oct 25 '16 at 02:58
  • 1
    That gives the element the size of the screen, but doesn't guarantee that it will actually fill the screen --- or be onscreen at all. – jpaugh Aug 31 '17 at 01:20
9

This allows for a centered content body with min-width for my forms to not collapse funny:

html {
    overflow-y: scroll;
    height: 100%;
    margin: 0px auto;
    padding: 0;
}

body {
    height: 100%;
    margin: 0px auto;
    max-width: 960px;
    min-width: 750px;
    padding: 0;
}
div#footer {
    width: 100%;
    position: absolute;
    bottom: 0;
    left: 0;
    height: 60px;
}

div#wrapper {
    height: auto !important;
    min-height: 100%;
    height: 100%;
    position: relative;
    overflow: hidden;
}

div#pageContent {
    padding-bottom: 60px;
}

div#header {
    width: 100%;
}

And my layout page looks like:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">

<head>
    <title></title>
</head>
<body>
<div id="wrapper">
        <div id="header"></div>
        <div id="pageContent"></div>
        <div id="footer"></div>
    </div>
</body>
</html>

Example here: http://data.nwtresearch.com/

One more note, if you want the full page background like the code you added looks like, remove the height: auto !important; from the wrapper div: http://jsfiddle.net/mdares/a8VVw/

Matthew
  • 9,851
  • 4
  • 46
  • 77
6

Using top: 40px and bottom: 40px (assuming your footer is also 40px) with no defined height, you can get this to work.

.header {
    width: 100%;
    height: 40px;
    position: absolute;
    top: 0;
    background-color:red;
}
.mainBody {
    width: 100%;
    top: 40px;
    bottom: 40px;
    position: absolute;
    background-color: gray;
}
.footer {
    width: 100%;
    height: 40px;
    position: absolute;
    bottom: 0;
    background-color: blue;
}

JSFiddle

Tricky12
  • 6,752
  • 1
  • 27
  • 35
3

Well, there are different implementations for different browsers.

In my mind, the simplest and most elegant solution is using CSS calc(). Unfortunately, this method is unavailable in ie8 and less, and also not available in android browsers and mobile opera. If you're using separate methods for that, however, you can try this: http://jsfiddle.net/uRskD/

The markup:

<div id="header"></div>
<div id="body"></div>
<div id="footer"></div>

And the CSS:

html, body {
    height: 100%;
    margin: 0;
}
#header {
    background: #f0f;
    height: 20px;
}
#footer {
    background: #f0f;
    height: 20px;
}
#body {
    background: #0f0;
    min-height: calc(100% - 40px);
}

My secondary solution involves the sticky footer method and box-sizing. This basically allows for the body element to fill 100% height of its parent, and includes the padding in that 100% with box-sizing: border-box;. http://jsfiddle.net/uRskD/1/

html, body {
    height: 100%;
    margin: 0;
}
#header {
    background: #f0f;
    height: 20px;
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
}
#footer {
    background: #f0f;
    height: 20px;
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
}
#body {
    background: #0f0;
    min-height: 100%;
    box-sizing: border-box;
    padding-top: 20px;
    padding-bottom: 20px;
}

My third method would be to use jQuery to set the min-height of the main content area. http://jsfiddle.net/uRskD/2/

html, body {
    height: 100%;
    margin: 0;
}
#header {
    background: #f0f;
    height: 20px;
}
#footer {
    background: #f0f;
    height: 20px;
}
#body {
    background: #0f0;
}

And the JS:

$(function() {
    headerHeight = $('#header').height();
    footerHeight = $('#footer').height();
    windowHeight = $(window).height();
   $('#body').css('min-height', windowHeight - headerHeight - footerHeight);
});
Chad
  • 5,308
  • 4
  • 24
  • 36
1

Not sure exactly what your after, but I think I get it.

A header - stays at the top of the screen? A footer - stays at the bottom of the screen? Content area -> fits the space between the footer and the header?

You can do this by absolute positioning or with fixed positioning.

Here is an example with absolute positioning: http://jsfiddle.net/FMYXY/1/

Markup:

<div class="header">Header</div>
<div class="mainbody">Main Body</div>
<div class="footer">Footer</div>

CSS:

.header {outline:1px solid red; height: 40px; position:absolute; top:0px; width:100%;}
.mainbody {outline:1px solid green; min-height:200px; position:absolute; top:40px; width:100%; height:90%;}
.footer {outline:1px solid blue; height:20px; position:absolute; height:25px;bottom:0; width:100%; } 

To make it work best, I'd suggest using % instead of pixels, as you will run into problems with different screen/device sizes.

TyMayn
  • 1,936
  • 2
  • 18
  • 23
1

Relative values like: height:100% will use the parent element in HTML like a reference, to use relative values in height you will need to make your html and body tags had 100% height like that:

HTML

<body>
    <div class='content'></div>
</body>

CSS

html, body
{
    height: 100%;
}

.content
{
    background: red;
    width: 100%;
    height: 100%;
}

http://jsfiddle.net/u91Lav16/1/

0

Although this might sounds like an easy issue, but it's actually not!

I've tried many things to achieve what you're trying to do with pure CSS, and all my tries were failure. But.. there's a possible solution if you use javascript or jquery!

Assuming you have this CSS:

#myheader {
    width: 100%;
}
#mybody {
    width: 100%;
}
#myfooter {
    width: 100%;
}

Assuming you have this HTML:

<div id="myheader">HEADER</div>
<div id="mybody">BODY</div>
<div id="myfooter">FOOTER</div>

Try this with jquery:

<script>
    $(document).ready(function() {
        var windowHeight = $(window).height();/* get the browser visible height on screen */
        var headerHeight = $('#myheader').height();/* get the header visible height on screen */
        var bodyHeight = $('#mybody').height();/* get the body visible height on screen */
        var footerHeight = $('#myfooter').height();/* get the footer visible height on screen */
        var newBodyHeight = windowHeight - headerHeight - footerHeight;
        if(newBodyHeight > 0 && newBodyHeight > bodyHeight) {
            $('#mybody').height(newBodyHeight);
        }
    });
</script>

Note: I'm not using absolute positioning in this solution, as it might look ugly in mobile browsers

evilReiko
  • 19,501
  • 24
  • 86
  • 102
-2

This question is a duplicate of Make a div fill the height of the remaining screen space and the correct answer is to use the flexbox model.

All major browsers and IE11+ support Flexbox. For IE 10 or older, or Android 4.3 and older, you can use the FlexieJS shim.

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

html, body {
  height: 100%;
  margin: 0; padding: 0;  /* to avoid scrollbars */
}

#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/ */
}

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

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

#footer{
  background: lime;
}
<div id="wrapper">
  <div id="header">Title</div>
  <div id="body">Body</div>
  <div id="footer">
    Footer<br/>
    of<br/>
    variable<br/>
    height<br/>
  </div>
</div>

In the CSS above, the flex property shorthands the flex-grow, flex-shrink, and flex-basis properties to establish the flexibility of the flex items. Mozilla has a good introduction to the flexible boxes model.

Jonathan E. Landrum
  • 2,748
  • 4
  • 30
  • 46
Dan Dascalescu
  • 143,271
  • 52
  • 317
  • 404
  • 9
    Support for the `flex` property is still [_extremely_ limited.](https://developer.mozilla.org/en-US/docs/Web/CSS/flex#Browser_compatibility). Sure, post it as an answer, but get off of your high horse telling (asking) others to delete their answers 'cause yours is "better". – Cerbrus Feb 19 '15 at 15:12
  • 4
    @Cerbrus: what is "extremely limited" about all evergreen browsers and IE11+? I've also mentioned the FlexieJS shim. I don't care if "mine" is better, as evidenced by promoting Pebbl's answer in the question you probably got here from. – Dan Dascalescu Feb 19 '15 at 18:28
  • 2
    @ArunPrasadES: because it's the modern solution to the question. – Dan Dascalescu Oct 09 '19 at 08:02
  • 1
    Note that in 2023 this is the correct answer, even though it has been downvoted into oblivion. Furthermore, instead of classes or ID's on div's, you can use the builtin `header`, `main`, and `footer` entities directly, and apply the `flex` rule to the `body` element. By @Cerbrus' own link, this solution is supported in every extant browser with any market share, albeit with the occasional implementation note to address. – Jonathan E. Landrum Jan 30 '23 at 16:22
  • Since you had to ping me, @Jonathan: Meh, flexbox is still very janky, and tends to mess with inner elements' layout too much. Besides, when I originally wrote that comment, `flex` was indeed just not a good option. – Cerbrus Jan 30 '23 at 22:37
  • Oh absolutely, flex was a *terrible* option when you wrote your answer. I was noting how much has changed since then, and trying to bring attention to the fact that one of the best answers on the page is also the most downvoted. – Jonathan E. Landrum Jan 31 '23 at 13:50