psst.. this blog is on hiatus.

Quasi-frames with CSS: A layout with a different flavor

Many moons ago, when I was but a lad of 14, I was mesmerized as a classmate told me of new technology hitting the World Wide Web: frames. To say the least I was impressed. This frames stuff was hot. (Incidentally, that classmate was the son of Larry Smarr, former director of NCSA.)

But we users of Netscape 2.0 were young and naïve. Now we know better; frames suck(ed), for a variety of reasons. But frames were still useful, particularly in the way they presented content. The navigation was clear; the header was clear; the content was clear. As the user moved from page to page, much of the content remained static, imparting a feeling of security. Today, with the almost total depature of frames, the security blanket of frames has been lost.

Recovering the “security blanket”—with CSS

Today, I drew up a quick CSS layout for a coworker. It forced me to get back to the basics with CSS layouts, and I remembered a time a few years ago when I tried with limited success to use the position:fixed CSS property in a previous design. But as I composed this simple layout—header, nav, content area, and footer—I thought back to the position:fixed experiment. Maybe there was something useful there, after all. And maybe, a few years later and with a few more Web standards, well, standard, I could make it work.

So I mocked it up, real-simple like, and here ’tis:

Quasi-frames with CSS
(View source for HTML and CSS)

What’s going on here? Well, nothing too fancy schmancy. It’s your basic, flavor-of-the-month header+2col+footer layout, with the 2col background-color achieved via faux columns. However, it is rather rare to see a layout of this type with a footer of the fashion you see here. This is the behavior of the layout in various browsers:

  • Mozilla Firefox and Gecko browsers: header is fixed, navigation column is fixed, content scolls, footer at bottom after nav/content
  • Opera: same as Mozilla
  • Microsoft Internet Explorer 6: ignores position:fixed and treats this as a normal header+2col+footer layout, scrolling everything. It degrades nicely.
  • Safari: I dunno, I can’t test it! Someone tell me!

Caveats

Important point: keep the content in the navigation column short. If it goes long, it displays very strangely. But as long as you’ve got just a handful of links in your nav, you’re golden.

Also, note the quirkiness of the scrolling. It’s nice in that you get the “frame-like” behavior of a fixed header and navbar combined with a footer beneath everything, and it’s great that it scrolls via the window’s scrollbar, not some internal frame’s. The disadvantage of this behavior is that the content actually scrolling beneath the header DIV (which has a >1 z-index, so if you e.g. link to an in-page anchor, the header can cover up the beginning of the content to which you’re linking.

Other CSS as frames layouts

Well, I’m certainly not the first to do a layout like this. While I concentrated on the position:fixed property, many others keyed in on the overflow:scroll property to truly simulate frames, scrollbars and all. That CSS property comes with its own set of caveats and browser problems which I won’t delve into here. However, I will link you to some excellent resources:

Feedback welcome!

11 Responses to “Quasi-frames with CSS: A layout with a different flavor”

  1. 1
    Matthew Blake Says:

    This is a little late, but I just wanted to tell you that it works on Safara 2.0 just like it would on Mozilla or Firefox.

  2. 2
    Matthew Blake Says:

    *Safari*…..sorry for the second post. I also forgot to say that I really like your approach to solving this problem.

  3. 3
    Rick Says:

    So I have been looking into quite a few tutorials on this “css frame” solution and I am stumped on one thing…With frames, I can set up links/buttons on one side that when clicked, the opposing frame loads another page. How does this work using CSS without having the other page include the menu, the header, the footer, etc. Can a div tag hold “content.html” until a nav button is clicked, at which point “content2.html” is loaded in the div?

  4. 4
    tom sherman Says:

    Rick: Not possible. The entire page will reload. What you want to use is an IFRAME.

  5. 5
    Lars Henning Says:

    This is excellent. I was searching for an alternative to the dreaded framesets and iframes. They are such a pain. This works well. I have modified the css by using relative positioning of the content frame. This allows for auto margining the container (an thus centering it) for websites where the nav is horizontal, not vertical.

  6. 6
    phil vas Says:

    I agree: this is excellent if you’re dealing with a vertically scrollbar. But is there a solution to the position:fixed/IE problem for horizontal scrollbars?

  7. 7
    Daniel Says:

    I just wanted to note that Safari is based on the KHTML rendering engine, used in the Open Source Konqueror Browser/File Manager on Linux. I am working in Konqueror at the moment, and the page works fine and as expected. If you want to test compatibility with Safari, I recommend checking performance in Konqueror, which is generally comparable (Konqueror is usually a TINY step ahead of Safari, but this is negligible.)

    Thank you for the useful entry! It helps greatly in my looking for a solution to frames.

    Oh, and Rick, I disagree with Mr. Sherman somewhat, (Sorry!), about loading content into div’s. but I think that while possible, it requires some PHP. I’m looking into it myself at the moment. If you’re not familiar with PHP, though, it can’t be done to my knowledge.

  8. 8
    Tom Sherman (blog owner) Says:

    Daniel, you’re write. At the time I posted that comment I didn’t know about innerHTML :P

  9. 9
    Ejaz Asi Says:

    I wonder if we could have links in the static frames-like header return content in the content area without reloading the page?

  10. 10
    yukkk Says:

    kj

  11. 11
    yukkk Says:

    ,jnnnnnnttttttttttbrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr