Internet Explorer 8 and the Totally New World of Cascading Style Sheets

All you rock-star cascading style sheet developers who can create insanely complex page layouts: look, I’m happy for you. Really. What you can do is cool. But this article is intended for the rest of us, those who still regularly feel the pain of trying to get those columns to line up correctly.

Internet Explorer 8 and cascading style sheets

Windows Internet Explorer 8 has vastly improved support for cascading style sheets. And that changes everything. Internet Explorer 8 offers full support for CSS2.1, which means the current version of every major web browser in the world now supports CSS2.1.

Let’s review

The point of cascading style sheets is to separate content from presentation. This is a good thing for a number of reasons, foremost of which is that most sites change content frequently, change presentation rarely, and almost never change both at the same time.

If content and presentation are heavily intertwined, adding new content to a site—and making the new content look like it’s part of the same site—can be a lot of work. Changing the theme of an entire site whose presentation is embedded in the content can be…challenging. Challenging enough to make you want to chuck the whole site and completely start over.

There’s an easier way

In properly decoupled sites—sites in which content and presentation are handled separately—content is defined by the HTML elements in the HTML pages, and presentation is defined in external style sheets. Adding new content is nearly as easy as adding plain text. Changing the site theme, instead of editing each page by hand, is as easy as updating the style sheet.

Tables

Remember the bad old days of the web, when your only structured layout choices were frames and tables? Yeah, we’re not even going to talk about frames.

Which pretty much just leaves tables.

About now, all of the semantic-web purists are screaming, “NOOOO!!!” and all of the pragmatists are saying, “Hey, all right!”

So, allow me to elaborate a bit.

Using an HTML table for layout is like using a car for an anchor; it works, but it’s wrong. For the purposes of this post, tables are just wrong for layout (unless what you’re laying out is a table).

But as wrong as they are, they’re about the only way to create an actual grid-based layout. And you can even make it scalable—what we cool web designers like to call a “liquid layout.”

So why are tables bad? Anyone who’s ever had to rework a table-based site already knows the answer to that.

For the rest of you, here’s an analogy. Imagine that you own a book. You’ve written your name on every page of the book (because, hey, it’s your book, right?). Now imagine that you want to sell the book. Just for fun, let’s say you’re selling it to a guy named Steve. The problem is that your name is not Steve. And Steve’s not too keen about having your name on every page of his book. At this point, you have two choices: You can either a.) throw the book away, get a new copy, and sell that to Steve—probably at a loss (start over with a new site design), or b.) erase your name from every page and write in Steve’s name (hand-edit every page).

That was really awful. All that site rework, I mean, not the analogy.

Just imagine, if you had had a magical book controlled by a cascading style sheet, you could have done all that work by changing just one page (probably in an appendix), and then that change would have automatically appeared throughout the book!

Hey, that wouldn’t so bad.

Cascading Style Sheet Layout Pain

So okay, cascading style sheets are great, but they’re hardly perfect. The thing about cascading style sheets up through CSS2.1 is that they mostly deal with content in chunks. Cascading style sheets are really good at taking content, bundling it into chunks, and then stacking the chunks.

And though cascading style sheets generally get the order of the chunks correct, where they sometimes stop making sense is when you try to get those chunks to show up where you want them to show up. (Unless you use absolute positioning for everything, but then your site doesn’t scale gracefully to different browser window dimensions—which you care about if you want people to able to view your sites on a phone or other mobile Internet device. And you do. Well, most of you do.)

Anyone who has ever struggled with columns knows exactly what I’m talking about.

The display: table Property to the Rescue!

Don’t get alarmed by the use of the word “table” in conjunction with layout. The CSS property we’re going to invoke is actually the display property.

Here’s your basic three-column layout with header and footer:

<!DOCTYPE html>
<html>
<head>
<title>Three Column - Fixed</title>
<meta content="text/html; charset=utf-8" http-equiv="content-type" />
<link href="three-column.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="wrapper">
 <div id="header">
  Header text</div>
 <div id="main">
  <div id="left_col">
   <p>scelerisque</p>
   <p>Tincidunt</p>
   <p>Sedeu purus</p>
   <p>Aenean orci</p>
   <p>Mauris sed</p>
   <p>In gravida</p>
   <p>Augue eget</p>
   <p>Cras porta</p>
   <p>Vestibulum</p>
   <p>Facilisis</p>
   <p>Justo in</p>
   <p>Gravida varius</p>
   <p>Quam metus</p>
   <p>Condimentum</p>
  </div>
  <div id="page_content">
   <p>Sed sodales hendrerit quam. Nunc congue tempor mi. Donec ut
   diam eu dui ultricies tristique. Mauris eros leo, consectetur a,
   bibendum id, dignissim at, mi. Maecenas luctus condimentum lacus.
   Praesent congue. Aliquam et nibh nec quam mollis tincidunt. Pellentesque
   fringilla convallis erat. Ut porttitor, velit sed facilisis aliquam,
   risus erat varius felis, ut laoreet mauris nisi in odio.</p>
   <p>Phasellus malesuada turpis et ante. Duis facilisis. Donec ultricies
   adipiscing quam. Praesent convallis elementum diam. Nulla urna.
   Vestibulum eu nunc. Ut lacinia nibh a magna consequat suscipit.
   Sed scelerisque tincidunt mauris. Sed eu purus. Aenean orci. Mauris
   sed dolor. In gravida augue eget neque. Cras porta. Vestibulum
   facilisis, justo in gravida varius, quam metus condimentum lorem,
   et varius odio nisl rhoncus neque.</p>
   <p>Pellentesque lobortis varius enim. Maecenas nulla est, lacinia
   at, bibendum ut, consequat sit amet, enim. Pellentesque sagittis
   enim nec lorem. Ut iaculis condimentum mi. Lorem ipsum dolor sit
   amet, consectetur adipiscing elit. Donec tempus tincidunt sem.
   Fusce condimentum. Ut ac ligula at velit ornare vestibulum. Sed
   sit amet leo sit amet massa faucibus aliquam.</p>
   <p>Nunc ac diam. Nunc elementum dui sed urna eleifend iaculis.
   Nam mattis euismod elit. Nullam ornare neque et eros. Praesent
   ipsum tortor, malesuada non, tincidunt sit amet, varius quis, quam.
   Suspendisse pretium. Praesent egestas, lorem ac sollicitudin adipiscing,
   erat velit tempor dui, ut viverra nisi ante eget lacus. Cras a
   mauris. In libero quam, tristique sed, accumsan ut, ullamcorper
   a, lorem. Curabitur feugiat feugiat augue. Cras rhoncus tellus
   at purus. Cras ac ligula eu justo faucibus placerat.</p>
   <p>Sed eget dui et urna rutrum pretium. Fusce dapibus mi eget nisl.
   Curabitur dictum nisl. Donec eget lacus et magna posuere varius.
   Nunc tristique diam et justo elementum iaculis. Duis purus. Maecenas
   luctus sem eu lacus. In vulputate cursus lectus.</p>
  </div>
  <div id="right_col">
   <p>Sed sodales hendrerit quam. Nunc congue tempor mi. Donec ut
   diam eu dui ultricies tristique.</p>
   <p>Mauris eros leo, consectetur a, bibendum id, dignissim at, mi.
   Maecenas luctus condimentum lacus.</p>
   <p>Praesent congue. Aliquam et nibh nec quam mollis tincidunt.
   Pellentesque fringilla convallis erat.</p>
   <p>Ut porttitor, velit sed facilisis aliquam, risus erat varius
   felis, ut laoreet mauris nisi in odio.</p>
   <p>Phasellus malesuada turpis et ante. Duis facilisis. Donec ultricies
   adipiscing quam.</p>
   <p>Praesent convallis elementum diam. Nulla urna. Vestibulum eu
   nunc.</p>
   <p>Ut lacinia nibh a magna consequat suscipit. Lobortis varius.
   Enim. Maecenas nulla est. Lacinia at. Bibendum ut.</p>
   <p>Consequat sit. Pellentesque enim nec lorem. Ut iaculis. Condimentum
   mi.</p>
   <p>Lorem ipsum. Dolor sit amet. Consectetur. Adipiscing elit. Donec
   tempus. Tincidunt sem. Fusce condimentum.</p>
   <p>Ut ac ligula at velit. Ornare vestibulum.</p>
  </div>
 </div>
 <div id="footer">
  Footer text</div>
</div>
</body>
</html>

For reasons already mentioned, we want a liquid layout, rather than fixed positioning. And we’d rather not have to rely on JavaScript. A typical cascading style sheet for a liquid layout would probably contain something like the following:
Yuck!

* {
  font: 10pt Tahoma, Verdana, sans-serif;
}
body {
  background-color: #E7E7D7;
  margin: 0;
  padding: 4px;
}
#wrapper {
  position: relative;
  text-align: left;
  width: 1024px;
  margin: 0 auto;
  background-color: #FFF;
  border: 1px #FFF solid;
}
#header, #footer {
  color: #FFF;
  background-color: #777767;
}
#header {
  height: 53px;
  font-size: 2em;
  border-bottom: 1px solid #EED;
  padding: 0.5em;
}
#left_col {
  background-color: #F0F0E0;
  width: 120px;
  border-right: 1px solid #EED;
  padding-right: 6px;
  float: left;
}
#right_col {
  margin-top: -30.1em; /* this value calculated */
  float: right;
  background-color: #EED;
  width: 190px;
  padding-left: 10px;
}
#page_content {
  margin: 0 200px;
}
#footer {
  clear: both;
  height: 38px;
  padding: 10px;
  font-size: 0.8em;
  border-top: 1px solid #EED;
  text-align: left;
}
p {
  margin: 0 2px;
  padding: 0 0 1em 0;
}

This works well enough, except in cases where we need different background colors or borders. Then things get kind of ugly. The problem, of course, is that each column is only as tall as the content it contains; we make all three of them look the same height by using float for the columns and clear for the footer. However, using background colors or borders reveals the column height differences in painfully embarrassing ways.

If we use the display: table property instead of float and clear, the cascading style sheet would look like the following:
Much Better!

* {
	font: 10pt Tahoma, Verdana, sans-serif;
	background-color: #BBB;
}
body {
	background-color: #E7E7D7;
	margin: 0;
	padding: 4px;
}
#wrapper {
	position: relative;
	text-align: left;
	width: 800px;
	margin-right: auto;
	margin-left: auto;
	border-left: 1px solid #CCB;
	border-right: 1px solid #CCB;
}
#header, footer {
	color: #FFF;
	background-color: #777767;
}
#footer, p {
 font-size: 0.8em;
}
#header {
	font-size: 2em;
	height: 53px;
	border-bottom: 1px solid #EED;
	padding: 0.5em;
}
#main {
	display: table;
	border-collapse: collapse;
}
#left_col, #right_col, #page_content {
	display: table-cell;
}
#left_col, #left_col * {
	background-color: #F0F0E0;
}
#left_col {
	border-right: 1px solid #EED;
	padding-right: 6px;
	width: 120px;
}
#right_col, #right_col * {
	background-color: #EED;
}
#right_col, #page_content {
	padding-left: 10px;
}
#right_col {
	width: 190px;
}
#page_content {
	padding-right: 10px;
	border: 2px #CCB solid;
	background-color:#FFF;
}
p {
	padding: 6px;
}
#footer {
	height: 38px;
	padding: 10px;
	border-top: 1px solid #EED;
	text-align: left;
}
p {
	margin: 0;
	padding: 1px 6px;
}

The difference when the page is displayed is that each of the three columns is actually the same height. This becomes even more apparent when you add background colors or borders.

How Is That Different from Using HTML Tables?

First and foremost, display: table is not an HTML tag, it’s a CSS display property. If you have qualms, remember that you’re not creating an actual table; you’re just applying a style.

Where HTML table elements imply semantic meaning (and take too long to load, more or less throw accessibility out the window, and do very unpleasant things to search engine optimization), all we’re doing here is applying cascading style sheet rules to semantically correct HTML div elements.

It still feels like a hack

This is not a hack. There’s no reason to feel guilty about applying display: inline to create a horizontal menu from an unordered list. You’re not changing the semantic content of the list (it’s a navigation list, after all), you’re just changing its presentation.

It seems like I remember reading somewhere that the whole point of cascading style sheets was to separate content from presentation. Now, where would I have seen that?

Oh yeah. Everywhere.

Reasonably Graceful Degradation for Older Browsers

Don’t try this in Internet Explorer 7; you’ll only break your heart. Internet Explorer 7 and Internet Explorer 6 don’t support the display: table property, so the page renders… badly. Don’t believe me? try it for yourself. Go ahead, I’ll wait.

The good news is that we can fall back on the (admittedly) imperfect float/clear method for Internet Explorer 6 and Internet Explorer 7 by adding the following conditional statement:

<!--[if lt IE 8]>
  <link rel="stylesheet" type="text/css" href="3c_float.css" />
<![endif]-->

Be sure to add this after the primary style sheet declaration so that the style rules in 3c_float.css take precedence. And you should really avoid having any in-page style rules. (But if you’re this far along into cascading style sheets, you’ve probably already learned that lesson.)

3c_float.css needs to contain replacement styles only for those that use the display: table and display: table-cell properties. If you want to save some time, use the style rules from the first cascading style sheet example above. We’ve already tested them, after all.

So, for not very much effort (certainly less than getting floating columns to work), you can have perfect multi-column pages in Internet Explorer 8. And when your site is viewed in Internet Explorer 6 or Internet Explorer 7 (or Internet Explorer 8 in forced compatibility mode), it will render using the old tried-and-true faux-column display using float and clear.

<?php echo get_option('blogname'); ?> - Comments on <?php the_title(); ?>

3 Responses to “Internet Explorer 8 and the Totally New World of Cascading Style Sheets”

  1. [...] Permanent Link to Internet Explorer 8 and the Totally New World of Cascading Style Sheets [...]

  2. Münevver AYDEMİR says:

    Hello
    Firstly, I want to thanks to writte wonderful information to us. I make an effort to blend.
    I’m Computer Education Student at Metu in Turkey. I have problem with Expression Blend. I can’t add a picture my workspace. I use windows 7. Can you help me what can I do?
    Thanks

  3. Your article really struck a chord with me, so thanks for taking the time to write it.

    I still do the odd layout styling using tables. Yes, like you I know its wrong, but despite all my technical abilities (5 years as a c#/sql developer), css is still as much a headache now as it was when I started. I try to do as much as possible in css, but always end up spending more time trying to get frickin panels lining up than I do coding the rest of the website. And then, only to find it doesn’t line up in chrome, or firefox 3.6 or IE7 or … etc. I know CSS is the way to go but still do the odd bit of layout cheating.

Leave a Reply