Simulating frames with CSS
As we know, frames are evil. However, one thing that is easy with frames and difficult without them is keeping certain elements of a page visible when the rest of the page is scrolled. Whether you should do this is a question I leave to the reader, but the following is a cross-platform (IE and Mozilla) way to acomplish this using only valid XHTML 1.0 Strict and CSS.
The solution presented here was designed to replace a framed website that had a top frame to contain a header and a left-hand frame that displayed a navigation menu. The basic idea is to create three divs, one each for the header, navigation and content. The header and navigation divs are positioned absolutely, while the content is left relative.
See a working example and view the code.
<!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>Example of CCS-simulated framed page</title> <style type="text/css"> body { margin: 0; padding: 0 10px 0 10px; height: 100%; overflow-y: auto; } #content { margin: 113px 0px 0px 150px; display: block; padding: 10px; } #header { display: block; top: 0px; left: 0px; width: 100%; height: 112px; position: fixed; background-color: #ffffff; border: 1px solid #888; } #navigation { display: block; top: 113px; left: 0px; width: 142px; height: 100%; position: fixed; border: 1px solid #888; } * html #header {position: absolute;} * html #navigation {position: absolute;} </style> <!--[if lte IE 6]> <style type="text/css"> /*<![CDATA[*/ html {overflow-x: auto; overflow-y: hidden;} /*]]>*/ </style> <![endif]--> </head> <body> <div id="header"> </div> <div id="navigation"> </div> <div id="content"> </div> </body> </html>
Note the following code, which is placed in the document head
<!--[if lte IE 6]> <style type="text/CSS"> /*<![CDATA[*/ html {overflow-x: auto; overflow-y: hidden;} /*]]>*/ </style> <![endif]-->
This is a conditional comment: the code within it is executed (or not) depending upon the condition within the square brackets. Because all of the code is contained within HTML comments, browsers that don't understand conditional commments will ignore it. If the browser viewing the page is IE 5.01 or 5.5 or 6, then the above code adds a style that sets the overflow properties of the <html>
elememt to auto
and hidden
(for x and y respectively). If this code is omitted, then these browsers get a bit weird (Mozilla users won't see anything wrong).
View the full CSS. Note that I've tried to remove everything from the CSS that isn't actually required to get this to work. I've added borders around the header and navigation menu to make it clear what is happening, and specified a background colour for the header to prevent the main content from displaying behind it when it is scrolled. The code in the CSS body {margin:0; padding:0 10px 0 10px;}
isn't required for Mozilla-based browsers, but if it's not included then IE 6.0 includes a horizontal scroll-bar for no good reason (I have only tested this with Firefox and IE 6.0).
Problems with this solution
If you've played with the links in the above example, you'll have noted one of the problems with this method of simulating frames: namely that if you link to a section in a document, when navigating to that link the browser displays the first part of the content behind the header. This happens with both Mozilla and IE, and it's very irritating. I'm still working on a solution for this; in the meantime, don't use this technique if you need to link to sections within a document.