CSS Frames Example / Tutorial

This is an example page to demonstrate "CSS Frames".

The main reason people use frames is that they allow you to always have pertinent information on the screen. The navigation - for example - can be visible to users all the time without the need for any scrolling. Standard HTML frames, however, have some serious drawbacks.

You can read more on these drawbacks - and why an emulating technique usually referred to as CSS Frames is a better choice - in this article:

CSS Frames VS Standard HTML Frames


There are some exceptions though. If a website is to be viewed only by clients(browsers) within an intranet is one of the main exception. If this is the case I don't really see any problems in using standard HTML frames.

On non-intranet sites, such as sites on the Internet, one is better off using the "CSS Frames" technique. This technique - sometimes called "Frames without Frames", "Emulated Frames" or "Fake Frames" - make use of CSS to accomplish the same behaviour as with standard HTML frames. This is especially an useful technique when stricter versions of XHTML are prefered, since they don't allow the frameset tag.

Standard HTML frames - not recommended


<html>
    <frameset rows="100px,*,70px">
        <frame src="header-frame.htm">
        <frame src="content-frame.htm" name="content">
        <frame src="footer-frame.htm">
    </frameset>
</html>

Kind of easy, but - as already mentioned - not recommended due to all the drawbacks with HTML frames.

CSS frames - recommended

By using CSS frames you will avoid the drawbacks of standard HTML frames and still get the same kind of layout. The trick for real browsers is to use the "fixed" value of the "position" property in your style sheet for those section of the page that you don't wan't to scroll with the content of the page. On this page the header and footer has fixed positions.

This is what the the top level HTML code of this page looks like:


<html>
    <head>
    Meta information and title tag goes here
    <link rel="stylesheet" type="text/css" href="css-frames-style.css" />
    <!--For versions below Internet Explorer 7-->
    <!--[if lt IE 7]>
    <link rel="stylesheet" href="css-frames-style-unreal.css" type="text/css">
    <![endif]-->
    </head>
    <body>
        <div id="content-wrapper">
            <div id="content">
            Main content here
            </div>
        </div>
        <div id="header-wrapper">
            <div id="header">
            Header content here
            </div>
        </div>
        <div id="footer-wrapper">
            <div id="footer">
            Footer content here
            </div>
        </div>
    </body>
</html>

Linking the CSS file for real browsers

This line in the code example above will link to an external CSS file with the style sheet used for all browsers. It also contains the code to accomplish the frames in real browsers such as Firefox:

<link rel="stylesheet" href="css-frames-style.css" type="text/css">

To view the source code of this CSS file go to: CSS file for all browsers

Linking the CSS file for unreal browsers

This line in the code example above will link to an external CSS file with the style sheet used to accomplish the frames in unreal browsers such as Internet Explorer:

<link rel="stylesheet" type="text/css" href="css-frames-style-unreal.css" />

To view the source of this CSS file go to: CSS file for unreal browsers

Note that the file is linked to from the HTML document within a "Conditional Comment". You can read more on "Conditional Comments" in this article:

Browser Detection with Conditional Comments

This is a "Conditional Comment":


<!--[if some condition]>
    Conditional HTML markup code goes here
<![endif]-->

How to Create a Frames Layout with CSS

You will propably understand how to create "CSS Frames" just by looking at the CSS files. I will, however, describe the vital steps, and why they are taken.
The layout of this page has 1 column and 3 rows.


The header is visible in the top row and has this CSS code in the style sheets for all browsers, i.e. the style sheet found in the css-frames-style.css file:


/* Absolute positioned header for all browsers*/
div#header-wrapper {
    position:absolute;
    width:100%;
    top:0;
    left:0;
    height:100px;
}
/* Resets the header position to fixed for real browsers such as Firefox*/
body>div#header-wrapper {
    position:fixed;
}
div#header {
    height:100px;
    width:720px;
    margin:0 auto;
}

The main content is visible in the middle row and has this CSS code in css-frames-style.css:


div#content-wrapper {
    padding:6em 0 0 0;
    margin-left:0;
    voice-family: "\"}\""; 
    voice-family:inherit;
    margin-left:16px;
    padding-bottom:50px;
}

body>div#content-wrapper {
    margin-left:0;
}
div#content {
    width:720px;
    margin:0 auto;
}

The footer in the bottom row has this CSS code in css-frames-style.css:


div#footerwrap {
    width:100%;
    p\osition:absolute;
    bottom:0;
    left:0;
    height:50px;
}
body>div#footerwrap {
    position:fixed;
}
div#footer {
    height:50px;
    width:720px;
    margin:0 auto;
}

Internet Explorer workaround for the lack of support for "position:fixed"

Since the unreal browser Internet Explorer(version 6 and below) doesn't support the very useful "fixed" value of the "position" property, i.e. "position:fixed", a workaround is needed.


This workaround is found in the style sheet for Internet Explorer 6 and below, i.e. in the css-frames-style-unreal.css file. It looks like this:


html {
    overflow:hidden;
    }
body {
    height:100%;
    overflow:auto;
    }
#footer-wrapper {
    bottom:-3px;/* For certain IE widths */ 
    }
    
 

Basically, what it does is simulating the "fixed" value of the "position" property. The scrollbar that otherwise would appear when the "html element" is overflowed is moved to the "body element" by setting the value of the "overflow" property to "hidden" for the "html element" and to "auto" for the "body element". This will, however, not work in older versions of IE without the use of JavaScript workarounds - which I am trying to avoid.

Instead, for those browsers that don't support position:fixed or the workaround for position:fixed, the whole page will scroll as a normal non-framed layout. I.e., the page will still be perfectly accessible and readable, but it won't have the frame scrolling functionality when overflowed. This is accomplished by using position:absolute for the footer and header, and by using a child selector(the "less than" sign, e.g. body>div#header-wrapper { position:fixed }) - that only can be read by real browsers - to reset their their positions to fixed.

More on the layout of this page

The page is centered horizontally by having the left and right margins set to "auto" for each row in the layout.


This is done by using a common shorthand technique for the margins of each section, like this:


div#header {
  ...
  margin:0 auto;
}
div#content {
  ...
  margin:0 auto;
}
div#footer {
  ...
  margin:0 auto;
}

This shorthand technique does the same as if the values for each property were set individually, like this:


 margin-top:0;
 margin-right:auto;
 margin-bottom:0;
 margin-left:auto

Furthermore, I've put the HTML code for the content row first, followed by the HTML code for the header and the footer rows. This is done because it will make the page more readable for text browsers and search engines. Hence, more user and search engine friendly. Search Engine Optimization(SEO) is actually one of the reasons it's better to use CSS frames instead of standard HTML frames.

Having the content first doesn't effect the layout for visual browsers since the rows(header, content and footer sections) all have absolute and fixed positions.

To understand what I mean by "more readable in text browsers and search engines" you can view this page with a browser such as Firefox with "Page Style" set to "No Style"(No CSS file will be loaded) and compare the order of the rows/sections with the page source.

And last, but not least: I use the em unit for the font since this makes the font resizable in browsers like Internet Explorer.
That's it. Good luck and happy coding!