Styling tables (part I)

Example table design

Funnily enough, a lot of people ask me if I hate tables. The answer to that is no, I do not :) I rather dislike the use of tables for tabular layout—it is an unsemantic and, in the long run, limiting way of doing things. However, that is an entirely different argument :) Let’s just assume I do like tables (for tabular data) and I’m going to go over today how to make them look a little less … ugly, and a little more aesthetically appealing.

So, to begin, we should decide exactly what is a semantic, well-structured table. I like to start with the row along the top, that which defines what the table is:

<table summary="This table defines all the events that are in progress throughout February 2007">
    <caption>Events for February 2007</caption>

    …

</table>

Don’t forget to use clear definitions as to what the table is for. Second step: to define the breadth of our columns (allocating what types of data are in the table, as opposed to data itself,) through the table header:

<table summary="This table defines all the events that are in progress throughout February 2007">
    <caption>Events for February 2007</caption>
    <thead>
        <tr>
            <th scope="col" abbr="Date of Event">Date</th>
            <th scope="col" abbr="Event Category">Category</th>
            <th scope="col" abbr="Event Name">Name</th>
            <th scope="col" abbr="Related Documents">Documents</th>
        </tr>
    </thead>


    …

</table>

Added code from each step will be in red, to differentiate the previously added code.

A little information about those attributes scope and abbr: they do not affect the layout in any visual way, rather, their purpose is for aural narrators (text-to-speech converters,) to mark which direction the table is flowing (scope) and whether the content in the headings has been abbreviated in any way (e.g. an ‘M’ in a calendar table would have abbr="Monday" to enhance its meaning.) The confusing thing about the abbr attribute is that it can go both ways: it can mean the long version of what’s in the table heading, or it could be the abbreviation to the table heading, which happens to be the long version. Which … is a little weird, but that’s what the W3C has to say about that …

Next, if necessary, the footer (which is usually used to generate totals, but basically is the summation of data.) Some people argue that if you aren’t needing a footer, you don’t need a header (that stuff I defined above,) but I still think there are tabular data examples that justify a header without a footer. Let’s continue:

<table summary="This table defines all the events that are in progress throughout February 2007">
    <caption>Events for February 2007</caption>
    <thead>
        <tr>
            <th scope="col" abbr="Date of Event">Date</th>
            <th scope="col" abbr="Event Category">Category</th>
            <th scope="col" abbr="Event Name">Name</th>
            <th scope="col" abbr="Related Documents">Documents</th>
        </tr>
    </thead>
    <tfoot>
        <tr>
            <td>total</td>
            <td>total</td>
            <td>total</td>
            <td>total</td>
        </tr>
    </tfoot>


    …

</table>

As my actual example table doesn’t require a footer, I have just put non-relevant data in there. The final product table I have created will not have the table footer :)

Moving on … let’s not forget the guts of the operation: the main body of the table, all the content.

<table summary="This table defines all the events that are in progress throughout February 2007">
    <caption>Events for February 2007</caption>
    <thead>
        <tr>
            <th scope="col" abbr="Date of Event">Date</th>
            <th scope="col" abbr="Event Category">Category</th>
            <th scope="col" abbr="Event Name">Name</th>
            <th scope="col" abbr="Related Documents">Documents</th>
        </tr>
    </thead>
    <tfoot>
        <tr>
            <td>total</td>
            <td>total</td>
            <td>total</td>
            <td>total</td>
        </tr>
    </tfoot>
    <tbody>
        <tr>
            <td>15 February 2007</td>
            <td>Council Meeting</td>
            <td>Council Meeting</td>
            <td><a href="http://static.mingteo.com/files/test.pdf" title="Agenda (PDF, 26KB)">Agenda (<acronym title="Portable Document File">PDF</acronym>, 26<acronym title="Kilobytes">KB</acronym></a></td>
        </tr>

    …

    </tbody>


</table>

The table header is supposed to be sequentially followed by the table footer, and only then followed by the body. Don’t ask me why, I didn’t make the rules :)

*wipes sweat from forehead* Well, now that we have all the structure sorted out, we’re ready for the next step: getting to the actual styling. I think … that will have to come another day :) This post is already rather long …

Post Script: there are many arguments for and against different, all seemingly semantic, methods to achieve this layout—sometimes, I suppose, what one developer believes is semantic might not be the case for another. I am not claiming this to be ‘the one true way’. If anybody has a suggestion or correction to this structure, be my guest and let me know :) We can easily have a discussion (argument? :D) This is just what I believe is quite good (semantic.)

This entry was posted in techthings and tagged , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *