Fixed-position footers

This page describes a solution to the problem of creating a page with a fixed-position footer that is always displayed, while the rest of the content is free to scroll if required (depending upon the size of the browser window and the content).

See a working example

Constraints

A previous solution had used javascript to remedy the problem of fixed positioning and fixed backgrounds in IE. This obviously required that javascript be enabled, which I don't consider to be a serious shortcoming, but the solution didn't work particularly well. One serious shortcoming was that, in IE, the footer was not perfectly still while the main content was scrolled but flickered up and down. A new solution had to improve upon this and I was certain that it should be possible to implement without using javascript.

The design had to work across both Gecko- and IE-based browsers.

Highlights of the solution

Producing a fixed footer

Sensible browsers

The following shows the minimum markup and CSS required for sensible browsers (Firefox and IE7):

<!DOCTYPE html
	PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	"http://www.w3.org/1999/xhtml/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>Fixed footer example 1</title>
<style type="text/CSS">
	html, body{
		padding: 0px;
		margin: 0px;
	}

	body {
		padding-bottom: 70px;
		background-color: yellow;
	}

	#footer {
		position: fixed;
		bottom: 0;
		width: 100%;
		height: 70px;
		background-color: green;
	}
</style>
</head>

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

See an example.

First attempt for Internet Explorer 6

Some additions are required if this is to work in IE6. For a first attempt:

<!DOCTYPE html
	PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	"http://www.w3.org/1999/xhtml/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>Fixed footer example 2</title>
<style type="text/CSS">
	html, body {
		height: 100%;
		overflow: hidden;
		padding: 0px;
		margin: 0px;
	}

	body {
		padding-bottom: 70px;
	}

	#content {
		overflow: auto;
		height: 99.9%;
		background-color: yellow;
	}

	#footer {
		position: absolute;
		bottom: 0;
		width: 100%;
		height: 69px;
		background-color: green;
	}
</style>
</head>

<body>
<div id="content">
</div>
<div id="footer">
</div>
</body>
</html>

Looking at the result a number of problems are apparent: the footer now obscures the bottom part of the vertical scroll-bar, we cannot see the last of the main content text (it is obscured by the footer), and in Firefox there is a strange gap between the top of the browser window and the beginning of the content.

Problem fixing

Produce a 'footer-inner' div that contains the background colour, and set the right-hand margin to 17 pixels. This prevents the footer background colour from obscuring the scroll-bar. Put the background colour in the #contain-all div, preventing the white band at the top of the window. Add a margin at the bottom of the #content div, allowing us to see all of the content.

<!DOCTYPE html
	PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	"http://www.w3.org/1999/xhtml/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Fixed footer example 3</title>
<style type="text/css">
	html, body {
		height: 100%;
		overflow: hidden;
		padding: 0px;
		margin: 0px;
	}

	#outer {
		overflow: auto;
		height: 99.9%;
		background-color: yellow;
	}

	#contain-all{
		position: absolute;
		overflow: auto;
		width: 100%;
		height: 100%;
	}

	/* margin-bottom ensures that last
	content is not obscured by footer */
	#content {
		margin-bottom: 69px;
	}

	#footer {
		position: absolute;
		bottom: 0px;
		width: 100%;
		height: 69px;
	}

	#footer-inner {
		margin-right: 17px;
		height: 69px;
		background-color: green;
	}
</style>
</head>

<body>
<div id="outer">
	<div id="contain-all">
		<div id="inner">
			<div id="content">
			<p>some text</p>
			</div>
		</div>
	</div>
</div>

<div id="footer">
	<div id="footer-inner">
		<p>Footer</p>
	</div>
</div>
</body>
</html>

This has solved the problem of the footer obscuring the bottom of the scroll bar.

Cross-browser implementation

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	"http://www.w3.org/1999/xhtml/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Cross-browser implementation</title>

<style type="text/css">
	html, body{
		padding: 0;
		margin: 0;
	}

	/* using the child selector to hide the
	following body css from IE6 and earlier */
	html>body {
		background-color: yellow;
	}

	#footer {
		position:absolute;
		bottom:0;
		width:100%;
		height:69px;
	}

	/* for moz/opera and others*/
	html>body #footer{position:fixed}

	#footer-inner {
		height: 69px;
		background-color: green;
	}

	/* margin-bottom ensures last content
	is not obscured by footer */
	#content {
		margin-bottom: 69px;
	}
</style>

<!--[if lte IE 6]>
	<style type="text/css">
		html, body{
			height:100%;
			overflow:hidden;
		}

		#outer {
			overflow:auto;
			height:99.9%;
			background-color: yellow;
		}

		#contain-all{
			position:absolute;
			overflow:auto;
			width:100%;
			height:100%;
		}

		/* add margin to footer to avoid
		obscuring the scroll-bar */
		#footer-inner {
			margin-right:17px;
		}
	</style>
<![endif]-->
</head>

<body>
<div id="outer">
	<div id="contain-all">
		<div id="inner">
			<div id="content">
				<p>Some text</p>
			</div>
		</div>
	</div>
</div>

<div id="footer">
	<div id="footer-inner">
	</div>
</div>
</body>
</html>

Example

Actual implementation

The actual implementation has some more structural markup:

<!DOCTYPE html
	PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	"http://www.w3.org/1999/xhtml/DTD/xhtml1-strict.dtd">
<html>
<head>
<title></title>
</head>

<body>
<div id="outer">
	<div id="contain-all>
		<div id="inner>
			<div id="header">
			</div>
			<div id="cover">
			</div>
			<div id="nav">
			</div>
			<div id="content">
			</div>
		</div>
	</div>
</div>
<div id="footer">
	<div id="footer-inner">
		<div id="footer_bg">
		</div>
		<div id="bpllogo">
		</div>
	</div>
</div>
</body>
</html>

Complications

The most complicated part of this design was the bottom right background image. This has to be behind the main content for the most part, but also appears in the footer, where it must obscure the main content.

The real problem here was not getting a solution that would work in sensible browswers, it was supporting IE as well. Hence the second style-sheet included for IE < 7, simply to account for the inconsistency of the rendering between the IE and Mozilla engines.

Fixes for Internet Explorer

Internet Explorer 6 (and earlier)

Using child selector in the main CSS (IE6 and earlier doesn't understand the child selector, and so ignores all styles specified using it)

Using a separate stylesheet called using conditional comments

Internet Explorer 7

Using a separate stylesheet called using conditional comments

Problems with this solution

External links