Modern way to markup 100% height layout in HTML5 and CSS3 - css

I've been away from marking up sites for some time. So, now we have HTML5 and a lot of new features in CSS. I have a common site layout with fixed size header and footer. And of course main content area in between. By default page should take 100% of window height (i.e. content area expands). And if content is long page vertical scrollbar appears and all like usual.
Usually I used to do it by something like this:
<body>
<table id="main" ...>
<tr>
<td id="header-and-content">
<div id="header">contains logo, nav and has fixed height</div>
<div id="content">actual content</div>
</td>
</tr>
<tr>
<td id="footer">
fixed size footer
</td>
</tr>
</table>
</body>
And accompanying css:
html, body { height:100% }
table#main { height:100% }
td#footer { height:123px }
So, it's obsolete. You, who keeps abreast of new markup techniques, how it is done by now in 2011?
UPD People, issue not about semantic markup or using divs. I know what it does mean. Issue now in - how do I tell footer to stay at bottom even while content is empty or short. When content is long enough footer just go down as it would do in other case. Absolute and fixed is not the solution (at least at its basic form)
SOME SUMMARY UPDATE
I've tried method with usage of display:table and display:table-row and it works: little content, more content
Method Make the Footer Stick to the Bottom of a Page was adviced by Andrej. It works also: little content, more content
Some disappointment though I feel: first method is just those tables but without table tag. The second is really old, I've avoided to use it because it resembles hack. My god, nothing new :)

Well, first of all in 2011 we dont use tables for layout anymore!
If I were you, I would write the markup like so:
<body>
<div id="main" role="main">
<header>
contains logo, nav and has fixed height
</header>
<div class="content"> /*use <article> or <section> if it is appropriate - if not sure what to use, use a div*/
actual content
</div>
<footer>
fixed size footer
</footer>
</div>
</body>
And the CSS would be the same except the changed selectors
html, body { height:100% }
#main { height:100% }
footer { height:123px }
For a fixed footer, I would suggest to use position:absolute or maybe position:fixed - it depends how you want it to behave (scroll with page or always stay at bottom).
To make a "sticky" footer, that will be at the bottom of the page but move with the content, this method will do the trick.

In 2013 there is still nothing that beats a decent table that has respectively thead/tfoot/tbody.
The below (valid HTML5 page) is a fixed header and footer, 100% height and NOT ANY resize trouble.
<!DOCTYPE html>
<meta charset="utf-8" />
<title>valid HTML5 / fixed header and footer / nada CSS sizing trouble</title>
<style type="text/css">
html, body, table { height: 100% }
th { height: 80px }
#f { height: 40px }
table { width: 1000px }
html, body { margin: 0 }
table { margin: 0 auto }
td { text-align: left }
html, body { text-align: center } /* important for old browsers */
th { text-align: right }
html, body { background-color: rgb(148,0,211) }
#m { background-color: #f39 }
#m { -webkit-border-radius: 25px;
-khtml-border-radius: 25px;
-moz-border-radius: 25px;
-ms-border-radius: 25px;
-o-border-radius: 25px;
border-radius: 25px; }
</style>
<table>
<thead><tr><th> head</th></tr></thead>
<tfoot><tr><td id="f">foot</td></tr></tfoot>
<tbody><tr><td id="m">main</td></tr></tbody>
</table>

As you asked for "modern"... anno 2016 I have maybe a better answer than in 2013:
use the 100vh solution in CSS3. vh is a new unit and stands for ViewPort height.
html, body { height: 100% }
header { height: 100px }
footer { height: 50px }
main { height: calc(100vh - 150px); }
html, body { width: 100% }
header, main, footer { width: 1000px }
html, body { margin: 0 }
header, main, footer { margin: 0 auto }
html, body { padding: 0 }
html, body { text-align: center }
body { background-color: white }
header { background-color: yellow }
main { background-color: orange }
footer { background-color: red }
<!DOCTYPE html>
<meta charset="utf-8" />
<title>test</title>
<header>bla</header>
<main>bla</main>
<footer>bla</footer>
But if you wish to be compatible with old browsers, use the code in my 2013 answer.

Today, you would do like this (not much different really)
http://jsfiddle.net/5YHX7/3/
html, body { height: 100%; width: 100%; margin: 0; }
div { height: 100%; width: 100%; background: #F52887; }
and
<html><body><div></div></body></html>

Technically you could probably still get away with laying out your page with table tags but it is now considered bad practice. It is considered good practice to use "semantic" web markup which means using tags for their intended purposes so a table tag should be used to represent table data and not invisible design. DIVs are intended for use designing your invisible page layout. A list apart is a great website resource for understanding these concepts.
This article is good for understanding semantic markup: http://www.alistapart.com/articles/12lessonsCSSandstandards
So all that said, here is a sample page that does what you want:
http://peterned.home.xs4all.nl/examples/csslayout1.html

As asking for "modern" AND "compatible" is a contraction anyway, the grid method wasn't mentioned so far, and maybe is too modern right now, but with some adaptions might be a solution.
This article (and pointers) -with more complex use- is great to read:
https://developers.google.com/web/updates/2017/01/css-grid
Now the code looks nice, however browsers don't... - so I added some forcing.
https://jsfiddle.net/qLcjg6L6/1/
<!DOCTYPE html>
<html>
<head>
<style>
html, body {
height: 100%;
min-height: 100vh;
margin: 0;
padding: 0 }
body { display: grid;
grid-template-rows: minmax(auto, min-content) auto minmax(auto, min-content);
grid-template-columns: 100% }
header { background: red }
main { background: pink }
footer { background: purple }
/* as this code is yet far from well-supported, here's a brute force... */
header { height: 70px }
footer { height: 60px }
main { height: calc(100vh - 130px); }
/* 130px being the sum of header/footer - adapt to your desired size/unit */
</style>
</head>
<body>
<header>hdr</header>
<main>main</main>
<footer>foot</footer>
</body>
</html>

Let me add my contribution by adding 3 columns to your header / main / footer layout:
http://jsfiddle.net/ESrG9/
<!DOCTYPE html>
<table>
<thead>
<tr id="header">
<th colspan="3">head</th>
</tr>
</thead>
<tbody>
<tr>
<td id="left">main</td>
<td id="main">main</td>
<td id="right">main</td>
</tr>
</tbody>
<tfoot>
<tr>
<td id="footer" colspan="3">foot</td>
</tr>
</tfoot>
</table>

So far nobody mentioned the flex-box method
https://jsfiddle.net/55r7n9or/
<!DOCTYPE html>
<html>
<head>
<style>
html, body, div {
height: 100%;
margin: 0;
padding: 0 }
div { display: flex;
flex-direction: column }
main { flex: 1 }
header { background: red }
main { background: pink }
footer { background: purple }
</style>
</head>
<body>
<div>
<header>hdr</header>
<main>main</main>
<footer>foot</footer>
</div>
</body>
</html>

Related

How to make an image to fill its container which has height in percentage? [duplicate]

I am working on a web application where I want the content to fill the height of the entire screen.
The page has a header, which contains a logo, and account information. This could be an arbitrary height. I want the content div to fill the rest of the page to the bottom.
I have a header div and a content div. At the moment I am using a table for the layout like so:
CSS and HTML
#page {
height: 100%; width: 100%
}
#tdcontent {
height: 100%;
}
#content {
overflow: auto; /* or overflow: hidden; */
}
<table id="page">
<tr>
<td id="tdheader">
<div id="header">...</div>
</td>
</tr>
<tr>
<td id="tdcontent">
<div id="content">...</div>
</td>
</tr>
</table>
The entire height of the page is filled, and no scrolling is required.
For anything inside the content div, setting top: 0; will put it right underneath the header. Sometimes the content will be a real table, with its height set to 100%. Putting header inside content will not allow this to work.
Is there a way to achieve the same effect without using the table?
Update:
Elements inside the content div will have heights set to percentages as well. So something at 100% inside the div will fill it to the bottom. As will two elements at 50%.
Update 2:
For instance, if the header takes up 20% of the screen's height, a table specified at 50% inside #content would take up 40% of the screen space. So far, wrapping the entire thing in a table is the only thing that works.
2015 update: the flexbox approach
There are two other answers briefly mentioning flexbox; however, that was more than two years ago, and they don't provide any examples. The specification for flexbox has definitely settled now.
Note: Though CSS Flexible Boxes Layout specification is at the Candidate Recommendation stage, not all browsers have implemented it. WebKit implementation must be prefixed with -webkit-; Internet Explorer implements an old version of the spec, prefixed with -ms-; Opera 12.10 implements the latest version of the spec, unprefixed. See the compatibility table on each property for an up-to-date compatibility status.
(taken from https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Flexible_boxes)
All major browsers and IE11+ support Flexbox. For IE 10 or older, you can use the FlexieJS shim.
To check current support you can also see here:
http://caniuse.com/#feat=flexbox
Working example
With flexbox you can easily switch between any of your rows or columns either having fixed dimensions, content-sized dimensions or remaining-space dimensions. In my example I have set the header to snap to its content (as per the OPs question), I've added a footer to show how to add a fixed-height region and then set the content area to fill up the remaining space.
html,
body {
height: 100%;
margin: 0;
}
.box {
display: flex;
flex-flow: column;
height: 100%;
}
.box .row {
border: 1px dotted grey;
}
.box .row.header {
flex: 0 1 auto;
/* The above is shorthand for:
flex-grow: 0,
flex-shrink: 1,
flex-basis: auto
*/
}
.box .row.content {
flex: 1 1 auto;
}
.box .row.footer {
flex: 0 1 40px;
}
<!-- Obviously, you could use HTML5 tags like `header`, `footer` and `section` -->
<div class="box">
<div class="row header">
<p><b>header</b>
<br />
<br />(sized to content)</p>
</div>
<div class="row content">
<p>
<b>content</b>
(fills remaining space)
</p>
</div>
<div class="row footer">
<p><b>footer</b> (fixed height)</p>
</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.
There really isn't a sound, cross-browser way to do this in CSS. Assuming your layout has complexities, you need to use JavaScript to set the element's height. The essence of what you need to do is:
Element Height = Viewport height - element.offset.top - desired bottom margin
Once you can get this value and set the element's height, you need to attach event handlers to both the window onload and onresize so that you can fire your resize function.
Also, assuming your content could be larger than the viewport, you will need to set overflow-y to scroll.
The original post is more than 3 years ago. I guess many people who come to this post like me are looking for an app-like layout solution, say a somehow fixed header, footer, and full height content taking up the rest screen. If so, this post may help, it works on IE7+, etc.
http://blog.stevensanderson.com/2011/10/05/full-height-app-layouts-a-css-trick-to-make-it-easier/
And here are some snippets from that post:
#media screen {
/* start of screen rules. */
/* Generic pane rules */
body { margin: 0 }
.row, .col { overflow: hidden; position: absolute; }
.row { left: 0; right: 0; }
.col { top: 0; bottom: 0; }
.scroll-x { overflow-x: auto; }
.scroll-y { overflow-y: auto; }
.header.row { height: 75px; top: 0; }
.body.row { top: 75px; bottom: 50px; }
.footer.row { height: 50px; bottom: 0; }
/* end of screen rules. */
}
<div class="header row" style="background:yellow;">
<h2>My header</h2>
</div>
<div class="body row scroll-y" style="background:lightblue;">
<p>The body</p>
</div>
<div class="footer row" style="background:#e9e9e9;">
My footer
</div>
Instead of using tables in the markup, you could use CSS tables.
Markup
<body>
<div>hello </div>
<div>there</div>
</body>
(Relevant) CSS
body
{
display:table;
width:100%;
}
div
{
display:table-row;
}
div+ div
{
height:100%;
}
FIDDLE1 and FIDDLE2
Some advantages of this method are:
1) Less markup
2) Markup is more semantic than tables, because this is not tabular data.
3) Browser support is very good: IE8+, All modern browsers and mobile devices (caniuse)
Just for completeness, here are the equivalent Html elements to css properties for the The CSS table model
table { display: table }
tr { display: table-row }
thead { display: table-header-group }
tbody { display: table-row-group }
tfoot { display: table-footer-group }
col { display: table-column }
colgroup { display: table-column-group }
td, th { display: table-cell }
caption { display: table-caption }
CSS only Approach (If height is known/fixed)
When you want the middle element to span across entire page vertically, you can use calc() which is introduced in CSS3.
Assuming we have a fixed height header and footer elements and we want the section tag to take entire available vertical height...
Demo
Assumed markup and your CSS should be
html,
body {
height: 100%;
}
header {
height: 100px;
background: grey;
}
section {
height: calc(100% - (100px + 150px));
/* Adding 100px of header and 150px of footer */
background: tomato;
}
footer {
height: 150px;
background-color: blue;
}
<header>100px</header>
<section>Expand me for remaining space</section>
<footer>150px</footer>
So here, what am doing is, adding up the height of elements and than deducting from 100% using calc() function.
Just make sure that you use height: 100%; for the parent elements.
A simple solution, using flexbox:
html,
body {
height: 100%;
}
body {
display: flex;
flex-direction: column;
}
.content {
flex-grow: 1;
}
<body>
<div>header</div>
<div class="content"></div>
</body>
Codepen sample
An alternate solution, with a div centered within the content div
Used:
height: calc(100vh - 110px);
code:
.header { height: 60px; top: 0; background-color: green}
.body {
height: calc(100vh - 110px); /*50+60*/
background-color: gray;
}
.footer { height: 50px; bottom: 0; }
<div class="header">
<h2>My header</h2>
</div>
<div class="body">
<p>The body</p>
</div>
<div class="footer">
My footer
</div>
How about you simply use vh which stands for view height in CSS...
Look at the code snippet I created for you below and run it:
body {
padding: 0;
margin: 0;
}
.full-height {
width: 100px;
height: 100vh;
background: red;
}
<div class="full-height">
</div>
Also, look at the image below which I created for you:
None of the solutions posted work when you need the bottom div to scroll when the content is too tall. Here's a solution that works in that case:
.table {
display: table;
}
.table-row {
display: table-row;
}
.table-cell {
display: table-cell;
}
.container {
width: 400px;
height: 300px;
}
.header {
background: cyan;
}
.body {
background: yellow;
height: 100%;
}
.body-content-outer-wrapper {
height: 100%;
}
.body-content-inner-wrapper {
height: 100%;
position: relative;
overflow: auto;
}
.body-content {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
<div class="table container">
<div class="table-row header">
<div>This is the header whose height is unknown</div>
<div>This is the header whose height is unknown</div>
<div>This is the header whose height is unknown</div>
</div>
<div class="table-row body">
<div class="table-cell body-content-outer-wrapper">
<div class="body-content-inner-wrapper">
<div class="body-content">
<div>This is the scrollable content whose height is unknown</div>
<div>This is the scrollable content whose height is unknown</div>
<div>This is the scrollable content whose height is unknown</div>
<div>This is the scrollable content whose height is unknown</div>
<div>This is the scrollable content whose height is unknown</div>
<div>This is the scrollable content whose height is unknown</div>
<div>This is the scrollable content whose height is unknown</div>
<div>This is the scrollable content whose height is unknown</div>
<div>This is the scrollable content whose height is unknown</div>
<div>This is the scrollable content whose height is unknown</div>
<div>This is the scrollable content whose height is unknown</div>
<div>This is the scrollable content whose height is unknown</div>
<div>This is the scrollable content whose height is unknown</div>
<div>This is the scrollable content whose height is unknown</div>
<div>This is the scrollable content whose height is unknown</div>
<div>This is the scrollable content whose height is unknown</div>
<div>This is the scrollable content whose height is unknown</div>
<div>This is the scrollable content whose height is unknown</div>
</div>
</div>
</div>
</div>
</div>
Original source: Filling the Remaining Height of a Container While Handling Overflow in CSS
JSFiddle live preview
CSS3 Simple Way
height: calc(100% - 10px); // 10px is height of your first div...
all major browsers these days support it, so go ahead if you don't have requirement to support vintage browsers.
It could be done purely by CSS using vh:
#page {
display:block;
width:100%;
height:95vh !important;
overflow:hidden;
}
#tdcontent {
float:left;
width:100%;
display:block;
}
#content {
float:left;
width:100%;
height:100%;
display:block;
overflow:scroll;
}
and the HTML
<div id="page">
<div id="tdcontent"></div>
<div id="content"></div>
</div>
I checked it, It works in all major browsers: Chrome, IE, and FireFox
Disclaimer: The accepted answer gives the idea of the solution, but I'm finding it a bit bloated with an unnecessary wrapper and css rules. Below is a solution with very few css rules.
HTML 5
<body>
<header>Header with an arbitrary height</header>
<main>
This container will grow so as to take the remaining height
</main>
</body>
CSS
body {
display: flex;
flex-direction: column;
min-height: 100vh; /* body takes whole viewport's height */
}
main {
flex: 1; /* this will make the container take the free space */
}
Solution above uses viewport units and flexbox, and is therefore IE10+, providing you use the old syntax for IE10.
Codepen to play with: link to codepen
Or this one, for those needing the main container to be scrollable in case of overflowing content: link to codepen
I've been searching for an answer for this as well. If you are fortunate enough to be able to target IE8 and up, you can use display:table and related values to get the rendering rules of tables with block-level elements including div.
If you are even luckier and your users are using top-tier browsers (for example, if this is an intranet app on computers you control, like my latest project is), you can use the new Flexible Box Layout in CSS3!
What worked for me (with a div within another div and I assume in all other circumstances) is to set the bottom padding to 100%. That is, add this to your css / stylesheet:
padding-bottom: 100%;
In Bootstrap:
CSS Styles:
html, body {
height: 100%;
}
1) Just fill the height of the remaining screen space:
<body class="d-flex flex-column">
<div class="d-flex flex-column flex-grow-1">
<header>Header</header>
<div>Content</div>
<footer class="mt-auto">Footer</footer>
</div>
</body>
2) fill the height of the remaining screen space and aligning content to the middle of the parent element:
<body class="d-flex flex-column">
<div class="d-flex flex-column flex-grow-1">
<header>Header</header>
<div class="d-flex flex-column flex-grow-1 justify-content-center">Content</div>
<footer class="mt-auto">Footer</footer>
</div>
</body>
If you can deal with not supporting old browsers (that is, MSIE 9 or older), you can do this with Flexible Box Layout Module which is already W3C CR. That module allows other nice tricks, too, such as re-ordering content.
Unfortunately, MSIE 9 or lesser do not support this and you have to use vendor prefix for the CSS property for every browser other than Firefox. Hopefully other vendors drop the prefix soon, too.
An another choice would be CSS Grid Layout but that has even less support from stable versions of browsers. In practice, only MSIE 10 supports this.
Update year 2020: All modern browsers support both display: flex and display: grid. The only one missing is support for subgrid which in only supported by Firefox. Note that MSIE does not support either by the spec but if you're willing to add MSIE specific CSS hacks, it can be made to behave. I would suggest simply ignoring MSIE because even Microsoft says it should not be used anymore. Microsoft Edge supports these features just fine (except for subgrid support since is shares the Blink rendering engine with Chrome).
Example using display: grid:
html, body
{
min-height: 100vh;
padding: 0;
margin: 0;
}
body
{
display: grid;
grid:
"myheader" auto
"mymain" minmax(0,1fr)
"myfooter" auto /
minmax(10rem, 90rem);
}
header
{
grid-area: myheader;
background: yellow;
}
main
{
grid-area: mymain;
background: pink;
align-self: center
/* or stretch
+ display: flex;
+ flex-direction: column;
+ justify-content: center; */
}
footer
{
grid-area: myfooter;
background: cyan;
}
<header>Header content</header>
<main>Main content which should be centered and the content length may change.
<details><summary>Collapsible content</summary>
<p>Here's some text to cause more vertical space to be used.</p>
<p>Here's some text to cause more vertical space to be used (2).</p>
<p>Here's some text to cause more vertical space to be used (3).</p>
<p>Here's some text to cause more vertical space to be used (4).</p>
<p>Here's some text to cause more vertical space to be used (5).</p>
</details>
</main>
<footer>Footer content</footer>
Example using display: flex:
html, body
{
min-height: 100vh;
padding: 0;
margin: 0;
}
body
{
display: flex;
}
main
{
background: pink;
align-self: center;
}
<main>Main content which should be centered and the content length may change.
<details><summary>Collapsible content</summary>
<p>Here's some text to cause more vertical space to be used.</p>
<p>Here's some text to cause more vertical space to be used (2).</p>
<p>Here's some text to cause more vertical space to be used (3).</p>
<p>Here's some text to cause more vertical space to be used (4).</p>
<p>Here's some text to cause more vertical space to be used (5).</p>
</details>
</main>
There's a ton of answers now, but I found using height: 100vh; to work on the div element that needs to fill up the entire vertical space available.
In this way, I do not need to play around with display or positioning. This came in handy when using Bootstrap to make a dashboard wherein I had a sidebar and a main. I wanted the main to stretch and fill the entire vertical space so that I could apply a background colour.
div {
height: 100vh;
}
Supports IE9 and up: click to see the link
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test</title>
<style type="text/css">
body
,html
{
height: 100%;
margin: 0;
padding: 0;
color: #FFF;
}
#header
{
float: left;
width: 100%;
background: red;
}
#content
{
height: 100%;
overflow: auto;
background: blue;
}
</style>
</head>
<body>
<div id="content">
<div id="header">
Header
<p>Header stuff</p>
</div>
Content
<p>Content stuff</p>
</div>
</body>
</html>
In all sane browsers, you can put the "header" div before the content, as a sibling, and the same CSS will work. However, IE7- does not interpret the height correctly if the float is 100% in that case, so the header needs to be IN the content, as above. The overflow: auto will cause double scroll bars on IE (which always has the viewport scrollbar visible, but disabled), but without it, the content will clip if it overflows.
CSS Grid Solution
Just defining the body with display:grid and the grid-template-rows using auto and the fr value property.
* {
margin: 0;
padding: 0;
}
html {
height: 100%;
}
body {
min-height: 100%;
display: grid;
grid-template-rows: auto 1fr auto;
}
header {
padding: 1em;
background: pink;
}
main {
padding: 1em;
background: lightblue;
}
footer {
padding: 2em;
background: lightgreen;
}
main:hover {
height: 2000px;
/* demos expansion of center element */
}
<header>HEADER</header>
<main>MAIN</main>
<footer>FOOTER</footer>
A Complete Guide to Grids # CSS-Tricks.com
This is my own minimal version of Pebbl's solution. Took forever to find the trick to get it to work in IE11. (Also tested in Chrome, Firefox, Edge, and Safari.)
html {
height: 100%;
}
body {
height: 100%;
margin: 0;
}
section {
display: flex;
flex-direction: column;
height: 100%;
}
div:first-child {
background: gold;
}
div:last-child {
background: plum;
flex-grow: 1;
}
<body>
<section>
<div>FIT</div>
<div>GROW</div>
</section>
</body>
I wresteled with this for a while and ended up with the following:
Since it is easy to make the content DIV the same height as the parent but apparently difficult to make it the parent height minus the header height I decided to make content div full height but position it absolutely in the top left corner and then define a padding for the top which has the height of the header. This way the content displays neatly under the header and fills the whole remaining space:
body {
padding: 0;
margin: 0;
height: 100%;
overflow: hidden;
}
#header {
position: absolute;
top: 0;
left: 0;
height: 50px;
}
#content {
position: absolute;
top: 0;
left: 0;
padding-top: 50px;
height: 100%;
}
Why not just like this?
html, body {
height: 100%;
}
#containerInput {
background-image: url('../img/edit_bg.jpg');
height: 40%;
}
#containerControl {
background-image: url('../img/control_bg.jpg');
height: 60%;
}
Giving you html and body (in that order) a height and then just give your elements a height?
Works for me
You can actually use display: table to split the area into two elements (header and content), where the header can vary in height and the content fills the remaining space. This works with the whole page, as well as when the area is simply the content of another element positioned with position set to relative, absolute or fixed. It will work as long as the parent element has a non-zero height.
See this fiddle and also the code below:
CSS:
body, html {
height: 100%;
margin: 0;
padding: 0;
}
p {
margin: 0;
padding: 0;
}
.additional-padding {
height: 50px;
background-color: #DE9;
}
.as-table {
display: table;
height: 100%;
width: 100%;
}
.as-table-row {
display: table-row;
height: 100%;
}
#content {
width: 100%;
height: 100%;
background-color: #33DD44;
}
HTML:
<div class="as-table">
<div id="header">
<p>This header can vary in height, it also doesn't have to be displayed as table-row. It will simply take the necessary space and the rest below will be taken by the second div which is displayed as table-row. Now adding some copy to artificially expand the header.</p>
<div class="additional-padding"></div>
</div>
<div class="as-table-row">
<div id="content">
<p>This is the actual content that takes the rest of the available space.</p>
</div>
</div>
</div>
style="height:100vh"
solved the problem for me. In my case I applied this to the required div
Vincent, I'll answer again using your new requirements. Since you don't care about the content being hidden if it's too long, you don't need to float the header. Just put overflow hidden on the html and body tags, and set #content height to 100%. The content will always be longer than the viewport by the height of the header, but it'll be hidden and won't cause scrollbars.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test</title>
<style type="text/css">
body, html {
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
color: #FFF;
}
p {
margin: 0;
}
#header {
background: red;
}
#content {
position: relative;
height: 100%;
background: blue;
}
#content #positioned {
position: absolute;
top: 0;
right: 0;
}
</style>
</head>
<body>
<div id="header">
Header
<p>Header stuff</p>
</div>
<div id="content">
Content
<p>Content stuff</p>
<div id="positioned">Positioned Content</div>
</div>
</body>
</html>
For mobile app i use only VH and VW
<div class="container">
<div class="title">Title</div>
<div class="content">Content</div>
<div class="footer">Footer</div>
</div>
.container {
width: 100vw;
height: 100vh;
font-size: 5vh;
}
.title {
height: 20vh;
background-color: red;
}
.content {
height: 60vh;
background: blue;
}
.footer {
height: 20vh;
background: green;
}
Demo - https://jsfiddle.net/u763ck92/
Try this
var sizeFooter = function(){
$(".webfooter")
.css("padding-bottom", "0px")
.css("padding-bottom", $(window).height() - $("body").height())
}
$(window).resize(sizeFooter);
I had the same problem but I could not make work the solution with flexboxes above. So I created my own template, that includes:
a header with a fixed size element
a footer
a side bar with a scrollbar that occupies the remaining height
content
I used flexboxes but in a more simple way, using only properties display: flex and flex-direction: row|column:
I do use angular and I want my component sizes to be 100% of their parent element.
The key is to set the size (in percents) for all parents inorder to limit their size. In the following example myapp height has 100% of the viewport.
The main component has 90% of the viewport, because header and footer have 5%.
I posted my template here: https://jsfiddle.net/abreneliere/mrjh6y2e/3
body{
margin: 0;
color: white;
height: 100%;
}
div#myapp
{
display: flex;
flex-direction: column;
background-color: red; /* <-- painful color for your eyes ! */
height: 100%; /* <-- if you remove this line, myapp has no limited height */
}
div#main /* parent div for sidebar and content */
{
display: flex;
width: 100%;
height: 90%;
}
div#header {
background-color: #333;
height: 5%;
}
div#footer {
background-color: #222;
height: 5%;
}
div#sidebar {
background-color: #666;
width: 20%;
overflow-y: auto;
}
div#content {
background-color: #888;
width: 80%;
overflow-y: auto;
}
div.fized_size_element {
background-color: #AAA;
display: block;
width: 100px;
height: 50px;
margin: 5px;
}
Html:
<body>
<div id="myapp">
<div id="header">
HEADER
<div class="fized_size_element"></div>
</div>
<div id="main">
<div id="sidebar">
SIDEBAR
<div class="fized_size_element"></div>
<div class="fized_size_element"></div>
<div class="fized_size_element"></div>
<div class="fized_size_element"></div>
<div class="fized_size_element"></div>
<div class="fized_size_element"></div>
<div class="fized_size_element"></div>
<div class="fized_size_element"></div>
</div>
<div id="content">
CONTENT
</div>
</div>
<div id="footer">
FOOTER
</div>
</div>
</body>
Spinning off the idea of Mr. Alien...
This seems a cleaner solution than the popular flex box one for CSS3 enabled browsers.
Simply use min-height(instead of height) with calc() to the content block.
The calc() starts with 100% and subtracts heights of headers and footers (need to include padding values)
Using "min-height" instead of "height" is particularly useful so it can work with javascript rendered content and JS frameworks like Angular2. Otherwise, the calculation will not push the footer to the bottom of the page once the javascript rendered content is visible.
Here is a simple example of a header and footer using 50px height and 20px padding for both.
Html:
<body>
<header></header>
<div class="content"></div>
<footer></footer>
</body>
Css:
.content {
min-height: calc(100% - (50px + 20px + 20px + 50px + 20px + 20px));
}
Of course, the math can be simplified but you get the idea...
I found a quite simple solution, because for me it was just a design issue.
I wanted the rest of the Page not to be white below the red footer.
So i set the pages background color to red. And the contents backgroundcolor to white.
With the contents height set to eg. 20em or 50% an almost empty page won't leave the whole page red.

How to remove the white space under my footer in Wordpress?

I have basic coding experience. In my Wordpress install, some of my pages have a blank white space under the footer that I would like to remove. I have tried several solutions but to no avail. The problem is persistent on chrome, Firefox, IE etc.
I'm not really sure of the cause, but the size of the white space changes depending on computer/browser/resolution.
As I am working in Wordpress I have access to custom CSS and source theme files, however, I would prefer to solve this problem with custom CSS.
I would like a footer that sticks to the bottom of the browser window with no whitespace below it.
Q. Please provide me with code/solution that will remove the white spaces below the footer on my website (preferably custom CSS method).
You can find an example of the white space on my website here. (try viewing on a browser resolution higher than 1280x800)
Solutions i've tried:
#footer {overflow: hidden;} didn't work
Putting html, body, parentDiv, childDiv, section, footer { height : 100%; } in my css but that didn't work
#copyright { padding-bottom: 20px;} "#copyright" is under the footer so this did reduce the whitespace to a point where it seemed it weren't present, but on taller browser windows the white space reappeared.
You have whitespace under the footer because the content is not sufficient to push it past the bottom of the monitor at higher resolutions.
I'd recommend using the Sticky Footer to handle this. It allows the minimum height of the body to be that of the browser, regardless of how little content is in the page.
The sticky footer solution requires some specific HTML to be included, and some basic CSS. Here's a Fiddle of Ryan Fiat's sticky footer in action using the code from his example.
The code goes like this:
HTML:
<body>
<div class="wrapper">
<p>Your website content here.</p>
<div class="push"></div>
</div>
<div class="footer">
<p>Footer content here</p>
</div>
</body>
CSS:
* {
margin: 0;
}
html, body {
height: 100%;
background-color:#eaeaea;
}
.wrapper {
min-height: 100%;
height: auto !important;
height: 100%;
margin: 0 auto -155px; /* the bottom margin is the negative value of the footer's height */
border:solid 1px red;
}
.footer, .push {
height: 155px; /* '.push' must be the same height as 'footer' */
}
.footer {
border:solid 1px blue;
}
Looking at your markup, you can use your existing div class="clear"></div> as your .push div, then you only need to add the div class="wrapper"> around your content.
Try something like this
html {
height: 100%;
}
body {
height: 100%;
flex-direction: column;
min-height: 100vh;
display: flex;
}
footer {
flex-shrink: 0;
}
.futovac {
flex: 1;
}
<html>
<body>
<main></main>
<div class="futovac"></div>
<footer></footer>
</body>
</html>
DEMO: https://help.podio.com/hc/en-us
find you code on .footer you code will be like this,
.footer-top-content .widget_links ul li a {
border-bottom: 1px #4C4C4C solid;
background: #333;
color:#999;
replace this code with this one,
.footer-top-content .widget_links ul li a {
border-bottom: 1px #4C4C4C solid;
background: #333;
color:#999 !important;
overflow: hidden;
this helped mine. hope for you too guys..

CSS layout with Source ordered Content

Beginning to wonder if I am missing something obvious but I have been searching for days now and still haven't been able to find a definitive answer.
What I am looking for is a Source ordered Content CSS layout for a two column page (menu to right) with header and sticky footer, and preferably no nasty hacks. Preferable Source order of:
{content}
{rightmenu}
{footer}
{header}
Like I say I'm not getting too far in trying to build this for myself, nor have I been able to find a suitable example anywhere. Any suggestions?
Thanks
content right, with sidebar left is perhaps the easiest floated layout to make, just float the content right with a width, let the left fill the space with overflow to avoid wrapping. footer goes below by clearing.
As for the header put a fake header div first in the source, presuming there may be a logo or something to go in it, even though you might not want hordes of links up there if there is a big dropdown menu to go in there or something like that. Anyway I'd make the "fake" header tall enough to create the space you need then put any actual content in it, then put the content you want to appear top only in a div at the bottom and absolutely position it.
here's a fiddled mockup
This is the best I can come up with at the moment. Bit of a mixture of relative and absolute positioning but seems to work. Can anyone see any problems with this.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html>
<head>
<style>
* {
margin: 0;
}
html, body {
height: 100%;
}
.container {
min-height: 100%;
/*height: auto !important;*/
height: 100%;
margin: 0 auto -2em;
}
.content{
float: left;
width: 80%;
}
.menu{
margin-left: 80%;
}
.header{
position: absolute;
top: 0px;
height: 3em;
width: 100%;
}
.clearheader{
height: 3em;
}
.footer, .clearfooter {
height: 2em;
clear: both;
}
.container {
background: grey;
}
.header{
background: cyan;
}
.clearheader{
background: cyan;
}
.footer{
background: blue;
}
.clearfooter {
background: lightblue;
}
</style>
<link rel="stylesheet" href="NJC layout2.css" ... />
</head>
<body>
<div class="container">
<div class="clearheader"></div>
<div class="content">Content</div>
<div class="menu">menu</div>
<div class="clearfooter"></div>
</div>
<div class="header">header</div>
<div class="footer">Footer</div>
</body>
</html>
If I understand your question right, this should be your answer:
http://www.positioniseverything.net/ordered-floats.html
I actually think this article is explaining everything quite nice.

Why does footer not go all the way to the bottom?

I have a web page as follows:
http://www.transeeq.com/health/bq17a.html#
The yellowish footer does not get pushed all the way to the bottom. Any ideas? Here is the CSS code:
#container {
min-height:100%;
position:relative;
}
#body {
padding-bottom:60px; /* Height of the footer */
}
#footer {
position:absolute;
bottom:0;
width:100%;
height:60px; /* Height of the footer */
background:#CCCC66;
}
It works; your CSS is probably being cached locally. Have you done a forced browser refresh lately? Hit Ctrl+F5.
Try the CSS code to achieve a "sticky footer" (per http://ryanfait.com/sticky-footer/).
* {
margin: 0;
}
html, body {
height: 100%;
}
.wrapper {
min-height: 100%;
height: auto !important;
height: 100%;
margin: 0 auto -142px; /* the bottom margin is the negative value of the footer's height */
}
.footer, .push {
height: 142px; /* .push must be the same height as .footer */
}
I use this css.
* {
margin: 0;
}
html, body {
height: 96%;
}
.wrapper {
min-height: 96%;
height: auto !important;
height: 96%;
margin: 0 auto -4em;
}
.footer, .push {
height: 4em;
}
And you can use it in your html page like this
<html>
<head>
<link rel="stylesheet" href="layout.css" ... />
</head>
<body>
<div class="wrapper">
<p>Your website content here.</p>
<div class="push"></div>
</div>
<div class="footer">
<p>Copyright (c) 2008</p>
</div>
</body>
</html>
It works very well in IE AND Firefox
I just tested it; it extends to the bottom in Chrome, Firefox, Opera, Safari, IE8, IE7, and even IE6. In which browser do you experience this problem, and can you describe your problem in more detail?
have you tried floating the footer to the bottom and changing the position to relative?
You have "height: 60px;" in #footer. Try making that a smaller number in the .css.
Put your footer inside the container div - if you want to have the footer at the bottom of the page (not the bottom of a window) using position:absolute, you need to put it in a relatively positioned div, such as your container.
Have a look at this article
Try position: fixed on the footer instead if you want to ensure that it's always at the bottom of the window. Otherwise, to ensure it's always at the bottom of the document, you can keep its position as relative/auto.

How do I force a DIV block to extend to the bottom of a page even if it has no content?

In the markup shown below, I'm trying to get the content div to stretch all the way to the bottom of the page but it's only stretching if there's content to display. The reason I want to do this is so the vertical border still appears down the page even if there isn't any content to display.
Here is my DEMO:
body {
font-family: Trebuchet MS, Verdana, MS Sans Serif;
font-size:0.9em;
margin:0;
padding:0;
}
div#header {
width: 100%;
height: 100px;
}
#header a {
background-position: 100px 30px;
background: transparent url(site-style-images/sitelogo.jpg) no-repeat fixed 100px 30px;
height: 80px;
display: block;
}
#header, #menuwrapper {
background-repeat: repeat;
background-image: url(site-style-images/darkblue_background_color.jpg);
}
#menu #menuwrapper {
height:25px;
}
div#menuwrapper {
width:100%
}
#menu, #content {
width:1024px;
margin: 0 auto;
}
div#menu {
height: 25px;
background-color:#50657a;
}
<form id="form1">
<div id="header">
<a title="Home" href="index.html" />
</div>
<div id="menuwrapper">
<div id="menu">
</div>
</div>
<div id="content">
</div>
</form>
Your problem is not that the div is not at 100% height, but that the container around it is not.This will help in the browser I suspect you are using:
html,body { height:100%; }
You may need to adjust padding and margins as well, but this will get you 90% of the way there.If you need to make it work with all browsers you will have to mess around with it a bit.
This site has some excellent examples:
http://www.brunildo.org/test/html_body_0.html
http://www.brunildo.org/test/html_body_11b.html
http://www.brunildo.org/test/index.html
I also recommend going to http://quirksmode.org/
I'll try to answer the question directly in the title, rather than being hell-bent on sticking a footer to the bottom of the page.
Make div extend to the bottom of the page if there's not enough content to fill the available vertical browser viewport:
Demo at (drag the frame handle to see effect) : http://jsfiddle.net/NN7ky
(upside: clean, simple. downside: requires flexbox - http://caniuse.com/flexbox)
HTML:
<body>
<div class=div1>
div1<br>
div1<br>
div1<br>
</div>
<div class=div2>
div2<br>
div2<br>
div2<br>
</div>
</body>
CSS:
* { padding: 0; margin: 0; }
html, body {
height: 100%;
display: flex;
flex-direction: column;
}
body > * {
flex-shrink: 0;
}
.div1 { background-color: yellow; }
.div2 {
background-color: orange;
flex-grow: 1;
}
ta-da - or i'm just too sleepy
Try playing around with the following css rule:
#content {
min-height: 600px;
height: auto !important;
height: 600px;
}
Change the height to suit your page. height is mentioned twice for cross browser compatibility.
you can kinda hack it with the min-height declaration
<div style="min-height: 100%">stuff</div>
You can use the "vh" length unit for the min-height property of the element itself and its parents. It's supported since IE9:
<body class="full-height">
<form id="form1">
<div id="header">
<a title="Home" href="index.html" />
</div>
<div id="menuwrapper">
<div id="menu">
</div>
</div>
<div id="content" class="full-height">
</div>
</body>
CSS:
.full-height {
min-height: 100vh;
box-sizing: border-box;
}
While it isn't as elegant as pure CSS, a small bit of javascript can help accomplish this:
<html>
<head>
<style type='text/css'>
div {
border: 1px solid #000000;
}
</style>
<script type='text/javascript'>
function expandToWindow(element) {
var margin = 10;
if (element.style.height < window.innerHeight) {
element.style.height = window.innerHeight - (2 * margin)
}
}
</script>
</head>
<body onload='expandToWindow(document.getElementById("content"));'>
<div id='content'>Hello World</div>
</body>
</html>
The min-height property is not supported by all browsers. If you need your #content to extend it's height on longer pages the height property will cut it short.
It's a bit of a hack but you could add an empty div with a width of 1px and height of e.g. 1000px inside your #content div. That will force the content to be at least 1000px high and still allow longer content to extend the height when needed
Try Ryan Fait's "Sticky Footer" solution,
http://ryanfait.com/sticky-footer/
http://ryanfait.com/resources/footer-stick-to-bottom-of-page/
Works across IE, Firefox, Chrome, Safari and supposedly Opera too, but haven't tested that. It's a great solution. Very easy and reliable to implement.
Try:
html, body {
height: 102%;
}
.wrapper {
position: relative;
height: 100%;
width: 100%;
}
.div {
position: absolute;
top: 0;
bottom: 0;
width: 1000px;
min-height: 100%;
}
Haven't tested it yet...
Sticky footer with fixed height:
HTML scheme:
<body>
<div id="wrap">
</div>
<div id="footer">
</div>
</body>
CSS:
html, body {
height: 100%;
}
#wrap {
min-height: 100%;
height: auto !important;
height: 100%;
margin: 0 auto -60px;
}
#footer {
height: 60px;
}
Try http://mystrd.at/modern-clean-css-sticky-footer/
The link above is down, but this link https://stackoverflow.com/a/18066619/1944643 is ok. :D
Demo:
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<meta name="author" content="http://mystrd.at">
<meta name="robots" content="noindex, nofollow">
<title>James Dean CSS Sticky Footer</title>
<style type="text/css">
html {
position: relative;
min-height: 100%;
}
body {
margin: 0 0 100px;
/* bottom = footer height */
padding: 25px;
}
footer {
background-color: orange;
position: absolute;
left: 0;
bottom: 0;
height: 100px;
width: 100%;
overflow: hidden;
}
</style>
</head>
<body>
<article>
<!-- or <div class="container">, etc. -->
<h1>James Dean CSS Sticky Footer</h1>
<p>Blah blah blah blah</p>
<p>More blah blah blah</p>
</article>
<footer>
<h1>Footer Content</h1>
</footer>
</body>
</html>
I think the issue would be fixed just making the html fill 100% also,
might be body fills the 100% of the html but html doesn't fill 100% of the screen.
Try with:
html, body {
height: 100%;
}
Also you might like this: http://matthewjamestaylor.com/blog/ultimate-2-column-left-menu-pixels.htm
It isn't quite what you asked for, but it might also suit your needs.
I dont have the code, but I know I did this once using a combination of height:1000px and margin-bottom: -1000px; Try that.
Depending on how your layout works, you might get away with setting the background on the <html> element, which is always at least the height of the viewport.
It is not possible to accomplish this using only stylesheets (CSS). Some browsers will not accept
height: 100%;
as a higher value than the viewpoint of the browser window.
Javascript is the easiest cross browser solution, though as mentioned, not a clean or beautiful one.
#content {
height: calc(100% - the amount of pixels the content div is away from the top);
}
So if your div is 200px from the top, the code you need would be
#content {
height: calc(100% - 200px);
}
I know this is not the best method, but I couldnt figure it out without messing my header, menu, etc positions. So.... I used a table for those two colums. It was a QUICK fix. No JS needed ;)

Resources