The Cult of DIV2008-12-19

I believe that by definition, most people will consider themselves to be pragmatic -- that is, using the right tool for the job; rather than relying on dogma. And yet, an interesting phenomena occurs with web development: logic goes out the window, using tables for page layout is demonized, and people go to extraordinarily great lengths to use divs for page layout.

I've apparently fallen into the same trap myself: finding myself spending hours and hours, after each and every page redesign, trying to get archaic browsers with ~85%+ market penetration to work with divs, reading article after article on the subject. It finally dawned on me how wasteful this behavior was.

I'm not suggesting that tables are better than divs — far from it. In this article, I'd like to separate the fact from fiction, and show that div is not always the right tool for the job.

Divs versus tables — the basic arguments

"Divs reduce per-page sizes, saving bandwidth."

In today's web environment, where embedded streaming video is commonplace, this seems a rather silly argument. But let's compare ...

<div id="foo"></div>
<table id="foo"><tr><td></td></tr></table>

Twenty bytes versus fourty-two bytes. With background images consuming upwards of 100,000 bytes in some cases, surely there are more important things to worry about than an extra twenty-two bytes per page.

"Screen readers cannot parse tables as they can with divs."

Apparently, some unnamed screen reader software out there will read out the word "table" to users, whereas it will not with divs. Somehow software used by a fraction of one percent of web users is now the responsibility of all web developers to cater to? Why not correct the software, instead? If a webpage contains 80% or more of its content inside a single table, chances are its a layout table. If the table contains ids of "nav", "navigation" and "body", chances are its a layout table.

I'm sorry that we aren't all fortunate enough to have great vision in this world. But this is a problem to be addressed with the screen readers, not by eliminating tables. Tables aren't what's broken.

"Divs allow for easier maintenance through CSS."

Patently false. Just as divs can be manipulated and styled through CSS, so too can tables. Now again, this comes down to the right tool for the job. Divs will allow you to easily swap your navigation bar between the left and right, which can be considered a benefit in some cases. But that flexibility comes with a cost, which I will discuss shortly.

The usual argument about maintenance is that you don't have to go back and edit hundreds of HTML files by hand. I have to ask — what serious website edits all of their files through raw HTML directly? By that logic, you'd have to do the same anyway just to add a new entry to your navigation menu. Unless you use frames ... but let's not even go there right now.

Fact is, most serious webpages are generated through programming languages: PHP, ASP, etc. Changing the table layout is as simple as changing two lines of code in a script.

"Divs remove layout information from HTML files."

Sure, in an ideal world, this would be true. But due to limitations, you still end up adding extra divs for the sole purpose of page layout. Divs that are just as susceptible as tables to changes during site redesigns.

Take for instance, the venerable <div id="container">. Sound familiar? It's used by nearly all CSS layouts to constrain the widths of nested divs. A lot like <table> does for its child elements.

"Divs make more sense when examining source code."

Seriously, how many people look at source code to webpages? For those that do, how much harder is it to understand the word "table" than "div"? If you don't understand HTML, you shouldn't be looking at HTML source code.

Divs are not tables, tables are not divs

The most important point to consider is that tables and divs are different tools, each with their own semantics. They should be considered before a choice is made.

For divs, their main advantage is extreme flexibility on a per-element basis. That is, it is very easy to move a div around on the page: put it on the left, on the right, make it float, posiiton it to an absolute spot or make it relative to another, allow it to be displayed inline or not. But this flexibility comes at a cost: sizing information is not inherited from its parent element.

And this is the advantage of tables. Given multiple elements in a row, they all share the height of surrounding row entries, which is equal to the height of the parent row container. That's the basic idea we want when designing columns, and divs fail miserably at it.

Perhaps some examples will help ...

Two-columns with a border separator

Let's say we want to make two columns using divs, with a border between the two for style. Unfortunately, without the height being shared between the two divs, we run into problems when we try and add color to each div:

Content

Note how the nagivation background color extends beyond the content background color. The typical workaround to this is to add a container div, and make its color match the shorter div. This adds layout bloat information, the very things divs were supposed to eliminate in the first place. But even with that, there's still one major problem: how do we know which div will be smaller? On some pages, the nagivation menu may be longer; while on others, the content data may be longer.

Content
Content
Content
Content
Content
Content

Worse yet ... content wraps to the left once it extends past the shorter navigation div. To work around that, you have to float both divs, and use exact measurements for each div to get them aligned to each other. If you exceed the parent element's width by even one pixel with that approach (note that padding adds to width on properly programmed browsers, but not with IE6), the content div will wrap to the next line and appear on the left as well.

And take a look at that black border line. In my example, the border was specified through the nagivation div. So if navigation is longer, it goes past content. And if content is longer, it gets cut off too soon. The same is true in the reverse if content controls the border. And if we put the border command in both, then part of the div will get a double-thick line, while part will only have a single-thick line. Yuck.

Again, I must stress ... there is absolutely no way to get the two divs to share the same element height, short of client-side Javascript to dynamically manipulate element heights at page load (and Javascript has its own set of problems — many web users turn off Javascript on untrusted sites). height: 100%; has no effect. As they don't inherit height from the container div like tables, they assume they already are at 100% height.

Even more hacks — what about "faux columns"?

Faux columns are a trick where, instead of specifying the background color in the CSS script, we instead point to a background image. This background image would typically be a one-pixel-high image that contains the color for our navigation, border and part of the content. We'd then set the container div to repeat this image all the way down its div, because the container div will be of equal height to the tallest div.

But this approach quickly falls apart when you try and scale the webpage. Much more common than blindness (one of the main arguments against tables), is minor to moderate vision loss. There's also growing popularity in portable micro web browsers for handheld gaming systems, cell phones, netbooks, etc. Being able to resize pages cleanly seems pretty important. Yet when you use the background image, you either lock your navigation div to the size of the image, or you let your background color break completely. While a small number of browsers will also scale static images with text (causing blurring between background color boundaries), many more will not.

Even worse ... as if specifying layout information through CSS table properties was bad — now we're specifying layout information inside images!! We now need an image editor just to change our site layout.

And what of multi-browser support?

It's no secret: Internet Explorer 6 is the bane of all web developers. It is horribly, horribly broken when it comes to CSS and divs. There are literally thousands of pages out there devoted to using clever tricks to apply special CSS rules for certain browsers only. All of this comes at a real cost to ease of updating site themes. And with its vast market share, we cannot ignore it.

But when you look at tables ... that's something even the decrepit IE6 knows how to handle properly. They've been around since at least HTML3. Imagine being able to design a webpage, and knowing it will work on IE6 already. Imagine how much frustration that would save.

The same layout approach, but with tables instead

By definition, the table row paradigm is a perfect fit to our layout idea. For example:

Content

Content
Content
Content
Content
Content
Content

It no longer matters whether the navigation block or content block is taller ... they share height, so it is trivial to specify unique colors for both (using CSS rather than background images), and it no longer matters where we place our black spacing border. And best of all, this required no images, no browser-specific hacks, it scales to any size perfectly, and it works everywhere. Even the screwed-up div padding is fixed!

So ... we should always use tables for layout, then?

No!! Tables are not always appropriate. Let's take a look at an example where divs hold the upper hand in flexibility:

Content
Content
Content
Content
Content
Content

Here, tables fail miserably. They can't compete with the fluidity of divs. Although it is possible to hack up tables to represent the above; it's the same problem as hacking divs to create the two-column layout from earlier: it ends up very complex, and very hackish.

Again, all this article really boils down to is this: use the right tool for the job. Always keep your mind open, and use critical thinking. All too often, I see people blindly repeating the "gospel" they hear from others they admire: "gotos are evil", "tables are evil", etc etc.

It's depressing to me, because the people who most often repeat this vitriol against tables are some of the people I respect and admire the most: people who aren't afraid to think outside the box in all other areas. People motivated by success by any means. But when it comes to HTML and divs — all critical thinking is left at the front door, in favor of parroting the rants of others.

Believe me, I get the ideal behind divs. If they worked as people idealize them to, they would be truly amazing. But fantasy and reality are two different things: divs simply aren't appropriate for all layout approaches. They aren't flexible enough for that.