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).
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
- Fixed position footer
- Footer obscures main content behind it
- Background image which obscures content under the footer, but is behind the content otherwise
- Footer does not flicker while scrolling
- Works across Gecko (Firefox), IE6 and IE7
- No javascript
- Markup validates as XHTML 1.0 Strict
- Only a few ugly CSS hacks
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>
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)
- hide the fact that we're putting a background image in
<body>
- Do not use
position:fixed
for#footer
Using a separate stylesheet called using conditional comments
height
andoverflow
properties are set for<html>
,<body>
,#outer
and#contain-all
width
property is set for#contain-all
- a background image is added to
#outer
- the background image is changed and right margin adjusted for
#footer-inner
to avoid obscuring the scroll-bar
Internet Explorer 7
Using a separate stylesheet called using conditional comments
- remove the negative
margin-top
from#content
, as this prevented the#nav
links from working
Problems with this solution
External links
- Footer fixed to bottom and always displayed Example 1 Example 2 Example 3
- Footer fixed to bottom but can scroll off
- Fixed position background image
- QuirksMode
- On having layout