How to make a perfect semantic HTML table

Posted Jul 31st, 2008 by David Calhoun in html, table

I’ve been sitting in on a few Juku classes hosted by Christian Heilmann this week at the Yahoo headquarters in Sunnyvale.   This portion of the Juku training is a two week look at DOM scripting and Yahoo’s YUI.  Just as review, we went over what makes a nice semantic HTML table.  I figured it would be a good reference, so here’s what we came up with.

Difficulty:

This tutorial assumes you have a basic knowledge of how to make HTML tables using common elements such as <table>, <tr>, <td>, <colspan>, and <rowspan>.  This post shows how to take this knowledge one step further, using tags such as <caption>, <thead>, <tfoot>, <tbody>, <th>, and elements such as summary, scope, and headers.

These extra tags not only make a semantically correct table that can be more easily read by search engines and screen readers, it also creates more “hooks” for which to apply CSS styling.

Code:

<table caption="Table Title" summary="This is a summary of my tabular data.">
	<caption>Table Title</caption>
	<thead>
		<tr>
			<th id="itemcolumn" scope="col">Item Column</th>
			<th id="col1" scope="col">Column 1</th>
			<th id="col2" scope="col">Column 2</th>
		</tr>
	</thead>
	<tfoot>
		<tr>
		<td colspan="3">Table Footer</td>
		</tr>
	</tfoot>
	<tbody>
		<tr>
			<th id="row1" scope="row">Item 1</th>
			<td headers="itemcolumn col1">A</td>
			<td headers="itemcolumn col2">B</td>
		</tr>
		<tr>
			<th id="row2" scope="row">Item 2</th>
			<td headers="itemcolumn col1">C</td>
			<td headers="itemcolumn col2">D</td>
		</tr>
		<tr>
			<th id="row3" scope="row">Item 3</th>
			<td headers="itemcolumn col1">E</td>
			<td headers="itemcolumn col2">F</td>
		</tr>
	</tbody>
</table>

Example:

Table Title
Item Column Column 1 Column 2
Table Footer
Item 1 A B
Item 2 C D
Item 3 E F

Note: This table has CSS formatting which is not included in the example.  It WILL look different when you use it.

Explanation:

<table summary=”Table Title”>
For screen readers and search engines.

<caption>Table Title</caption>
The text the appears above the table.  Note: this is different from the caption element that appears in the <table> tag.

<thead>
This tag contains the table head data.  In the example above, the following text is contained in it: Item Column, Column 1, Column 2.  It’s commonly ignored, since browsers will insert it automatically if it’s not present.  However, it’s nice to have for CSS styling, plus it’s semantically correct, so you should use it!

<tfoot>
This is the table footer, which appears at the bottom of the table, and commonly contains table summary information.  As such, it’s more helpful to screen readers if this appears directly after <thead>, just as it appears in the code above.  However, you can also add this after <tbody> if that makes more sense to you.  Either way, it will appear visually at the bottom of the table.

<tbody>
This is where all of the tabular data is.  It’s the real meat of the table!

<th>
This is the title of the column or row.  In the example above, <th> elements include the following: Item Column, Column 1, Colum 2, Item 1, Item 2.  If you have a table with first and last names, “First Name” and “Last Name” would be <th> elements of the columns.  In addition, if for instance each person is assigned a “User Id”, then each Id would be in a <th> tag.

caption (used in the <table> tag)
This element is here for accessibility reasons.  The W3 guideline suggests making the caption 1-3 sentences long.  Alternatively, you can use the <title> tag in its place.  Note: this is different from the <caption> tag which is explained above.

summary (used in the <table> tag)
This element is also here for accessibility.  As its name suggests, it provides a summary of the data in the table.

id (used only in <th> tags which are in <thead>) (optional)
If you choose to use the headers element (see below), it’s necessary to give the <th> tag a matching id.

scope (used in <th>)
The value of scope is commonly either col or row.  As it only appears in <th> (table header) elements, it specifies which set of data cells (columns or rows) it’s a table header for.

headers (used in <td>) (optional)
In large tables, the user might be viewing data that’s far removed from the column or row headers, so it might be easy to get confused as to what the data is.  “Is this a first name or a last name?”, “Is this a city or a county?”, etc.  The headers element points to the header ids and thus logically connects them.  In the example above, each element points to two header elements ids, which are separated by a space.

It seems to me that this element should be optional.  For one, it looks like this element might be phased out for HTML 5, but some still argue that it should be retained.  Also, unless the table is exceptionally large, there should be no difficulty determining which row and column the data is in.  I am no expert in screen readers, but modern screen readers should have no problem determing which row and column the data is in.

There may be cases, however, when using Javascript to manipulate table data, it might be handy to have the headers element applied, in which case the question whether to implement the element is up to the developer!

abbr (used in <th> tags) (optional)
This element isn’t used in the example above because it won’t necessarily be needed, and as such, in my opinion, its usage is optional (though proponents of web accessibility will argue otherwise!).  A common example of its usage is in calendars, which HTML tables are perfect for.  Many calendars have abbreviations for days of the week, so the <th> (table header) for Sunday may look something like this:

<th id=”sun” scope=”col”>Sun</th>

Now we can add the abbr tag allows us to spell out the column name in its entirety for screen readers:

<th id=”sun scope=”col” abbr=”Sunday”>Sun</th>

See Also:

Techniques for Table Accessibility (Web Accessibility Guidelines 1.0 at w3.org)

Any comments are welcome!  I’ve been making websites for over ten years, but have only very recently started to make them correctly, so I might be making a lot of mistakes or false assumptions here!  Please correct me!

  • Paris Vega on 26 Jul 2010 at 2:58 pm

    Thanks for the knowledge. I’m using this new web wisdom in a project as we speak.

  • Ted Clayton on 10 Dec 2010 at 4:52 pm

    I too have made webpages for a long time, mostly ‘wrong’, no doubt. ;)

    But I have learned the proper CSS, semantic methods, in recent years.

    I work in construction, etc, for a living, and computers, programming and web authoring are all sidelines.

    By the time a person has to make a really serious commitment to a topic (ie, can’t do anything else) in order to participate or practice it, it becomes less interesting to me.

    In fact, I like to do a lot of different things, don’t want to be restricted to one or a few of them … and I like to work in avenues that tend to strengthen that outlook.

    After doing table-presentation in the early years (and adding some CSS to make it more maintainable) I was confronted by the ‘tables are wrong’ campaign. I could see the argument (non-semantic), but I had difficulty with the CSS.

    I also saw that folks who were web-authoring-naive, could fairly easily pick up table-presentation, while CSS presentation did not lend itself nearly so well to usage by ‘lightweights’.

    As time has passed, CSS has matured and standardized far less quickly & well, than other web paradigms. Pushing a decade now, and it’s still messy, on top of being more challenging that table-presentation.

    As my abilities have gradually improved, and I’ve come to understand the ’semantic web’ better & more-clearly, I’ve gradually realized that it *should* be possible to do a good deal of perfectly semantic work, within tables.

    In your post here, you are talking about making *tabular* content semantic. That is different from the semantic issues of typical narrative content, etc, tho, it seems to me, hardly prohibitive of the later.

    Do you know of any degree of acceptance of the idea of using tables for presentation, while honoring the laudable semantic goals?

    Thanks! Ted

  • HTML Table Elements and SEO – The Complete HTML Reference Guide for SEO – Part II on 04 Apr 2011 at 12:02 pm

    [...] you should semantically markup your tables. David Calhoun wrote a good piece of article on how to create the perfect semantic html. Here’s how the table looks like:The Perfect Semantic TableRead the article, then go and make [...]

  • Nick Williams on 01 Jun 2011 at 6:33 am

    Hey Dave,

    The caption attribute isn’t valid on the table element. it fails W3 validation for XHTML Transitional/Strict. Everything else is great though :)

    Cheers,
    Nick

Trackback URI | Comments RSS

Leave a Reply

Categories