Mobile version (Display Regular Site)

Skip to: Navigation | Content | Sidebar | Footer

Weblog Entry

Too Far

March 31, 2005

You know the dogma has gone too far when…

Here’s a code sample from someone who obviously misunderstands the fact that “it’s okay to use tables for tabular data”, and probably spent more time than was necessary coming up with the CSS to make this work:

<h3>My Schedule</h3>
<ul class="pseudotable">
     <span class="event">Event #1</span>
     <span class="location">(location)>/span>
     <strong>May 15, 2005</strong>
     <span class="event">Event #2</span>
     <span class="location">(location)</span>
     <strong>May 16, 2005</strong>

Too bad that someone was me. The CSS that made this work ended up looking like this:

.pseudotable li {
  padding-left: 66%;
  position: relative;
.pseudotable strong {
  width: 33%;
  display: block;
.pseudotable .event {
  display: block;
  width: 29%;
  position: absolute;
  left: 0;
.pseudotable .location {
  display: block;
  width: 53px;
  position: absolute;
  left: 33%;

A misguided waste of time, for sure. You’d think the class name “pseudotable” should have tipped me off that maybe I was going about it the wrong way… and I coded this only last month, too. Here’s the much more sane data table I ended up with:

<h3>My Schedule</h3>
<table cellspacing="0">
     <td class="event">Event #1</td>
     <td class="location">(location)</td>
     <td><strong>May 15, 2005</strong></td>
     <td class="event">Event #2</td>
     <td class="location">(location)</td>
     <td><strong>May 16, 2005</strong></td>

About the same weight, markup-wise, but compare the resulting CSS:

table {
  border: none;
td {
  width: 33%;
td.location {
  width: 53px;

That’s a few hours of my life I’ll never see back. Gosh.

Update: as a few commenters have rightly pointed out, there’s more that can and should be done with a data table like this one. You could go as far as something like the following if you’re so inclined:

<h3>My Schedule</h3>
<table cellspacing="0" summary="Upcoming Events, their locations, and dates.">
     <th scope="col" class="event">Events</td>
     <th scope="col" class="location">Locations</td>
     <th scope="col" class="event">Dates</td>
     <td class="event">Event #1</td>
     <td class="location">(location)</td>
     <td><strong>May 15, 2005</strong></td>
     <td class="event">Event #2</td>
     <td class="location">(location)</td>
     <td><strong>May 16, 2005</strong></td>

And there are even more elements and attributes to explore, like col, colgroup, and caption.

March 31, 01h


CSS even saved my marriage! And I don’t even have a wife :D

March 31, 01h

Good thoughts.

Yeah, it’s definitely right to use a table when appropriate. And it’s always important to be on the lookout for unforeseen advantages to a particular approach.

For example (sorry to css-d folks who’ve already seen this), even though a calendar is best done with a table, when you use a list, you get a neat rollover property for free:

March 31, 01h

This reminds me of the hCalendar microformat ( ) , which seems to use very similar HTML to your first ‘pseuodtable’ example.

March 31, 01h

At least you didn’t waste as much time as I did…

Hey, we learn from our mistakes, right? :)

March 31, 01h

I appreciate your transparency. Helps make for an environment where people can share their blunders (all of mine are on my web site now filed under ‘achievements’) :-P

Kevin Tamura says:
March 31, 01h

Ouch. I’ve done the same thing too.

Chris says:
March 31, 01h

“Important write-up.”

no it’s not. People confuse CSS and tables so much it is just sad.

luke says:
March 31, 01h

Not that it’s a major issue but you could use css’s:

border-spacing: 0;

instead of html’s


Dave S. says:
March 31, 02h

“Not that it’s a major issue but you could use css’s: border-spacing: 0; instead of html’s cellpadding=”0””

I was wondering if that would come up. You can, but you probably shouldn’t yet.

Key words: Not supported by IE.

March 31, 02h

Not to slight Mike Purvis, but I did manage to take his example and translate it over to a table-based layout for the calendar and still have the mouseover divs show as they did for the ordered-list.

Naturally, it’s not AS clean as using the list, but it still works in very much the same manner as the example (a rewrite on the javascript used by IE was required to properly access the TD elements).

Zelnox says:
March 31, 02h

Strangely, I probably would have tried with lists…

March 31, 02h

Charles Martin: The advantage of the list (with the rollovers) is that on a non-css agent, it unravels into a clean agenda. Whereas the table has huge blobs of text in the cells, so it would be unusable on a phone… Also, the list-based calendar would lend itself better to a style-switcher for different formats, if you’re into that.

But yeah, the table<->css issue is not always as clear-cut as it looks.

Ben Ward says:
March 31, 02h

I did the exact same thing a year or so back. I was using a PHPNuke CMS and building my own CSS-layout theme for it. I was very much in the “tables are the devil” mindset that you describe and while I was very pleased with having torn apart PHPNuke’s default table layout, half a dozen pages listing tabular summaries were suddenly in lists…

Worse still, each “column” in my list had a blatent separator (paranthesese, square brakets, a hypen or two, maybe a colon). About a week or two later I looked at it, saw how silly it was and went to much effort to swap it back.

I think this is the kind of lesson that comes to all of us who live standards. Maybe it’s important to vary the kinds of bleeding edge techniques we use (tableless layout was once that, of course). I’m convinced that spending so much time working only to destroy <table/>s gave me some kind of CSS tunnel vision.

This same kind of “whoops, too far” could so easily happen with the newly beloved ‘creative license’ we have for definition lists too. I’ve sat with a colleague at work working out the XHTML structure for his Blog’s sidebar and we’ve watched the slow trainwreck of slowly but surely transforming the entire navigation structure into a nest of <dl/>s. We paused for a moment to survey the wreckage.
“Nah”, we said.

March 31, 03h

Mike, very good point. I very rarely consider a non-CSS view of the page and it does degrade quite nicely. Hrm… now I’m considering this format more than the table just for that reason. I just wanted to see if there was some specific advantage visually and functionally between them. Not really, but your version is much better from a style-less perspective. Much to learn, much to learn.

trovster says:
March 31, 04h

Hmm, that information looks more like a definition list? - with more information such as “date” in the definition title, which could be hidden in the CSS. However, this adds a lot more unrequired content. But, surely if it’s tabular data it should have table headers? That span the columns?

Paul D says:
March 31, 04h

Am I the only one who can never get table styles to look the same in every browser? I usually prefer to lay tabular data out with spans and CSS in spite of the extra styles required. At least I’m in control that way, instead of the mysterious workings of <td> borders and spacing.

Oliver says:
March 31, 04h

I still see nothing wrong with tables, even for normal page layouts, etc. Of course, I see that all that slicing in Imageready and stuff cannot be made worse, but normal “header, content, sidebar, footer” cells don’t hurt at all.

beto says:
March 31, 04h

I falled prey once to designing a calendar using HTML lists and CSS to mimic a table-like layout. It wasn’t until I finished it that I realized the whole absurdity of it all.

Same can be said for data organized in a tabular way - there’s no use in reinventing the wheel. That’s what HTML tables are for.

Rest assured, lesson learned.

March 31, 06h

Although the structure still looks a little bare for a data table.

Your little problem reminded me of a web app that my company payed for. The programmers who developed it utilized about 200 different stylesheets and didn’t use one table for any data. My buddy is pulling his hair trying to even attempt adjustments to it. I feel for him, he got handed crap.

You know after reading 3 books on Accessibility, I think the misunderstanding out there is that you can’t use tables at all, no matter if it’s for data or layout.

This simply isn’t true. Sure pure CSS layouts help to alieviate some of the “Functional and Situational Limitations” addressed in Accessibility and help bring a finer separation to presentation and structure, but it is also not the end all answer. Tables are still ok, as long as they are done CORRECTLY, making sure Layout tables linearize correctly for semantics and document understandability or that Data tables are marked up correctly so that data still makes sense and is associated with the correct headers when read or displayed linearly. But in the end of course it truly depends on who your target audience is and on what types of devices you want them to be able to access your site on. This is where pure CSS layouts have an advantage/but still some disadvantage.

Of course that leads to another problem, Usability. Sure you can design 1 site to be viewable on a 21 inch monitor as well as a 5 inch PDA, but is it usable? Most likely not, all that data and info being squeezed into a smaller, less viewable screen is sure to bring about many usability and accessibility problems (refer back to “Situational Limitations”).

March 31, 10h

I like this post. It’s time for the CSS zealotry to ease up, for the web standards folks to take a collective deep breath, and for everyone to consider what the right code for the job is rather than what the “fashionable” approach is.

March 31, 12h

Dave, I’m sure no one would hold that against you. I once remodeled an entire kitchen using nothing but CSS. It looked great, but there are easier/more appropriate ways.

AkaXakA says:
March 31, 12h

Important write-up.

I guess the ‘web-standards-drive’ shouldn’t have used the phrase “table-less” but something like “inline-style-less” or “minimal-styling”. As you also have people putting all their style inline - all the time - and then proclame with a straight face that they “get” webstandards. Oh well.

But don’t worry Dave, this code doesn’t mean your already gone dement, think of it as a “senior-moment”. (Quick Canadian old folks joke my 2nd cousin twice removed told me)

seth says:
March 31, 12h

My addictive personality has gotten me into similiar crunches. Lately, I’ve been working a 12-step program to break my intense desire to use CSS for everything.

Jim Amos says:
March 31, 12h

What is this, CSS Confessional? ;)

March 31, 12h

We all have our moments when we get a little carried away. Sometimes we just need to get back to the basics. :)

March 31, 12h

Chalk that up to practice, not that you need practice…how about, if you can do it, you might as well.

March 31, 12h

<sigh> Idiot!

(no, not a slight towards Dave… just think based on that last line in his post that he’d just recently seen “Napoleon Dynamite”)

Anne says:
April 01, 02h

Isn’t “event” the header of the row? Isn’t the STRONG element presentational this way?

April 01, 03h

After having done the entire CSS for the Symphony UI, I’ve learnt a thing or two about tables and CSS (doing them the semantic/accessible thead, tfoot, tbody way of course). You might find it helpful to know that you can get rid of that ugly cellspacing attribute and instead use:

table { border-collapse: collapse; }

Keep the markup free from stylistic information, since that’s our whole purpose with using CSS right?

April 01, 03h

By the way, the technique I mentioned above does work in IE6 and IE5.x, as it’s the intended way CSS handles this situation. I think.

dusoft says:
April 01, 04h

I used similar thing once - h3 and span as two column table.

April 01, 04h

Why didn’t you try the display: table-*; properties? They work in everything by IE, so it would have at least reduced your CSS. However, you’re right the whole attempt was a waste of time.

It’s really just the opposite of mixing the presentation layer with the structure and semantics layer. The semantics belongs with the structure, not with the presentation where you tried to put it.

Unimportant says:
April 01, 05h

Tables as well as lists are presentational elements. Yes, I am serious about this. But what drives my sick and twisted mind to such a statement?

Well, it´s pretty easy. When you think of a list, you always imagine one column with an arbitrary amount of rows. Of course you can use CSS to position every item differently and way out of context but in the end, a list is a bunch of rows. Nothing more, nothing less.

What about tables? If you take a look at them, they are nothing else but a bunch of side-by-side lists. You could also say they are two-dimensional lists because the semantics apply to both axis, although the meaning is different for each case.

Now what if we had an element called “set”? Or “enum”? Or “collection”? All of those have no dimensional limitation implied nor are they strictly associated to a specific presentation. Every set or enum or collection could contain an arbitrary amount of subsets or sub-enums or sub-collections.

Now you might ask: But what about the semantics? Well, you don´t gain any but you don´t lose any either. A table row is a row and no machine is able to tell you what the data actually means. Same applies for table headers or footers. A parser will know which head and foot belong to which column, but they still cannot tell anything about the actual meaning. So be free to add a header to a set or maybe a set description and you have the same possibilities without the separation into different elements. If you still aren´t convinced, ask yourself following question: Why don´t I simply define a one-column-table instead of a list?

So what am I trying to say anyway? Don´t use list and tables? But what to use instead of?

Well, nothing. Keep it as it is. Why? Because there is no alternative. The whole point is to explain why I think that there is a huge gap and misconseption in (X)HTML about sets and collections as well as the public understanding of presentation. Further, I have no idea how one could present a four-dimensional set and above, but this still doesn’t mean I cannot define one. Just think about arrays in programing languages.

April 01, 06h

For a while I searched for a way to present forms without tables, lining up labels and inputs with all kinds of floats and spans. Then I had a Dave “what the heck am I doing” moment, kicked my own butt, and went back to using 2 column tables for forms.

Since then I’ve lost 35 pounds, my salary doubled to 700k per annum and and beautiful women throw themselves at me constantly.

See, tables aren’t so bad in the right context. I have to go now, I’m in the middle of a bike race.

(I bet nobody gets that.)

April 01, 07h

To all those people above saying things like “I usually prefer to lay tabular data out with spans and CSS”: TABLES ARE FOR TABULAR DATA. That’s why it’s called tabular! Semantics, accessibility, etc, etc.

And I’m sure you meant to close those <th> elements in your example with </th> and not </td>.

juan carlos says:
April 01, 07h

For accessibility why don’t you consider the following:

- summary attribute on table
- a thead tag with a row of th’s (you can hide this from visual browsers if you need to by moving it off the screen with CSS, so screen readers can still read it out)
- stick some scope’s in the th’s of scope=”col” and for those events, make that first td have a scope of row.

That way your table will be semantically more useful. I think jaws will soon be supporting some of this. Even if it doesn’t, it is all about future compatibility, right?

If you and other prominent people don’t do it, no one will, and screen readers won’t support it…!

April 01, 08h

Hey I’m surprised the CSS nazi’s didn’t get you for that one!

I like your openness - a lot of people would’ve just swept that under the carpet.

Following your example we should all ask ourselves daily:

“Does the way I am coding this provide a real benefit or am I doing it this way just because I can”.

Trouble is developers get bored easily and we do stuff for the challenge sometimes, even if it provides little towards the real goals of the project!

rdude says:
April 01, 09h

I am one of the CSS Nazi’s that Stuart mentioned.

Don’t worry Dave, we are definitely coming to get you…

April 01, 09h

Ahh Dave, no April Fools fun? Sure you could throw something together and surpise us all?

Very fun.

Clayton Scott says:
April 01, 10h

Semantically speaking your <H3> should really be the <caption> for the table
and then styled with CSS to your hearts every desire.


<table cellspacing=”0”>
<caption>My Schedule</caption>
<td class=”event”>Event #1</td>
<td class=”location”>(location)</td>
<td><strong>May 15, 2005</strong></td>
<td class=”event”>Event #2</td>
<td class=”location”>(location)</td>
<td><strong>May 16, 2005</strong></td>

Would you also not want to assign a class to the cell that have dates that you are <strong>ing? It just seems strange that you have Event,Location and strong.

April 01, 12h

Regarding the border-spacing thing,

Is border-spacing: 0px; not equivalent to border-collapse: collapse;, which DOES work in IE?

April 01, 12h

*upon actually looking at the spec* Okay, not totally equivalent, but almost certainly acceptable?

April 02, 05h

BTW, for the people going schizo about the cellspacing attribute… when was the last time you made a table with cellspacing != 0?

Oh, ok. So if all your tables have cellspacing=0, and attribute is kosher even under the latest and greatest XHTML doctype (with whipped on top!), then no big deal, eh?

Ryan Barr says:
April 03, 12h

Dave, I am a big believer of not using tables.. why must you use them? They are awfully dreadful in the first place and they tend to screw everything up.

Sorry for the loss of useful hours, I find myself coding many things just to later see the delete button being clicked.

Alistair says:
April 03, 12h

Curious Dave, what exactly made you think that a list was the solution initially? Was it just that you didn’t ‘think’ at the time or was there actually a ‘reason’ why you walked the list path instead of the table one?

Sam Ghods says:
April 04, 03h

Re Tom’s
“For a while I searched for a way to present forms without tables, lining up labels and inputs with all kinds of floats and spans. Then I had a Dave “what the heck am I doing” moment, kicked my own butt, and went back to using 2 column tables for forms.”

Forms are not tabular data, thus should not be written as tables. Very nice, functional, valid forms can be designed with simple, straightforward CSS. Example: (scroll down to “FORM(s) and Function”).

April 04, 06h


That ALA article is terribly outdated.

<div class=”spacer”>

I think putting putting forms in tables is much better then that example.

April 04, 12h

Sam Ghods:

Check out Cameron Adams’ form styling wizardry:

No tables there, and he demonstrates the advantages of it.

Aegir says:
April 05, 06h

One day CSS will have typographic grids, so that we can again have layouts up to the creative standards we had with tables.

I’m not saying tables were a good thing for layout, but the grid structure they provided *was*. I’ve read so many hacks and workarounds to get CSS and semantic markup to produce layouts that would be simple if an underlying grid was available. Setting guidelines and grid-points in a stylesheet would be straightforward and should help free us from the hell of float-itis.

All we need is CSS 6

April 05, 07h

Most bizarre example of table aversion I’ve come across was my online phone-bill [a certain UK cellphone company].

Hundreds of lines of data, [time, date, duration, cost etc for each call] all of it tabular, all of it assembled to look like a table with CSS [divs, spans and the weirdest class names]. Unreadable if you changed the font size even slightly.

Apart from that, a real tour de force.

April 06, 12h

Interesting issue, of course - nowadays some people think that tables must never be used. Together with the “divitis” and “spanitis” (whatever) phenomena, this is one of the new problems we face.

April 08, 08h

One other thing I want to throw into this debate is the situation where you want an entire row of a table to be clickable. This can be accomplished with a splash of Javascript, of course, but sometimes a list can be an elegant solution.

The issue becomes even more muddled when you start dealing with a table that has only two columns, since that’s starting into definition-list territory. I have an example that I started out doing with a table, and then ultimately switched to a list, for the sake of row-highlight and row-clickability.