3 column CSS layout with “display-table”, semi-hack to load content first for SEO

by Peter

The new “display: table” syntax in CSS 2.1 opens for new simple layout techniques for otherwise complex designs, such as the fixed-strechable-fixed layout that many seem to want, and makes it easy to get columns of equal height. A few simple lines of code is all it takes – no faux columns, no huge bottom paddings and negative margins, or other sophisticated CSS design exercises and tricks.

This is a CSS layout any beginner can create, just as the table designs of the old days. And it is very robust and scalable. So my guess is that it will become very, very popular. Here is all it takes (non-essential rules omitted). First the CSS:

1
2
3
4
5
6
7
8
9
body  { font-size: 100%; text-align:center;  }
#wrapper  { width: 500px; margin: 40px auto;  }
#main {display: table-row;  }
#side-left,#content,#side-right {display: table-cell;}
#header  { background: gold; height: 100px;  }
#footer  { background: gold; height: 100px; clear:both;   }
#content {  background: blue;
width: 300px; }
#side-left, #side-right  { background:yellow; width: 100px;  }

And here is the essential markup (load order of elements given by the numbering):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div id="wrapper">
<div id="header">
<h1>1.</h1>
</div>
<div id="main">
<div id="side-left">
<h1>2.</h1>
</div>
<div id="content">
<h1>3.</h1>
</div>
<div id="side-right">
<h1>4.</h1>
</div>
</div>
<!-- main -->
<div id="footer">
<h1>5.</h1>
Nekkidblogger CSS-fun
(c) Nekkidblogger (2010)</div>
</div>
<!-- Wrapper -->

This produces the layout in the figure below. (Here is the web page, with source code, including some fixes.)

3coldisplaytable

There are two problems with this. The first is that IE 7 and earlier does not support the “display: table” and similar CSS (display:table-row, display:table-cell). However, this can easily be dealt with, and I have included the necessary conditional style to IE lte 7 browsers in the source code for the figure.

The second is a SEO concern. Many authors, such as Rachel Andrew and Kevin Yank in “Everything you know about CSS is wrong!” and others on the internet, express some concern about the fact that it is impossible to load content first unless the content is in the first column. That is, the content loads in the order indicated by the numbers in the image above. The reason is that as the current implementation of the new CSS syntax does not support “rowspan” and “colspan”, “table hacks” like the one I wrote about in a previous article can not be implemented.

And this seems to be very true. I have tried to twist and bend the order of the columns a lot without result. There are no true hacks, as far as I can see. But there is a way to “hack it” even so. If you really want the content (the middle column) to load first for SEO (Search Engine Optimization) reasons, it can be done. But not by a hack, more something like a “semi-hack” (see also G. Sørtun’s method, based on relative repositioning, which is very nice but has some severe limitations):

First we place a container behind the three main columns and make it relatively positioned. Then we use a new div that we load (in the markup) after the three columns and that overwrites the original left column. The purpose of the extra container is to easily and precisely position the new column absolutely.

What this means, is that you do not load content in the original left sidebar, but leave it without content. Instead you load the sidebar content into the new absolutely positioned column. Doing this, you have, in effect, made your content in the middle sidebar load first. In the table hack (see above) we similarly fill the first cell only with the spacer.gif – and leave it empty of content – so there is a clear similarity.

Here is the new CSS for a new container and the new column:

1
2
3
#contain { position: relative; }
#side-left2  { background:red; position:absolute; overflow:hidden;
top: 0; left: 0; height:100%; width: 100px;   }

And the new markup (I have also re-numbered the footer)(essential rules only), still short and sweet:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<div id="wrapper">
<div id="header">
<h1>1.</h1>
</div>
<div id="contain">
<div id="main">
<div id="side-left">
<h1>2.</h1>
</div>
<div id="content">
<h1>3.</h1>
</div>
<div id="side-right">
<h1>4.</h1>
</div>
<div id="side-left2">
<h1>5.</h1>
Sidebar left content
(navbar) goes here!</div>
</div>
<!-- main --></div>
<!-- contain -->
<div id="footer">
<h1>6.</h1>
Nekkidblogger CSS-fun
(c) Nekkidblogger (2010)</div>
</div>

The result is shown in the image below (also, see demo here, with all the CSS in the source):

3coldisplaytable-b

As you can see, the (red) new sidebar column numbered 5 – meaning it is the fifth element in the markup, has now overwritten the old (yellow) left sidebar. This means that the content column (element 3) now load before the sidebars with whatever SEO benefit this brings. This is all valid CSS and markup, and I have tested it in a number of browsers (see the demo).

Also, I have written the code so that it degrades into a table (with the semi-hack still working) for IE7 and earlier IE versions. And it is easy to turn it into a flexible width design with fixed sidebars (just set the width to a percentage or em’s, and the width of the middle column to 100% or em’s, and use “min-width” and “max-width” if desirable).

The design has some well known weaknesses due to the absolute positioning of the new left sidebar that I outline and discuss how to deal with in the demo file. Also, since this ends up as a hybrid design it has some of the advantages of the “display: table” layout, but not all, and may perhaps be viewed as involving a trade-off between the ease of use of the new CSS table design and SEO concerns. To keep it simple I have used the semi-hack here on a fixed layout, but it only really makes sense to use it on hybrid CSS layouts, as fixed CSS layouts are relatively straightforward.

Related Posts:

Leave a Comment