Sticky Footer Yet Again

I have read all the relevant sticky posts in this forum, and many tutorials outside Sitepoint, and still can’t get this to work.

I have my two navigation bars (one fixed at the top of the viewport, one not), the header, the content and the footer each centred in containers that stretch the entire width of the screen.

I have tried all sorts of sticky footer methods, but each time at least one of the following won’t work: the site staying centred, the footer sticking and the content area filling the whole height of the space between header and footer regardless of how little content there is.

If possible, I would love the height of the footer to be dynamic, but I can live with a fixed height.

Could someone please take a look at my code and help me figure out what is going wrong? Thank you.

html:

<!DOCTYPE html>

<html lang="en" class="no-js">
<head>
	<meta charset = "utf-8">
	<title></title>
	<link rel="stylesheet" type="text/css" href="style.css" />
</head>

<body>
<div id="outer-wrapper">	
	<div id="cart-container">
		
		<nav class="cart-navigation">
			<h1 class="site-title">
				My Sticky Footer Playground
			</h1>
			<ul>
				<li><a href="#">Shopping</a></li>
				<li><a href="#">Cart</a></li>
				<li><a href="#">Checkout</a></li>
				<li><a href="#">My Account</a></li>
			</ul>
		</nav><!-- end of .cart-navigation -->
	</div><!-- end of #cart-container -->	
		
	<div id="header-container">
		<header id="masthead">
			<nav class="main-navigation">
				<ul>
					<li><a href="#">Home</a></li>
					<li><a href="#">About Sticky Footers</a></li>
					<li><a href="#">My Attempts</a></li>
					<li><a href="#">My Contact Info</a></li>
				</ul>
			</nav><!-- end of .primary-navigation -->
				
		</header><!-- end of #masthead -->
	</div><!-- end of #header-container -->

	
	<div id="wrapper">
		

		<div id="content">
			
			<section id="main">
				<p>Some Content</p>
				<p>Some Content</p>
				<p>Some Content</p
				<p>Some Content</p>
				<p>Some Content</p>
				<p>Some Content</p>
				<p>Some Content</p>
				<p>Some Content</p>
				<p>Some Content</p>
				<p>Some Content</p>
			</section><!-- end of #main -->
			
			
		</div><!-- end of #content -->
		
	</div><!-- end of #wrapper -->
	<div class="push"></div>
</div><!-- end of #outer-wrapper -->
	
<div id="footer-container">
	<footer id="site-footer">
	
		<section>
			<p>Some Content goes here.</p>
			<p>Some Content goes here.</p>
			<p>Some Content goes here.</p>
		</section>
		
		<section>
		<br />
		<div class="site-info">
			<p>
				Copyright 2014
				<a href="#">The Sticky Footer Academy</a>	
			</p>
		</div>
		</section>
		
		<section id="footer-nav">
			<p>Some Content goes here.</p>
			<p>Some Content goes here.</p>
			<p>Some Content goes here.</p>
		</section>
		
		<div class="clear"></div>
	</footer>
</div><!-- end of #footer-container -->

</body>
</html>

CSS:

/**** Global Reset ****/
html, body {
	height: 100%;
}

html, body, h1, h2, h3, h4, h5, h6, p, a,
ul, li, footer, header, menu, nav, section
{
	margin: 0;
	padding: 0;
	border: 0;
	font-size: 100%;
	vertical-align: baseline;
	background: transparent;
}

article, aside, footer, header, nav, section {
	display: block;
}

/* force a vertical scrollbar to prevent a jumpy page */
html {
	overflow-y: scroll;
}

/***** General Site Styles *****/
body {
	background: #000;
	font-family: Verdana, Arial, sans-serif;
	font-size: 100%;
}

#outer-wrapper {
	height: 100%;
	min-height: 100%;
	height: auto !important;
	background: #c5a3ca; /* lilac */
	margin: 0 0 -160px 0;
}

#wrapper {
	width: 1000px;	
	height: 100%;
	margin: 0 auto;
	background: #f7caa6;  /* orange */
}

p {
	margin-bottom: 10px;
}

a:hover {
	color: #02750a;
}

.clear {
	clear: both;
}

/***** header styles *****/

#header-container {
	background: #ffccff;
}

#masthead {
	position: relative;
	width: 940px;
	margin: 0px auto 0 auto;
	height: 70px;
	padding: 50px 30px 0 30px;
	font-size: 90%;
	background: #eebbee;
}

.site-title {
	position: absolute;
	top: 0px;
	left: 30px;
	font-size: 1.2em;
}

/***** navigation styles *****/
nav ul {
	list-style: none;
}

nav ul a {
	text-decoration: none;
}

#cart-container {
	width: 100%;
	padding: 10px 0;
	background: #ddd;  /* grey */
	position: fixed;
	top: 0;
	z-index: 50;
}

.cart-navigation {
	position: relative;
	width: 940px;
	margin: 0 auto;
	padding: 10px 30px;
}

.cart-navigation ul {
	float: right;
	font-size: 0.9em;
}

.main-navigation {
	float: left;
	padding: 25px 0 0 30px;
	font-weight: bold;
}

.main-navigation ul li, .cart-navigation ul li {
	float: left;
	margin-right: 25px;
}

.left-navigation ul li:last-child, .cart-navigation ul li:last-child {
	margin-right: 0;
}

.left-navigation ul li, .cart-navigation ul li a {
	display: block;
}

/***** content styles *****/

#content {
	padding-bottom: 20px;
}

/***** #main styles *****/

#main {
	padding: 30px;
	background: #abcdef;
}

.push {
	height: 160px;
}
/***** footer styles *****/

#footer-container {
	background: #b1caa3;  /* light green */
	height: 160px;
}

#site-footer {
	width: 940px;
	margin: 0 auto;
	padding: 20px 30px;
	font-size: 90%;
	background: #bbb;  /* light grey */
}

footer section {
	width: 280px;
	float: left;
	padding: 10px;
	margin-right: 20px;
	background: #ccc;
}

footer #footer-nav {
	margin-right: 0;
}

Hi,

I have loads of these old demos tucked away but did you mean something like this codepen I just knocked up (IE8+ only).


<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Centred Fluid height sticky footer</title>
<!-- html5 shiv for IE8 and under -->
<!--[if lt IE 9]>
  <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<!-- If you aren't using jquery you can use the body element instead (body{width:100%;display:table;height:100%})of the #wrap div as jquery has a bug (
http://bugs.jquery.com/ticket/7261) in webkit when the body is display:table. -->
<style>
html, body, #wrap {
	margin:0;
	padding:0;
	height:100%;
}
body {
	background:#ccc;
}
#wrap {
	display:table;
	width:100%;
	position:relative;
	z-index:2;
}
/* if ie7 support is needed then set height of #wrap and header and footer to auto in CC's and just let it have a normal layout (or: *+html #wrap{height:auto})*/
.content {
}
header {
	background:#999;
	color:#fff;
	text-align:center;
	padding:10px 0
}
header, .footer, main {
	display:block
}/* ie7 and under*/
header, .footer, main {
	display:table-row
}
/* height 1px on the header and footer is the sticky footer technique */
header, .footer {
	height:1px
}
h1 {
	padding:10px;
	margin:0;
}
.footer {
	background:#999;
	color:#fff;
	text-align:center;
}
.footer p {
	margin:0;
	padding:10px
}
.inner {
	max-width:940px;
	margin:auto;
}
header .inner {
	background:#3333
}
main .inner {
	background:teal;
	height:100%;
	display:table;
	width:100%;
}
footer .inner {
	background:#333
}
</style>

<!-- ie8 and 9 don't make the middle section 100% high so we shim an absolute background underneath it. IE9 also needs a fixed width to work -->
<!--[if lte IE 9]>
<style>
body:after{
	content:" ";
	position:absolute;
	top:0;
	bottom:0;
	left:0;	
	right:0;
	width:940px;
	margin:auto;
	background:teal;
	z-index:-1;
}
.inner{width:940px}
</style>
<![endif]-->

</head>

<body>
<div id="wrap">
		<header>
				<div class="inner">
						<h1>Fluid Height Sticky footer - IE8+ (ie8 and 9 needf fixed width but everone else can be fluid)</h1>
				</div>
		</header>
		<main class="content">
				<div class="inner"> Content </div>
		</main>
		<footer class="footer">
				<div class="inner">
						<p>Sticky footer with fluid height Sticky footer with fluid height Sticky footer with fluid height Sticky footer with fluid height Sticky footer with fluid height Sticky footer with fluid height Sticky footer with fluid height </p>
				</div>
		</footer>
</div>
</body>
</html>

If you need to support IE7 and under then you need to go back to the old methods and use something like this. (and if you are supporting older browsers you need to use all the hacks mentioned in the faq and included in most of my old demos. All other sticky footers around the web fail in various browsers without the hacks developed here over the last 12 years. I haven’t found one sticky footer on any other site that works as well as the ones documented here in the forums.)

Thank you. That should do the trick. I will spend some time tonight to see if I can get it to work with my client’s site,
which is quite a bit more complicated than the demo page I uploaded here.

I just have one question about your solution though: I wanted to see if the footer would stay at the bottom of the page
if the page was longer than the viewport. But when I started adding more content to your demo using <br /> tags, the bottom of the main
section pulled up away from the footer (see image). What caused that, and how would I prevent it from happening?

Different animals. There is a difference between a sticky footer and a fixed footer. The former is what you requested and Paul delivered. If the page is shorter than the height of the viewport, the footer stays at the bottom of the viewport; if the page is longer than the viewport, the footer is pushed below the bottom of the viewport and remains at the bottom of the page. A fixed footer is usually position:absolute and is removed from the flow of the page regardless of the content. Flexbox offers an excellent alternative to position:fixed but it’s not uniformly implemented in all devices yet.

Yes, I understand that Paul gave me exactly what I was looking for. He originally had only one line of content, and the teal coloured content area stretched all the way down to fit snugly with the footer. But with his code, when I added content to make the page longer (just to test that the footer would indeed be pushed below the bottom of the viewport), at one point before the content got this long, the bottom of the content lifted up away from the footer. If you look at the image I posted, you will see the light grey gap just above the footer. What causes that and how do I fix it?

I see now. Your screenshot had not been approved when I was writing and I misinterpreted your post. Sorry.

I’ve not seen this design before, so I’m at a bit of a loss to explain the space beneath the teal area. I can’t seem to duplicate that effect in FF on my PC.

Can you post the full working page of code that does this?

Now I can’t duplicate that error either. :rolleyes: It must have been a typo on my part last time. I’m going to try to fit this to the site that I am working on, and I will come back here if I run into problems.

Is there a written explanation somewhere as to why the 1px height makes Paul’s code work the way it does?

For the sake of my learning as much as I can, would you or someone else be able to take a quick look at the code that I had in the opening post from a different sticky footer method I found somewhere, and tell me why it didn’t work with the negative margin?

The outer container, display:table, has been given a height of 100% of the viewport. The header and the footer have been given heights of 1px, whereas the middle row has no height assigned. Normally, table-cells treat height as min-height. Setting the height of the header and footer to 1px attempts to collapse the height to 1px while the contents extend it to fit. A classic table behavior. In this case, with no height assigned, the middle row extends to supply the height not occupied by the header and footer.

I’ll look, but no promises.

Reading your first post, I do not understand how that sticky footer is failing. (It doesn’t seem to be failing in FF to me.)

but each time at least one of the following won’t work: the site staying centred, the footer sticking and the content area filling the whole height of the space between header and footer regardless of how little content there is.

Could you possibly restate the problem(s) a different way?

Sorry. I posted it at the end of a very long, frustrating day trying to get something to work.

My problem with that code was that the footer stuck, but the content area did not reach all the way down to the footer. It left a gap if the page was too short.

OK, I see that. Paul can give you an authoritative answer. {height:100%} is a frequently misunderstood/misapplied property. The best I can say is say that there is no basis for {height:100%} on #wrapper to do anything. 100% of what? The parent container, #outer-wrapper, has a height of “auto” and a min-height of 100% which makes it unpredictable. There must be an uninterrupted chain of {height:100%} from <html><body> to the object where is it applied. That chain doesn’t exist.

Thanks. :slight_smile:

Ron has correctly explained the reason but just to te-iterate what happens is that when you set a table (or display:table in this case) to 100% high (or any height) then any rows in that table must fill the height of the table. So if you have two rows then generally they would be 50% tall each. However if you set one row to 1px tall then the other row must stretch the rest of the height of the table or the table will be broken. This is classic table behaviour and cells will adjust to fit as required and height on tables and cells is treated as a minimum and will always accommodate its content (a similar thing happens for width on cells in some circumstances).

So the sticky footer using display:table works because firstly we can set the table to 100% high to start (assuming html and body are at 100% to begin with). Although the table is height:100% it will not be limited by the height:100% (unlike a div which would overflow at content greater than 100%) but a table treats height as a minimum and allows the content to grow as required (like a div with min-height:100%). However a div with min-height cannot contain any more nested elements of 100% height because height collapses to zero. Only elements with an unbroken chain of height:100% can carry further height into the inner elements. A table doesn’t have this problem as the cells must always fit the table and will stretch as required.

Height:100% is completely misunderstood by most and the CSS faq contains an explanation on this and in the sticky footer thread.

Remember that in most cases all the work has to be done in side the one 100% high wrapper. You can’t really have multiple elements making up the 100% height unless the header and footer are fixed in height but I wiuld advise against that in these days of resonsive layouts. The display:table sticky footer is ideal for responsive layouts and works in ie8+ (for ie7 and under you can just add a couple of extra rules to make it a normal page without fixed footer).

We can simplify the design if we use box-shadow for the flashes at the side (ie9+).


<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<!-- html5 shiv for IE8 and under -->
<!--[if lt IE 9]>
  <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<!-- If you aren't using jquery you can use the body element instead (body{width:100%;display:table;height:100%})of the #wrap div as jquery has a bug (
http://bugs.jquery.com/ticket/7261) in webkit when the body is display:table. -->
<style>
html, body,#wrap {margin:0;	padding:0;	height:100%;}
body{background:#333}
#wrap {display:table;width:100%;background:#999}
#wrap{max-width:940px;margin:auto;}
/* if ie7 support is needed then set height of #wrap and header and footer to auto in CC's and just let it have a normal layout (or: *+html #wrap{height:auto})*/
.content { background:#ccc; }
header {	background:#999;	color:#fff;	text-align:center;	padding:10px 0}
header, footer, main { display:block}/* ie7 and under*/
header, footer, main { display:table-row }
/* height 1px on the header and footer is the sticky footer technique */
header, footer{height:1px}
h1{padding:10px;margin:0;}
footer {background:#999;	color:#fff;	text-align:center;}
footer p {	margin:0;	padding:10px}
.inner{
	-webkit-box-shadow: 940px 0px red, -940px 0px 0px red;/* 940px matches max width of #wrap */
	-moz-box-shadow:   940px 0px 0px red, -940px 0px 0px red;
	box-shadow:        940px 0px 0px red, -940px 0px 0px red;
}


</style>
</head>

<body>

<div id="wrap">
	<header><div class="inner"><h1>Fluid Height Sticky footer simple - IE8+ (no hacks )</h1></div></header>
	<main class="content">Content</main>
	<footer><div class="inner"><p>Sticky footer</p></div</footer>
</div>
</body>
</html>


IE8 just won’t get the side panels colours but will work ok.

Thank you very much, Paul. That explanation cleared thing up beautifully. I find that when I apply someone’s code to a site that I am working on, and something goes wrong, I can’t troubleshoot effectively if I don’t know exactly why the code worked in the first place and I end up randomly trying various fixes with no real sense of direction.

I am working on a WordPress site right now that needs a sticky footer. I will try this technique on it. If I can’t get it to work, I will definitely be back here. :slight_smile:

Good luck :slight_smile:

It can be awkward trying to implement it on existing sites as often the structure is not quite right.