Simulating frames with CSS

The essential problems with frames are: you lose the page as the unit of navigation; a single URL is no longer sufficient to specify a view; and bookmarks are broken.

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.

Remember that however good your interface is, it would be better if there were less of it.

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]-->
Conditional comments are a cleaner method of sending different CSS to different broweser than using browser hacks.

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.

External links