I'm done with feeling guilty about using HTML tables for layout

August 30, 2013

Just over six years ago I wrote that using CSS instead of tables was a hack. As far as I can tell nothing has fundamentally changed since then; using CSS to create flexible, powerful column and row based layouts is still awkward and a hack. The promised high level CSS layout support is not particularly closer to materializing in real browsers now than it was then.

(One difference is that you can apparently now fake it with JavaScript, just in case you would like to have two baroque hacks instead of one.)

I don't know about anyone else, but I've spent a certain amount of the last six years feeling vaguely guilty when I periodically resorted to using tables for column-based layouts. As of now, I'm done with that. Until CSS gets its act together (if ever) tables are going to be my first and guilt-free choice for any grid-based things I need, all the way from just lining up form labels and form fields to full-page layout. And if the tables need additional styling I'm going to add bits of CSS without even thinking twice.

Ultimately what it comes down to is simple: HTML tables make it easier to create grid-like layouts and they work better than at least basic CSS. Letting the ghostly voice of CSS get to me about this is stupid and counterproductive (in that it pushes me away from better, more usable designs).

(As a side note, I'm not at all interested in recreating <table>, <tr>, <td> and so on in suitably marked up <div> and <span> entries plus CSS. I already have the table HTML tags and they work fine. Carefully redoing them in CSS just so that I can say I'm using <div> instead of <table> strikes me as the height of something under almost all circumstances.)

Sidebar: why the 'obvious' CSS solutions are not suitable

It's relatively easy to construct a CSS-based grid layout if you force specific column and/or row sizes (in points, pixels, em, or your absolute unit of choice). I refuse to do that for two reasons. First, because forced sizing has various bad side effects. My absolute requirement for a grid-based layout is that the grid spacing flexes in and out based on the browser size. Second, absolute sizing is a pain in the rear to specify out and to test. The advantage of a flexible grid is that I don't need to worry about more than a bit of this.

(The lack of worry is especially acute when I have very simple design rules like 'split the space in half' or 'just line up the left edge of all of these things'.)

Comments on this page:

Try just adding role="presentation" on the <table> element.

We have a genuine pragmatic effort to bridge us to the semantic-laden promised land and its name is ARIA. It helps people with disabilities. Bad accessibility is surely the biggest sin of non-data tables. I don't guarantee this will make users happy, but it looks good as a guilt-avoidance mechanism :p.

Maybe it was a good idea implementing layout:table for free, and seeing if it fixed the problems. But the answer is that it doesn't.

You don’t have to use <div> and <span> as hooks for display: table and friends – I often it’s not hard to hang them onto my existing semantic elements, or, at worst, to rearrange them just slightly to allow for that.

However, you cannot specify column and row spans in CSS – so if you need to do anything even remotely irregular in a CSS-based tabular layout, you’re out of luck.

Anyway, a major motivation for CSS was that tables effectively describe the materialised layout – as part of the content. So you have to send tons of materialised layout description markup down the wire every time you serve a page, and rearranging your layout means rearranging the landfill you buried your content inside of. Thus the impetus for separating presentation from content.

You really don’t want to go back to those bad old days – not because using CSS is somehow virtuous, but because using tables for layout is pragmatically horrible.

Unfortunately the only alternative to materialised inline description of layout that we got was constraint-based out-of-band description – there is no out-of-band option for a materialised description.

So by and large the most pragmatic approach is probably to use a very simple table or two to set up a coarse structure for the page and then use CSS to arrange things within that.

Unfortunately we’re in an era with a huge range of display sizes, so for some designs even that isn’t an option any more. (Cf. the responsive buzzword et al.)

By cks at 2013-09-03 13:06:08:

To make sure I understand this: the issue with 'materialized layout' is that one is sending extra HTML down the wire for every page (all of the <table> and <tr> and <td> tags that exist to wrap existing content), instead of sending the equivalent in CSS once as an external stylesheet? I assume that this only applies if you already have <div>s and <span>s and so on around all of the extra elements; otherwise it's mostly a toss up between <div> and table elements.

(Possibly the raw byte count actually comes out in favour of <table>, because the <div>s et al would have to be annotated so CSS can select them.)

My only real experience with table-based layout is in the context of auto-generated HTML (primarily in DWiki's templates and so on). In that context I've never had a problem with my content getting lost in tables; while there can be a number of nested ones, each level is generated separately and has been simple to shuffle around and redo. I can easily imagine that writing and recreating a multi-level table layout by hand would be a really bad experience.

Presumably your programming projects are also (effectively, in practice – if not absolutely nor in intent) single-developer, no-designer projects without a real style guide or something of the sort, where you just place elements onto pages ad-hoc as you go. In that case you can get away far more easily with a “just change the markup” process in which markup and corresponding CSS always go hand in hand.

I work on a modestly large application and yet the number of its templates is in the triple digits, with almost all of them containing at least some amount of display logic. We also have two designers working on it aside from myself as the developer, and the whole thing needs to follow a coherent visual language. It’s not possible to keep the process sane and the effort of making changes reasonable if we were to rely on tables to almost any extent.

The power of CSS is that you get to rearrange things without rearranging the markup for them. That is a power you get to retain even if you “just” use <div>s styled as tables, and which you deny yourself by using actual <table>s. (Well, actually, you don’t deny it yourself, but you make it much harder on yourself than it would be otherwise (unless you are using XHTML, irony of ironies, because then you do not get magic auto-inserted tags in your DOM), and the meaning of the markup becomes much more perverted.)

(Note that before CSS there wasn’t really any way to do what margin and padding (et al) do, other than to use nested tables with cell spacing and cell padding and spacer GIFs. So people were using a lot of nested tables, even for the simplest designs. (That is what I mean when I say materialised layout.) Even a “mere” transcription from <table> to <div> nowadays never means using markup the way it was used in those old days, so it isn’t really “just” doing faux tables via CSS.)

In my project we need that power in order to all be able to work in parallel without having to sit in the same room with our brains hooked up to each other and yet retain some semblance of development velocity.

I guess I didn’t adequately account for your different circumstances, though. If you really can make tables work for you – more power to you. (But do consider the trajectory of your project, because I can tell you from painful experience: once one template using bad practice has spawned a hundred others (accreted one by one, of course), it will take a painful long time to change course. And the longer you keep putting off that slog, the more new templates you will accrete which further perpetuate the problem.)

By San at 2016-09-08 15:14:43:

I know this is an old post, but it seems like CSS now supports (across all major browsers anyway) the exact thing you want for this: CSS Flexible Boxes.


Written on 30 August 2013.
« A new piece of my environment: clearing the X selection
HTML quoting as I currently understand it »

Page tools: View Source, View Normal, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Fri Aug 30 00:30:05 2013
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.