I have a page layout in which I have a fixed header which can have any height and a footer positioned at the bottom of the page. I'm looking for a css solution so that the content div fills the remaining space (vertically). In the jsfiddle below I've tried to do this, but as you can see the content is behind the footer.
HTML:
<main>
<header>
<ol>
<li>bar</li>
<li>foo</li>
</ol>
</header>
<section>
<div class="content"><div>
</section>
<footer></footer>
</main>
CSS:
header {
background-color: #abc;
z-index: 1000;
position: fixed;
top: 0px;
right: 0px;
left: 0px;
}
html, body, main, section {
height: 100%;
display: block;
}
.content{
background-color: #000;
height: 100%;
}
footer {
background-color: #def;
bottom: 0;
display: block;
height: 54px;
position: absolute;
width: 100%;
}
Is this possible with pure css(3) ?
jsfiddle
It is a bit of an ugly solution, but if you make the margin-top of the content div as -54px and add a div inside it with padding-top:54px, it works as expected.
HTML:
<div class="content"><div class="contentwrapper"></div><div>
CSS:
.contentwrapper {
padding-top:54px;
}
.content{
background-color: #000;
height: 100%;
margin-top:-54px;
}
Fiddle: http://jsfiddle.net/dohqn8m4/1/
Here a diffrent approach:
HTML:
<header>
<ol>
<li>bar</li>
<li>foo</li>
</ol>
</header>
<main>
<section>
<div class="content"></div>
</section>
<div class="push"></div>
</main>
<footer></footer>
CSS:
html, body {
height: 100%;
min-height: 100%;
margin: 0;
padding: 0;
border: 0;
}
header {
background-color: #abc;
z-index: 1000;
position: fixed;
top: 0;
right: 0;
left: 0;
}
main {
min-height: 100%;
height: auto !important;
margin-bottom: -54px;
}
main > section{
padding-top: 72px;
}
.content {
background-color: #000;
}
.push {
height: 54px;
}
footer {
background-color: #def;
height: 54px;
}
Now the footer is always at the bottom aslong the content doesn't fill the hole page. In that case the "push" element provides enough space to deny overlapping of footer and content.
Your content div ist now placed under the footer through the padding. The height is actually 0 because of missing content. In my approach the content div fits always the content inserted.
Keep in mind that
a) for responsive purpose you had to know about the header height and adjust the padding of the section using media queries
b) the same for the footer. Adjust the height of the push element and adjust the margin-bottom value.
jsFiddle
Try positioning the content to be right above the footer
bottom: <footer-height>;
position: absolute;
I made sticky footer using this tutorial. I think it's easy and convenient to use.
CSS CODE
html {
position: relative;
min-height: 100%;
}
body {
margin: 0 0 100px; /* bottom = footer height */
}
footer {
position: absolute;
left: 0;
bottom: 0;
height: 100px;
width: 100%;
}
HTML CODE
<!DOCTYPE html>
<head>
<title></title>
</head>
<body>
<nav></nav>
<article>Lorem ipsum...</article>
<footer></footer>
</body>
</html>
DEMO URL
Related
I am trying to keep an element from scrolling past left: 0 using position: sticky. This works fine in some cases, but I have noticed that if the element width increases it stops working. For example, the following works:
#header {
position: sticky;
left: 0;
width: 50%;
background-color: #888;
}
#page {
height: 80vh;
width: 120vw;
background-color: #000;
}
<div>
<div id="header">
Where is my mind?
</div>
<div id="page">
</div>
</div>
But if I increase the witdth of header element to 100% it stops working.
#header {
position: sticky;
left: 0;
width: 100%;
background-color: #888;
}
#page {
height: 80vh;
width: 120vw;
background-color: #000;
}
<div>
<div id="header">
Where is my mind?
</div>
<div id="page">
</div>
</div>
Why does this happen? And is there any way to use position: sticky to prevent the header element from scrolling when it's width is 100%? I prefer not to use position: fixed in this case.
I now understand what is happening. The issue is the different way the browser treats the width and height of a <div>. The default values of auto mean that the width of the <div> is 100% while the height is set by the content. If the content is wider than 100%, then on horizontal scroll the sticky element hits the end of the container <div> and, since it cannot leave the confines of the container, begins to scroll. This doesn't happen in the same situation for vertical scrolling since the container <div> is as tall as the content by default.
To prevent this happening, we have to ensure that the container <div> is as wide as its content. This can be done in most browsers (not Edge or Explorer) by including width: max-content in the container style. Alternatively, as proposed in mfluehr's answer, putting overflow: auto creates a new block formatting context that is as wide as the content. Another option is to use display: inline-block or inline-flex etc. to cause the container <div> to base its width on the content.
For example, using two of these techniques, you can create headers, sidebars and footers that stick for a page that can scroll vertically and horizontally:
body {
padding: 0;
margin: 0;
}
#app {
overflow: auto;
height: 100vh;
}
#header {
background: blue;
width: 100%;
height: 40px;
position: sticky;
top: 0;
left: 0;
z-index: 10;
color: white;
}
#sidebar {
position: sticky;
background: green;
width: 200px;
height: calc(100vh - 40px);
top: 40px;
left: 0;
color: white;
flex-grow: 0;
flex-shrink: 0;
}
#container {
display: inline-flex;
}
#content {
background: #555;
height: 200vh;
width: 200vw;
background: linear-gradient(135deg, #cc2, #a37);
flex-grow: 0;
flex-shrink: 0;
}
#footer {
background: #000;
height: 100px;
z-index: 100;
left: 0;
position: sticky;
color: white;
}
<div id="app">
<div id="header" ref="header">
Header content
</div>
<div id="container">
<div id="sidebar" ref="sidebar">
Sidebar content
</div>
<div id="content" ref="content">
Page content
</div>
</div>
<div id="footer" ref="footer">
Footer content
</div>
</div>
This is an interesting problem. I don't know why, but putting overflow: auto on the container around the <div>s seems to fix the issue.
You can add height: 100vh to the container to let the content inside overflow with scrollbars.
body {
margin: 0;
}
#container {
overflow: auto;
height: 100vh;
}
#header {
position: sticky;
left: 0;
width: 100%;
background-color: #888;
}
#page {
height: 200vh;
width: 120vw;
background: linear-gradient(135deg, #cc2, #a37);
}
<body>
<div id="container">
<div id="header">
This is the header.
</div>
<div id="page">
Page content goes here.
</div>
</div>
</body>
I'm having some issues with min-height: 100%
I want the footer always below my content. Meaning, if the content is longer than the screen height, you don't see the footer, until you've scrolled all the way to the bottom
Also, when the content is shorter than the screen height, the footer needs to be at the bottom of the screen. Well, I thought I solved this just by adding min-height: 100%
<html>
<head>
<style>
html, body, main { min-height: 100% }
</style>
</head>
<body>
<main>
<article> .... </article>
<footer> ... </footer>
</main>
</body>
</htm>
DEMO
Now, for some reason the body tag seems to ignore this setting and its height simply fits the content.
Unfortunately, you can't just set the body to 100% ( DEMO )
Any suggestions how to fix this ?
Sticky footer 'hack' is usually done with the min-height and negative margin-bottom on the footer parent element. All parent elements up until root html, need to have height:100%;
article{
//height: calc(100% - 50px);
min-height: 100%;
background: yellow;
padding-bottom: 50px;
margin-bottom:-50px;
}
JSFIDDLE LONG CONTENT
JSFIDDLE SHORT CONTENT
The fantastic CSS Tricks website has, in their Snippets area a snippet for a Sticky Footer:
http://css-tricks.com/snippets/css/sticky-footer/
Or using jQuery:
http://css-tricks.com/snippets/jquery/jquery-sticky-footer/
latest link with demo
Or you can simply use Modern Clean CSS “Sticky Footer” from James Dean
So just change your HTML and CSS to this:
HTML
<!DOCTYPE html>
<head>
<title></title>
</head>
<body>
<main>
<article> .... </article>
</main>
<footer> ... </footer>
</body>
</html>
CSS
html {
position: relative;
min-height: 100%;
}
body {
margin: 0 0 100px; /* bottom = footer height */
}
footer {
position: absolute;
left: 0;
bottom: 0;
height: 100px;
width: 100%;
}
Demo here
You can use display:flex for this:
html,
body {
padding: 0;
margin: 0;
height: 100%
}
main {
min-height:100%;
display: flex;
flex-direction: column;
background:blue;
}
article {
flex-grow: 1;
background:green;
}
footer {
background:orange;
}
<main>
<article>... </article>
<footer> ... </footer>
</main>
I modified your css to put the footer and the article in a relative position:
* {
margin: 0;
box-sizing: border-box;
padding: 0;
}
article {
height: calc(100% - 50px);
position: relative;
}
main {
background-color:lightgray;
}
footer {
background-color: green;
height: 50px;
position: relative;
bottom: 0;
width: 100%;
}
the fiddle:
http://jsfiddle.net/np9n4ckb/5/
If you don't want to mess with positioning, you can use vh units.
1vh equals 1% of the viewport's height.
(For reference, this is a good read: https://web-design-weekly.com/2014/11/18/viewport-units-vw-vh-vmin-vmax/)
Fiddle: http://jsfiddle.net/np9n4ckb/6/
CSS
* {
margin: 0;
box-sizing: border-box;
padding: 0;
}
html, body {
min-height: 100vh; /* Minimum height is the full viewport */
}
article {
min-height: calc(100vh - 50px); /* Minimum height is the viewport height minus the footer */
}
main {
background-color:lightgray;
}
footer {
background-color: green;
height: 50px;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
/* browser reset */
html {
height: 100%;
position: relative;
min-height: 100%: padding-bottom: 50px;
/* equal to footer height */
}
body {
height: 100%;
color: #fff;
}
footer {
position: absolute;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 50px;
background: #ccc;
}
header {
background: #333;
}
main {
background: tomato;
}
<html>
<body>
<header>Menu</header>
<main>content of unknown height!!</main>
<footer>footer always stays at bottom</footer>
</body>
</html>
This is just what you need to do.
I am developing a site where I have a fixed header and a fixed footer. I am trying to get my content to be full page when there is not enough content and still be scrollable when there is.
What I have so far does this, but I am left with some extra space at the end of my page. How can I get rid of this extra space at the bottom?
Here is a jsFiddle: http://jsfiddle.net/0yz9nx35/1/
As you can see in the fiddle there is still a scrollbar showing empty space at the bottom of my page
My code:
<div class="wrapper">
<div class="header"></div>
<div class="content"></div>
<div class="footer"></div>
</div>
CSS:
html { height: 100%; margin: 0px; padding: 0px; }
body { height: 100%; margin: 0px; padding: 0px;}
.wrapper { min-height: 100%; height: 100%; padding-top: 60px; }
.header { position: fixed; top:0px; left:0px; height:60px; background-color: #333; width: 100%;}
.footer { position: fixed; bottom:0px; left:0px; height:50px; background-color: #333; width: 100%;}
You can use that on the wrapper class:
height: calc(100% - 60px)
Or maybe you could change the structure of your page by something like:
<!DOCTYPE html>
<html>
<head>
<style>
* { margin: 0; padding: 0; }
#global { height: 100vh; }
#header { height: 60px; background-color: orange; }
#content { height: calc(100% - (60px + 50px)); background-color: gray; }
#footer { height: 50px; background-color: green; }
</style>
</head>
<body>
<div id="global">
<div id="header">
Aenean
</div>
<div id="content">
lacinia
</div>
<div id="footer">
quam
</div>
</div>
</body>
</html>
Remove the body {height:100%;} add some padding bottom on wrapper to compensate for the fixed footer height. Here is the fixed fiddle:
http://jsfiddle.net/0yz9nx35/9/
you can add overflow-y: hidden; do remove the scrollbar at the bottom.
If you want any scroll bar to be on the .content block, you can try the following.
You can make .content fixed such that the top and bottom edges are below the header and above the footer respectively.
In this approach, you may not need the .wrapper block element unless you need it for placing some background images, for example.
html, body {
height: 100%;
margin: 0px;
padding: 0px;
}
.wrapper {
height: 100%;
}
.header {
position: fixed;
top: 0px;
left: 0px;
height: 60px;
background-color: #333;
width: 100%;
}
.footer {
position: fixed;
bottom: 0px;
left: 0px;
height: 50px;
background-color: #333;
width: 100%;
}
.content {
position: fixed;
top: 60px;
bottom: 50px;
left: 0px;
background-color: beige;
width: 100%;
overflow: auto;
}
<div class="wrapper">
<div class="header"></div>
<div class="content">
Content goes here<br>
and<br>and<br>and<br>and<br>and<br>and<br>and<br>and<br>and<br>and<br>
the end.
</div>
<div class="footer"></div>
</div>
I'm using Twitter Bootstrap's 'sticky footer' CSS to ensure my footer appears at the bottom of my page. How can I make my content (the blue div in the example) stretch all the way down to the footer (the yellow div in the example)? I've tried making .content 100% height but that has no effect.
My CSS
html {
position: relative;
min-height: 100%;
}
body {
/* Margin bottom by footer height */
margin-bottom: 60px;
}
.content {
height: 100%;
}
.footer {
position: absolute;
bottom: 0;
width: 100%;
/* Set the fixed height of the footer here */
height: 60px;
background-color: #f5f5f5;
}
My HTML
<body>
<div class="header">This is my header</div>
<div class="content">This is my content</div>
<div class="footer">This is my footer</div>
</body>
Example: http://jsfiddle.net/pjktqnmo/1/
Ref: http://getbootstrap.com/examples/sticky-footer-navbar/sticky-footer-navbar.css
Update: My header contains my page title so the height of the header varies from page to page.
here is a solution with no position property being used.
see snippet below:
html, body {
height: 100%;
margin: 0;
color:grey;
}
.header {
background-color:red;
}
.content {
min-height: 100%;
margin-bottom: -60px; /* equal to footer height */
background-color:blue
}
.content:after {
content:"";
display: block;
}
.footer, .content:after {
height: 60px;
}
.footer {
background: yellow;
}
<body>
<div class="header">This is my header</div>
<div class="content">This is my content</div>
<div class="footer">This is my footer</div>
</body>
More info here: sticky footer
UPDATED ANSWER Based on a Discussion with OP, where OP stated that doesn't want to have a Vertical ScrollBar, therefore here is a solution below:
What I did? Make your div .header child of div .content, with 0 changes on CSS regarding my 1st snippet above.
html, body {
height: 100%;
margin: 0;
color:grey;
}
.header {
background-color:red;
}
.content {
min-height: 100%;
margin-bottom: -60px; /* equal to footer height */
background-color:blue
}
.content:after {
content:"";
display: block;
}
.footer, .content:after {
height: 60px;
}
.footer {
background: yellow;
}
<div class="content">
<div class="header">This is my header</div>
This is my content
</div>
<div class="footer">This is my footer</div>
If your header is 30px tall, and your footer is 60px tall, this should work for the content:
position: absolute;
left: 0;
right: 0;
top: 31px;
bottom: 61px;
Set the height like this:
html, body {
height: 100%;
}
.content {
min-height: 100%;
}
http://jsfiddle.net/pjktqnmo/6/
It's working pretty well with javascript.
It also allows you to have to good height when user changes window dimensions.
Call this on page load and when user changes the window dimension:
$('.content').css('height',$(document).height() - ($('.header').height() + $('.footer').height() + `MARGIN TOP OR PADDING`) - $('.contact').height());
You could try using a table instead as a container for your page. Make sure that your <html>, <body>, and <table> elements have their width and height at 100%.
Make three rows in your table and put your header, content, and footer into each row, then make the content row 100% height so it will take up the rest of the page space.
Lastly, remove the spacing between the table cells
html {
position: relative;
min-height: 100%;
}
body {
/* Margin bottom by footer height */
margin-bottom: 60px;
}
.header {
background-color: green;
}
.content {
height: 100%;
background-color: cyan;
}
.footer {
width: 100%;
/* Set the fixed height of the footer here */
height: 60px;
background-color: #f5f5f5;
}
html, body {
width: 100%;
height: 100%;
margin: 0px;
}
table {
width: 100%;
height: 100%;
border-spacing: 0px;
}
td {
padding: 0px;
}
.contentCell {
height: 100%;
}
<body>
<table>
<tr>
<td>
<div class="header">This is my header</div>
</td>
</tr>
<tr class="contentCell">
<td>
<div class="content">This is my content</div>
</td>
</tr>
<tr>
<td>
<div class="footer">This is my footer</div>
</td>
<tr>
</table>
</body>
Ok so I've got a header and a footer with absolute positioning and heights of 144px. The content div in the middle area needs to be the full height of the area in between.
Simplified:
<style>
.marginals{
position: absolute;
height: 144px;
width: 100%;
left: 0;
}
#header{ top: 0px; }
#footer{ bottom: 0px; }
</style>
<div id="header" class="marginals"></div>
<div id="content"> Content </div>
<div id="footer" class="marginals"></div>
So basically I want a div that is 100% - 288px. At first I thought I could just make a 100% x 100% div with 144 padding on top and bottom and then stuff the content div in there at 100% but my thinking has gone stray somewhere.
Here's an example I made using 20% height for 'bread layers'. (Which I can't do on this project) Used 60% height for the scrolling 'meaty layer' and put it at top: 20%;
What you have won't work, tables and absolute positioning don't go well together, and height on table rows and cells is not handled consistently across browser anyway so I think you'd find it hard to get the top/bottom rows to stay a fixed height while still asking the middle row to scroll
however I think you were right with your original posting and using absolute positioning, you don't need percentages though, you can use the top and bottom co-ordinates tohether, so you can tell the middle div to start at 144px from top and finish 144px from bottom..
e.g.
HTML:
<div class="header">Some header content</div>
<div class="wrap">
Bulk content<br>bulk content<br>bulk content<br>bulk content<br>
Bulk content<br>bulk content<br>bulk content<br>bulk content
</div>
<div class="footer">Some footer content</div>
CSS:
html, body {margin: 0; padding: 0; height: 100%; overflow: hidden;}
.wrap {
position: absolute;
left: 0;
top: 144px; /* = height of header including any borders or padding */
bottom: 144px; /* = height of footer including any borders or padding */
width: 100%;
background: #fff;
overflow: auto;
}
.header, .footer {
position: absolute;
width: 100%;
left: 0;
height: 140px;
background: #f00;
}
.header {
top: 0;
border-bottom: 4px solid #000;
}
.footer {
bottom: 0;
border-top: 4px solid #000;
}
The whole thing is based on the html, body elements having the height of 100% set
Example: here
Looks like you're trying to create a 3 liquid row-layout. Why not try something like this:
Fiddle: http://jsfiddle.net/jCjsD/2/
HTML
<body>
<div id="body_container">
<div id="header">Some header content</div>
<div id="content"><!-- Bulk content here !--></div>
</div>
<div id="footer">Footer</div>
</body>
CSS
#header, #content, #footer {
float: left;
width: 100%;
}
#header {
border-bottom: 1px solid #888;
background: yellow;
}
#footer {
border-top: 1px solid #888;
background: yellow;
}
#content {
clear: both;
padding-bottom: 50px;
}
#footer {
position: relative;
margin-top: -50px;
height: 50px;
clear:both;
}
html, body {
height: 100%;
padding: 0;
margin: 0;
}
#body_container {
min-height: 100%;
}