How can an html element fill out 100% of the remaining screen height, using css only?
Asked Answered
A

16

170

I have a header element and a content element:

#header
#content

I want the header to be of fixed height and the content to fill up all the remaining height available on the screen, with overflow-y: scroll;.

It this possible without Javascript?

Adermin answered 9/9, 2011 at 6:19 Comment(0)
K
103

The trick to this is specifying 100% height on the html and body elements. Some browsers look to the parent elements (html, body) to calculate the height.

<html>
    <body>
        <div id="Header">
        </div>
        <div id="Content">
        </div>
    </body>
</html>

html, body
{
    height: 100%;
}
#Header
{
    width: 960px;
    height: 150px;
}
#Content
{
    height: 100%;
    width: 960px;
}
Kattie answered 9/9, 2011 at 6:32 Comment(2)
I tried all solution but only this solved my issue.Instrumentation
@Instrumentation if this works for all the browsers you are targeting, then by all means go ahead and implement it. Everyone's requirements are different.Kattie
L
451

forget all the answers, this line of CSS worked for me in 2 seconds:

    height: 100vh;

1vh = 1% of browser screen height

Source

For responsive layout scaling, you might want to use:

    min-height: 100vh

[update november 2018] As mentioned in the comments, using min-height might avoid having issues on responsive designs

[update april 2018] As mentioned in the comments, back in 2011 when the question was asked, not all browsers supported the viewport units. The other answers were the solutions back then -- vmax is still not supported in IE, so this might not be the best solution for all yet.

Lobachevsky answered 12/4, 2016 at 10:30 Comment(12)
This is the simplest answer, as you don't need to set the height of all the parent elements to 100%. Here's the current support for vh - caniuse.com/#feat=viewport-units - iOS apparently might need a workaround, as "vh on iOS is reported to include the height of the bottom toolbar in the height calculation".Lezlielg
WOW, nice find! Look at all these people with over-complicated answers.Manuscript
When the question was asked in 2011, none of the major browsers supported viewport units. Those "over-complicated answers" were the only options back then.Unclassical
this must be the simplest and clearest, most efficent answer!Pejsach
Minor suggestion that a min-height: 100vh would be a lot better. It would scale for responsive designs as well.Siphon
@WiggyA. Your suggestion helped me. I was getting reponsiveness issues with height: 100vh. Thanks :)Madge
This works for simple layouts, but when my div starts somewhere after top of screen, it makes the div overflow the viewport (which is logical)Mestizo
This does not answer the question asked, this would take up 100% of the viewport. He does not want this becuase his header will take up x % of the viewport, as such the other answers are correct.Barone
Same complaint as 4cody. This does not answer the question where fill >remaining< height is required. This results in a static element that is the height of the screen.Stryker
Is there any solution for width like this?Georg
I feel like this solution isn't 100% (no pun intended) correct as it doesn't answer the question. When you do 100vh, it takes then entire size of your viewport and adds it on. For example, if you have a header height of 86px and you want to add a dropdown menu that covers the rest of the screen, you will have a dropdown screen that will go under the viewport by 86px. You can try using the css attribute calc() to get a desired result if you know the explicit height. .menu { height: calc(100vh - 86px) } would get you a result that you would need but only if you know the explicit value.Unveil
Min-height:70vh did the job for me. Thanks a million.Retrieve
K
103

The trick to this is specifying 100% height on the html and body elements. Some browsers look to the parent elements (html, body) to calculate the height.

<html>
    <body>
        <div id="Header">
        </div>
        <div id="Content">
        </div>
    </body>
</html>

html, body
{
    height: 100%;
}
#Header
{
    width: 960px;
    height: 150px;
}
#Content
{
    height: 100%;
    width: 960px;
}
Kattie answered 9/9, 2011 at 6:32 Comment(2)
I tried all solution but only this solved my issue.Instrumentation
@Instrumentation if this works for all the browsers you are targeting, then by all means go ahead and implement it. Everyone's requirements are different.Kattie
M
39

Actually the best approach is this:

html { 
    height:100%;
}
body { 
    min-height:100%;
}

This solves everything for me and it helps me to control my footer and it can have the fixed footer no matter if page is being scrolled down.

Technical Solution - EDITED

Historically, 'height' is tricky thing to mold with, compared to 'width', the easiest. Since css focus on <body> for styling to work. The code above - we gave <html> and <body> a height. This is where magic comes into picture - since we have 'min-height' on playing table, we are telling browser that <body> is superior over <html> because <body> holds the min-height. This in turn, allows <body> to override <html> because <html> had height already earlier. In other words, we are tricking browser to "bump" <html> off the table, so we could style independently.

Modred answered 19/1, 2013 at 1:32 Comment(6)
Oh my god it's a miracle!Farfetched
Like miracle, it works! But please: why min-height and height?Ruyter
@ShaojiangCai - Historically, 'height' is tricky thing to mold with, compared to 'width', the easiest. Since css focus on <body> for styling to work. This code: we gave <html> and <body> a height. This is where magic comes into picture - since we have 'min-height' on playing table, we are telling server that <body> is superior over <html> because <body> holds the min-height. This in turn, allows <body> to override <html> because <html> had height already earlier. In other words, we are tricking server to "bump" <html> off the table, so we could style independently.Modred
@Modred It seems like 'browser' would be a better word choice here instead of 'server'. ;)Dipsomaniac
@EunLeem ... I agree with you on how I could have chose the proper wording to address this. Thanks for the "elbow-bump" tip. Updated my answer accordingly.Modred
This didn't quite work for one particular page I was working on. However, I fixed it by modifying the "html" CSS declaration above to html, body { height: 100%; } and that permitted the height to function properly. I guess I had to trick it more.Stockbroker
B
27

You can use vh on the min-height property.

min-height: 100vh;

You can do as follows, depending on how you are using the margins...

min-height: calc(100vh - 10px) //Considering you're using some 10px margin top on an outside element
Bagging answered 14/6, 2018 at 14:33 Comment(0)
G
11

The accepted solution will not actually work. You will notice that the content div will be equal to the height of its parent, body. So setting the body height to 100% will set it equal to the height of the browser window. Let's say the browser window was 768px in height, by setting the content div height to 100%, the div's height will in turn be 768px. Thus, you will end up with the header div being 150px and the content div being 768px. In the end you will have content 150px below the bottom of the page. For another solution, check out this link.

Godolphin answered 20/9, 2012 at 15:14 Comment(0)
K
8

With HTML5 you can do this:

CSS:

body, html{ width:100%; height:100%; padding: 0; margin: 0;}
header{ width:100%; height: 70px; }
section{ width: 100%; height: calc(100% - 70px);}

HTML:

<header>blabablalba </header>
<section> Content </section>
Keyboard answered 21/4, 2014 at 15:53 Comment(1)
Beware of using calc on percentage height. Firefox won't work with this correctly unless all parents have a set height.Stryker
C
6

For me, the next worked well:

I wrapped the header and the content on a div

<div class="main-wrapper">
    <div class="header">

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

    </div>
</div>

I used this reference to fill the height with flexbox. The CSS goes like this:

.main-wrapper {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}
.header {
    flex: 1;
}
.content {
    flex: 1;
}

For more info about the flexbox technique, visit the reference

Cobden answered 20/7, 2018 at 13:9 Comment(0)
E
3

Please let me add my 5 cents here and offer a classical solution:

html {height:100%;}
body {height:100%; margin:0;}
#idOuter {position:relative; width:100%; height:100%;}
#idHeader {position:absolute; left:0; right:0; border:solid 3px red;}
#idContent {position:absolute; overflow-y:scroll; left:0; right:0; border:solid 3px green;}
<div id="idOuter">
  <div id="idHeader" style="height:30px; top:0;">Header section</div>
  <div id="idContent" style="top:36px; bottom:0;">Content section</div>
</div>

This will work in all browsers, no script, no flex. Open snippet in full page mode and resize browser: desired proportions are preserved even in fullscreen mode.

Note:

  • Elements with different background color can actually cover each other. Here I used solid border to ensure that elements are placed correctly.
  • idHeader.height and idContent.top are adjusted to include border, and should have the same value if border is not used. Otherwise elements will pull out of the viewport, since calculated width does not include border, margin and/or padding.
  • left:0; right:0; can be replaced by width:100% for the same reason, if no border used.
  • Testing in separate page (not as a snippet) does not require any html/body adjustment.
  • In IE6 and earlier versions we must add padding-top and/or padding-bottom attributes to #idOuter element.

To complete my answer, here is the footer layout:

html {height:100%;}
body {height:100%; margin:0;}
#idOuter {position:relative; width:100%; height:100%;}
#idContent {position:absolute; overflow-y:scroll; left:0; right:0; border:solid 3px green;}
#idFooter {position:absolute; left:0; right:0; border:solid 3px blue;}
<div id="idOuter">
  <div id="idContent" style="bottom:36px; top:0;">Content section</div>
  <div id="idFooter" style="height:30px; bottom:0;">Footer section</div>
</div>

And here is the layout with both header and footer:

html {height:100%;}
body {height:100%; margin:0;}
#idOuter {position:relative; width:100%; height:100%;}
#idHeader {position:absolute; left:0; right:0; border:solid 3px red;}
#idContent {position:absolute; overflow-y:scroll; left:0; right:0; border:solid 3px green;}
#idFooter {position:absolute; left:0; right:0; border:solid 3px blue;}
<div id="idOuter">
  <div id="idHeader" style="height:30px; top:0;">Header section</div>
  <div id="idContent" style="top:36px; bottom:36px;">Content section</div>
  <div id="idFooter" style="height:30px; bottom:0;">Footer section</div>
</div>
Exhibitor answered 21/1, 2020 at 1:35 Comment(0)
C
1

You can also set the parent to display: inline. See http://codepen.io/tommymarshall/pen/cECyH

Be sure to also have the height of html and body set to 100%, too.

Crier answered 5/5, 2014 at 18:22 Comment(1)
Link-only answers are discouraged. Please try to summarize the link content in your answerDesultory
L
1

The accepted answer does not work. And the highest voted answer does not answer the actual question. With a fixed pixel height header, and a filler in the remaining display of the browser, and scroll for owerflow. Here is a solution that actually works, using absolute positioning. I also assume that the height of the header is known, by the sound of "fixed header" in the question. I use 150px as an example here:

HTML:

<html>
    <body>
        <div id="Header">
        </div>
        <div id="Content">      
        </div>
    </body>
</html>

CSS:(adding background-color for visual effect only)

#Header
{
    height: 150px;
    width: 100%;
    background-color: #ddd;
}
#Content
{
   position: absolute;
   width: 100%;
   top: 150px;
   bottom: 0;
   background-color: #aaa;
   overflow-y: scroll;
}

For a more detailed look how this works, with actual content inside the #Content, have a look at this jsfiddle, using bootstrap rows and columns.

Linearity answered 4/1, 2018 at 10:34 Comment(2)
"fixed pixel height header" -> this exactly! The bottom property made sure that the #Content stays stuck at the end of the page. I appreciate you taking the time to explain it.Thermoplastic
And I'm happy it helped someone ;)Linearity
E
1

In this instance I want my main content div to be liquid height so that the whole page takes up 100% of the browser height.

height: 100vh;

Enoch answered 18/5, 2018 at 6:2 Comment(0)
J
0

CSS PLaY | cross browser fixed header/footer/centered single column layout

CSS Frames, version 2: Example 2, specified width | 456 Berea Street

One important thing is that although this sounds easy, there's going to be quite a bit of ugly code going into your CSS file to get an effect like this. Unfortunately, it really is the only option.

Jugoslavia answered 9/9, 2011 at 6:25 Comment(1)
Link-only answers are discouraged. Try including the code in your answer.Desultory
S
0

Unless you need to support IE 9 and below, I would use flexbox

body { display: flex; flex-direction: column; }
.header { height: 70px; }
.content { flex: 1 1 0 }

You also need to get body to fill the whole page

body, html{ width:100%; height:100%; padding: 0; margin: 0;}
Stercoricolous answered 31/5, 2016 at 15:25 Comment(0)
C
0
#Header
{
width: 960px;
height: 150px;
}

#Content
{
min-height:100vh;
height: 100%;
width: 960px;
}
Casablanca answered 7/10, 2019 at 13:45 Comment(0)
C
-1

The best solution I found so far is setting a footer element at the bottom of the page and then evaluate the difference of the offset of the footer and the element we need to expand. e.g.

The html file

<div id="contents"></div>
<div id="footer"></div>

The css file

#footer {
    position: fixed;
    bottom: 0;
    width: 100%;
}

The js file (using jquery)

var contents = $('#contents'); 
var footer = $('#footer');
contents.css('height', (footer.offset().top - contents.offset().top) + 'px');

You might also like to update the height of the contents element on each window resize, so...

$(window).on('resize', function() {
  contents.css('height', (footer.offset().top -contents.offset().top) + 'px');
});
Chadwickchae answered 28/9, 2015 at 15:18 Comment(0)
L
-3

Have you tried something like this?

CSS:

.content {
    height: 100%;
    display: block;
}

HTML:

<div class=".content">
<!-- Content goes here -->
</div>
Lifeguard answered 9/9, 2011 at 6:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.