Bring on the tables
Something that often seems to confuse people that are new to CSS-based layouts is the use of tables. I’ve seen plenty of cases where people interpret “avoid using tables for layout” as “don’t use tables at all”. It’s important to remember that tables are still perfectly fine to use – if used correctly.
Yes, do your best to avoid using tables for layout, but for tabular data, tables are what you should use. I’d like to talk about how tables should be used when marking up tabular data. There’s a lot more to tables in HTML and XHTML than just rows and cells. Much more. Especially if you want to make them accessible.
First a bit of background info. The “avoid using tables for layout” blurb can be found in Introduction to tables in the HTML 4.01 Specification:
Tables should not be used purely as a means to layout document content as this may present problems when rendering to non-visual media. Additionally, when used with graphics, these tables may force users to scroll horizontally to view a table designed on a system with a larger display. To minimize these problems, authors should use style sheets to control layout rather than tables.
I’d say that makes it pretty clear, although the word used is should, not must, so there is some flexibility in the specification.
But this article is not about using tables for layout or not. It’s about using tables for their original purpose: marking up tabular data.
When tables are used to mark up actual data, they aren’t just a layout grid. Sighted people can get a feel for the relationship between header and data cells by looking at the layout and visual presentation of the table. Blind or severly vision impaired people can’t do that. For a table to be accessible to people using a screen reader or some other non-visual user agent, it needs to tell the user agent how the information it contains is related.
Fortunately, HTML provides plenty of elements and attributes for that. Less fortunate is the fact that it can be pretty difficult to understand how to use some of these accessibility features. In this article, I’ll try to explain how most of them can be used.
Table headers, <th>
Let’s start with a very simple table that only has a single row of headers, each defining the data in a column. Marked up the old-fashioned way, with just table rows and cells, the markup would be this:
<table><tr><td>Company</td><td>Employees</td><td>Founded</td></tr><tr><td>ACME Inc</td><td>1000</td><td>1947</td></tr><tr><td>XYZ Corp</td><td>2000</td><td>1973</td></tr></table>
With no borders or styling, the table will look like this in most browsers:
| Company | Employees | Founded |
| ACME Inc | 1000 | 1947 |
| XYZ Corp | 2000 | 1973 |
By styling the table with a bit of CSS, you can make the headers more obvious for those using a graphical browser:
| Company | Employees | Founded |
| ACME Inc | 1000 | 1947 |
| XYZ Corp | 2000 | 1973 |
For a sighted person, it’s now quick and easy to make the connection between headers and the data cells they describe. Someone using a screen reader, on the other hand, would hear something like Company Employees Founded ACME Inc 1000 1947 XYZ Corp 2000 1073
. Not very easy to make any sense out of.
The first – and easiest – step towards making this table more accessible is to mark up the headers properly. It’s very simple: just use the <th> (table header) element instead of <td> (table data) for the header cells:
<table><tr><th>Company</th><th>Employees</th><th>Founded</th></tr><tr><td>ACME Inc</td><td>1000</td><td>1947</td></tr><tr><td>XYZ Corp</td><td>2000</td><td>1973</td></tr></table>
| Company | Employees | Founded |
|---|---|---|
| ACME Inc | 1000 | 1947 |
| XYZ Corp | 2000 | 1973 |
For this simple table, that is enough information for a screen reader to be able to let the user know which header each data cell is related to. A screen reader might say Company: ACME Inc. Employees: 1000. Founded: 1947.
, and so on for each row. Much better.
Table captions: <caption>
The <caption> element can be used to provide a short description of a table, much like an image caption. By default, most visual browsers render the <caption> element centered above the table. The CSS property caption-side can be used to change that, if necessary. Most browsers will only display the caption either above (top) or below (bottom) the table contents, while some will accept left or right as values. I’ll leave it to you to experiment with this.
When used, the <caption> element must be the very first thing after the opening <table> tag:
<table><caption>Table 1: Company data</caption><tr><th>Company</th><th>Employees</th><th>Founded</th></tr><tr><td>ACME Inc</td><td>1000</td><td>1947</td></tr><tr><td>XYZ Corp</td><td>2000</td><td>1973</td></tr></table>
| Company | Employees | Founded |
|---|---|---|
| ACME Inc | 1000 | 1947 |
| XYZ Corp | 2000 | 1973 |
You can of course use CSS to style the caption if you wish. However, be aware that it can be a little tricky to style it consistently across browsers. I’ll leave that as another exercise for you.
Explaining the table: the summary attribute
A sighted person can easily decide whether or not to study a table in detail. A quick glance will tell how large the table is and roughly what it contains. A person using a screen reader can’t do that unless we add a summary attribute to the table element. This way you can provide a more detailed description of the table than is suitable for the <caption> element.
The contents of the summary attribute will not be rendered by visual browsers, so make the description long enough for anyone hearing it to understand what the table is about. Don’t overdo it though, and use the summary attribute only when necessary, i.e. for more complex tables where a summary will make it easier for someone using a screen reader to understand the contents of the table.
<table summary="The number of employees and the foundation year of some imaginary companies."><caption>Table 1: Company data</caption><tr><th>Company</th><th>Employees</th><th>Founded</th></tr><tr><td>ACME Inc</td><td>1000</td><td>1947</td></tr><tr><td>XYZ Corp</td><td>2000</td><td>1973</td></tr></table>
Shortening the headers: the abbr attribute
When a screen reader encounters a table, it can announce the associated header (or headers) before each data cell. If you have long headers, hearing them repeated over and over can get tedious. By using the abbr attribute to provide an abbreviated version of any long headers, you give screen readers something that they can use instead of the text in the header itself. Using the abbr attribute is optional, and most of the time your headers will (and probably should) be pretty short anyway.
If the example table is modified slightly, to make the headers longer, the abbr attribute could be used like this:
<table summary="The number of employees and the foundation year of some imaginary companies."><caption>Table 1: Company data</caption><tr><th abbr="Company">Company Name</th><th abbr="Employees">Number of Employees</th><th abbr="Founded">Foundation Year</th></tr><tr><td>ACME Inc</td><td>1000</td><td>1947</td></tr><tr><td>XYZ Corp</td><td>2000</td><td>1973</td></tr></table>
| Company Name | Number of Employees | Foundation Year |
|---|---|---|
| ACME Inc | 1000 | 1947 |
| XYZ Corp | 2000 | 1973 |
A screen reader could then read the full length headers for the first row of data, and then use the abbreviation for the remaining rows.
Considering how hard it can be to make data tables fit a layout, I’d say it’s more common to have a need for the opposite: to make the headers as short as possible, or even abbreviated, and use the title attribute or the <abbr> element to provide a longer explanation.
Linking headers to data: the scope, id and headers attributes
Many tables are more complex than the example table I’ve been using so far. I’ll make it a little more complex by removing the “Company” header and changing the data cells in the first column into header cells:
<table summary="The number of employees and the foundation year of some imaginary companies."><caption>Table 1: Company data</caption><tr><td></td><th>Employees</th><th>Founded</th></tr><tr><th>ACME Inc</th><td>1000</td><td>1947</td></tr><tr><th>XYZ Corp</th><td>2000</td><td>1973</td></tr></table>
| Employees | Founded | |
|---|---|---|
| ACME Inc | 1000 | 1947 |
| XYZ Corp | 2000 | 1973 |
In this table, each data cell has two headers. The simplest method, markup-wise, of making sure that a non-visual browser can make sense of this table is to add a scope attribute to all header cells:
<table summary="The number of employees and the foundation year of some imaginary companies."><caption>Table 1: Company data</caption><tr><td></td><th scope="col">Employees</th><th scope="col">Founded</th></tr><tr><th scope="row">ACME Inc</th><td>1000</td><td>1947</td></tr><tr><th scope="row">XYZ Corp</th><td>2000</td><td>1973</td></tr></table>
The scope attribute defines whether a header cell provides header information for a column or a row:
col: header information for the column it is inrow: header information for the row it is in
Adding a scope attribute with the value col to the headers in the first row declares that they are headers for the data cells below them. Likewise, giving the headers that begin each row a scope with the value row makes them headers for the data cells to their right.
The scope attribute can take two more values:
colgroup: header information for the rest of the column group that contains itrowgroup: header information for the rest of the row group that contains it
A column group is defined by the <colgroup> element. Row groups are defined by the <thead>, <tfoot> and <tbody> elements. I’ll get back to those in a bit.
What if you want to keep the “Company” header, and still have the company names be row headers? That would make the cells containing the company names provide both header and data information. In this case, <td> should be used together with the scope attribute:
<table summary="The number of employees and the foundation year of some imaginary companies."><caption>Table 1: Company data</caption><tr><th scope="col">Company</th><th scope="col">Employees</th><th scope="col">Founded</th></tr><tr><td scope="row">ACME Inc</td><td>1000</td><td>1947</td></tr><tr><td scope="row">XYZ Corp</td><td>2000</td><td>1973</td></tr></table>
This way, visual browsers won’t display the company names as headers by default, so a bit of CSS is needed to fix that. For this example, I used the following CSS:
td[scope] {font-weight:bold;}
Note that this rule uses an attribute selector, which Internet Explorer does not support. A workaround for that would be to add a class to any data cells that should be styled as a header.
| Company | Employees | Founded |
|---|---|---|
| ACME Inc | 1000 | 1947 |
| XYZ Corp | 2000 | 1973 |
Another technique for connecting a table’s data cells with their appropriate header involves giving each header a unique id. A headers attribute is then added to each data cell. This attribute contains a list, separated by spaces, of the id of every header cell that applies to that data cell. This technique is more complicated, and should only be used when there are data cells that need to be linked to more than two header cells, and the scope attribute is insufficient, as in a very complex or irregular table.
To illustrate this, I’ve changed the table to show the number of employees of each sex the companies have:
<table class="extbl" summary="The number of employees and the foundation year of some imaginary companies."><caption>Table 1: Company data</caption><tr><td rowspan="2"></td><th id="employees" colspan="2">Employees</th><th id="founded" rowspan="2">Founded</th></tr><tr><th id="men">Men</th><th id="women">Women</th></tr><tr><th id="acme">ACME Inc</th><td headers="acme employees men">700</td><td headers="acme employees women">300</td><td headers="acme founded">1947</td></tr><tr><th id="xyz">XYZ Corp</th><td headers="xyz employees men">1200</td><td headers="xyz employees women">800</td><td headers="xyz founded">1973</td></tr></table>
| Employees | Founded | ||
|---|---|---|---|
| Men | Women | ||
| ACME Inc | 700 | 300 | 1947 |
| XYZ Corp | 1200 | 800 | 1973 |
As you can tell, this method quickly gets really complicated, so if it is possible, use the scope attribute instead.
Spanning rows and columns
In the old, tables-for-layout days, the attributes rowspan and colspan were often used to make table cells span several rows or columns in order to put all of the neatly sliced images back together. Those attributes are still around – there is no way to use CSS to specify spanning. If you think about it, it’s quite logical: row and column spans are part of a table’s structure, not its presentation.
Columns and column groups: <col> and <colgroup>
HTML provides the <colgroup> and <col> elements for grouping related table columns. This allows (in some browsers) the use of CSS to style columns independently. Column groups can also be used by the scope attribute to specify that a cell contains header information for the rest of the column group that contains it.
That’s all I’m going to say about columns and column groups here. For more detailed information, see the links in the section “What I didn’t tell you”.
Row groups: <thead>, <tfoot>, and <tbody>
Table rows can be grouped into a table head (<thead>), a table foot (<tfoot>), and one or more table body (<tbody>) sections. Each row group must contain one or more table rows.
If a table has a head section, it must appear before the table foot and body sections. A table foot section must appear before the body section(s). If no head or foot section is used, the <tbody> element is not required (but not forbidden either, so add it if you like). The structure of a table that has row groups looks like this:
<table><thead><tr></tr>… more rows for the table head</thead><tfoot><tr></tr>… more rows for the table foot</tfoot><tbody><tr></tr>… more rows for the first table body</tbody><tbody><tr></tr>… more rows for the second table body</tbody>… more table bodies if necessary</table>
Row grouping can be useful for several reasons:
- It makes it easy to style the head, foot, and body sections of a table independently of each other, without having to add classes to any elements.
- When printing long tables, some browsers (like those based on Mozilla) will repeat the information in the head and foot sections on every printed page, making it easier to read the printed table.
- Separating the head and foot from the body also makes it possible for browsers to support scrolling of the table body only.
For data tables only
Everything described here is related to the use of HTML tables to structure and present data. If you use tables for layout, neither of the techniques described here should be used. No summary attribute, no headers, no <caption>, nothing. Just a plain, old-fashioned layout table, consisting of no other elements than <table>, <tr>, and <td>. Otherwise you will risk confusing users of non-visual user agents even more.
The benefits
It may look like a lot of work to create accessible data tables in HTML. For complex tables, it is. Sometimes to the point where it gets almost impossible to do by hand. For simple tables though, using header cells with a scope attribute is quick and easy.
It’s obvious that people using screen readers or other assistive technology benefit from tables that use the available accessibility features. Trying to make sense of a large and complex table by listening to it can still be very difficult, so if at all possible, simplify the table.
Less obvious is that designers and users of graphical browsers also benefit: an accessible table has plenty of structural hooks to apply CSS to, and good styling can make the table more usable for everybody.
What I didn’t tell you
There is even more to data tables than I have mentioned here. For example, I haven’t mentioned the axis attribute at all (until now), and I did not describe the <colgroup> and <col> elements in great depth. Neither have I gone into formatting and styling or the border models. Also missing is an example of a really complex table.
For those of you looking for even more detailed information, here are links to some further reading:
- Tables in HTML documents
- CSS formatting of tables
- Techniques for Accessible HTML Tables
- Building accessible websites: Tables and frames
- A table, s’il vous plaît
Translations
This article has been translated into the following languages:
- Chinese: 标准化——表格 (Translation by JunChen)
- French: Au tableau ! (Translation by Pompage.net)
- Russian: Практический HTML: работаем с таблицами (Translation by DreamwinD)
- Previous post: BloggForum Stockholm 2004
- Next post: Scrollable Table
Information, sponsorship, and externals
About the author
Roger Johansson is a Swedish web professional specialising in web standards, accessibility, and usability. More about me and this site.
Latest articles
- Validation statistics from Nikita the Spider Comments off
- An analysis of the sites crawled by the bulk validation tool Nikita the Spider during March 2008.
- Authentic Jobs API and Affiliates program Comments off
- The Authentic Jobs job listing service now has a public API and an affiliate program.
- What does Acid3 mean to you and me? Comments off
- Opera and Apple have announced that their web browsers pass the Acid3 Browser Test, but how will that help web designers and developers?
- Designing Web Navigation (Book review) Comments off
- Learn the fundamentals of navigation design and design better navigation systems for large and small sites as well as for web based applications.
- DOMAssistant bundle for TextMate Comments off
- To save keystrokes and speed up development I have created a DOMAssistant bundle for TextMate.
- First impressions of Internet Explorer 8 Beta 1 Comments off
- My impressions after trying out Internet Explorer 8 Beta 1 for a couple of days.









Comments
Great post. Definitely going to bookmark this one! Keep up the good work.
Amazing work. The best writing on the subject I've ever seen. Thanks for sharing.
Many thanks for this very good and useful article plus the complementary links.
I thing have struck me with tables. What is the purpose of having both summary and caption. Many times I notice that I put the same thing in the two. So if just using one, which one is to prefer?
Another thing I have a mental problem with is when to put things in tables. Should it just be numbers or is it ok with text. For example,
<table> <tr> <th>Details</th> <th>Information</th> </tr> <tr> <td>A long brown bear with hungry eyes</td> <td>Brown bear</td> </tr> </table>
Is that ok? But then, should the text be in a p?
<table> <tr> <th>Details</th> <th>Information</th> </tr> <tr> <td><p>A long brown bear with hungry eyes</p></td> <td><p>Brown bear</p></td> </tr> </table>
Thanks for the post
That's quite simple - Caption is just a title of a table (for both sighted and blind readers), while summary attribute is long(er) description of table data, purpose, layout and such (primary for blind readers).
Of course not! Any tabular data
You don't have to include <p> inside <td>, but I guess, you can do that when you want to include more than one paragraph in a single table cell. But do you really want to?
BTW - This is just the same situation with <li> tag...
hmmm... it was ok on preview but now it's broken :-(
again: You don't have to include p inside td [...] same situation with li tag...
Enlightening work; very well done. I was never aware of these extra tags and attributes to tables to help organize and describe information. This does bring up an idea I've been meaning to do for a while though: download a screen reader.
I apologize for being somewhat naïve and not googling this first, but does anyone quickly know of a good browser compatibility chart for these table tags and attributes?
Grant Gatchel: I would say that they all work great in all browsers. I have not found one that doesn´t support them. Even Lynx works well with them.
Me again :)
I must say the way you made the code examples was cool way of using ol. Mayby not semanticly correct but anyway. Too bad it is not valid to do:
<code> <ol> <li>test</li> <li>test</li> </ol> </code>
Sorry for be off topic
Whoa, great article, I didn't know there was so much about tables.
Jens: I think it's pretty semantic, in that it adds line numbers even if you view the document unstyled. But you're right: every line should be wrapped in a <code> element. I'll fix that as soon as my 'net connetion at home starts working again.
Anyway, I didn't come up with the line numbering idea: it's something I "borrowed" from Dunstan Orchard, who got the idea from Simon Willison.
Great article. I'm currently reading the excellent book on accesibility by Joe Clark and this summarises a lot of the stuff that makes tables more accesible. Great bunch of links too. Keep up the good work!
Great article. I'm currently reading the excellent book on accesibility by Joe Clark and this summarises a lot of the stuff that makes tables more accesible. Great bunch of links too. Keep up the good work!
One more link to consider: Dive into Accessibility - among many other things this book includes "real life" examples of importance of "extra tags" in tables.
Excellent.
Thank you for this cracking article, It's just what I've been looking for.
Cheers!
I had been trying to explain to people I work with for a while now that tables should be used for tabular data rather than layout. Thank you for this article. Hopefully some other people at my job will read this.
Long live tables for tabular data! "I like 'em so much, I put one on me 'omepage"
Thanks for writting this out Roger :) It'll be good to have something to point to when the next person asks how tables should be used.
Excellent article. I was not aware of the "caption" element.
Great work. Not seeing this article, I whould forget about table tags.
Great article. There was a heap there I hadn't seen before, especially the "scope" attribute.
I couldn't believe there were so many attributes I'd never seen before - scope, headers and abbr were all new to me. Time for me to read the XHTML Modularisation doc again.
Yes, an excellent post. (I've linked your site from mine.) I think it's important for people to understand the logical reason behind usage of certain elements of HTML, including tables. Thanks to CSS, we can now use tables for what they were originally intended for.
Great post! However:
The screen readers I have tried do not do this (at least not with default settings). Usually the listener has to press a key combination to hear the header cells again.
I have started writing on a similar topic: Grouping table data (work in progress)
Peter: I'd say that what's most important is that the headers can be announced if the user wants to hear them. I'll rephrase the sentence you quoted to reflect that.
Great article. There were some tags I've used infrequently (without fully understanding them) and some I wasn't aware of.
I'll be forwarding this to a number of colleagues.
BTW: all your nice formatting breaks in the print version, when I tried it with Opera and Mozilla. :-(
Tech Notes: That's the whole point of the print version :) It removes everything but the main content and basically just leaves the text.
IE doesn't use the THEAD and TFOOT tags properly by default when printing (ie: repeating those sections on every page for really long tables when printing). You can fix this through css like this:
Hello, this is juste my place where i keep my notes. It's just for me you know. Only for me. Usually, my place is password protected. Sorry for this bad felling. Sorrrrrrry Great article!
"Author : Roger Johansson Hi. Nice article. Reminds me a lot of Bring on the tables over at my site. Hrm."
And I like the same music as you (Dj Krush, Esbjörn Svensson Trio,...). (I'm a record dealer)
Simon: Apology accepted, and no hard feelings :-)
Have been in web dev. for a long while now. Is possible one of the best articles about tables I have seen. Well done. By the way I hate tables 'cause 90% of people dont know when and how to use them.
Great article, and a big help. Know anywhere I can find out how to style a column of data with CSS?
Matt: I haven't done any extensive research on column styling, but the specs state that you can only apply four CSS properties to col and colgroup elements: border, background, width, and visibility. IE/Win lets you apply other properties than those, but it shouldn't.
Ian Hixon has written a bit about the issue: The mystery of why only four properties apply to table columns.
Please note the speak-header property:
(Just ran into this while reading the specs, so can't tell you about support or its working)
Btw, in the CSS 2.1 spec, the speak-header property can be found in Appendix A - Aural style sheets
Anyone know the logic behind the tfoot having to appear before any tbodies in the source html?
I found the answer moments after asking my question from the html401 tables spec
You say that TD should be used together with the scope attribute if the cells containing the company names provide both header and data information. Would it be horribly wrong to use TH there as well? I just felt like you could have elaborated a little there...
Oh by the way, I had to enter my name and email twice because I clicked the radio buttons. Kind of annoying... I thought "Remember the above info" was some sort of acceptance of usage terms or something, but know I get it... :-)
Thanks for a great site!
I was actually looking for examples of accessible and stylish tables and came across this article on my travels. It's a great page to send people to with regards to getting people off tables for layouts and how to use them for their intended purpose.
A table potentially alters, albeit temporarily and if done incorrectly such as using for layouts, document structure, so it's important to use them wisely with regards to captions, summaries, headers, rows and footers.
A page to bookmark!
I particularly liked this article. Though you didn't mention it, your listed links (after) did: you can easily put the caption below the table with CSS. Just define:
caption { caption-side: bottom; }
http://www.w3.org/TR/CSS21/tables.html#q6
(with glass raised): TO THE TABLES!!!
Great article. I've been looking for it
Very interesting and helpful! Especially you also described how visually impaired people will perceive the output. I just attended a short presentation by a blind person, and he told us about the same stuff, just not the programming details that this might imply! More of this!
Excellent work. I've used infrequently.
Great Article!
Is there any way I can make the heading fixed on the page? This is useful with long tables.
craig: Yep: Pure CSS Scrollable Table with Fixed Header.
I was wondering what to do when you have some * in your table that refers to a footnote that has to be placed under the table.
Is it ok placing some (p)* footnote txt(/p) under the table? (table) (tr) (td)Company(/td) (td)Employees(/td) (td)Founded(/td) (/tr) (tr) (td)ABC Inc*(/td) (td)1000(/td) (td)1947(/td) (/tr) (tr) (td)XYZ Corp(/td) (td)2000(/td) (td)1973(/td) (/tr) (/table)
(p)ABC Inc* is part of A-Z Group(/p)
Nice article. Im searching nice ways to present huge data tables. So the link in post #47 helped me alot. But I found another nice solution. It's with fixed header and fixed first column - http://aktuell.de.selfhtml.org/artikel/javascript/scrolltabelle/index.htm
I tried todo it with pure CSS and without JavaScript. But i didnt found the solution yet.
Great article. That's the best piece of writing I have seen regarding HTML tables. I have learned more from your article than reading any of the HTML tutorials available online. Recently, I started learning more about website design, usability and accessibility. Your effort has given me aspirations to be a better coder and writer.
A truly well written article. Well done.
Thanks for not being the "No tables at all" type.. I'm thinking hard about how to really making some skinnable (fully css) sites/applications where tables can live too using the width 100% "trick".. last time I tried absolute positioned divs with tables inside, the "width 100%" screwed it completely up... sigh.
Great article, just been doing some complex design work for a design agency and the info in this article gave me some great ideas on how to make the code short and simple!
thanks
Nice. This is visible in all the brousers??
EXELLENT pure EXELLENCE
A good post. Yeah, it's funny at times when people go crazy just to get they'r code so tables when just what they need was tables.
Not sure if anyone mentioned this but I would NEVER embed a p inside a td.
The main reason is that to maximise accessibility you should be using scalable font sizes (to allow font to resize in IE) and you should NEVER embed elements with scalable font values inside other elements with scalable font values i.e. an element with a value of 90% inside an element with a value of 50% could have a final display value of 45% (depending on the browser). I am sure you have all seen examples of this where fonts in tables are so small they are unreadable.
The other big reason is that tables are for tabular data and p's are for paragraphs and we should always use XHTML elements as they we initially intended to be used. IMHO this is a key part of good coding practice.
I had no idea about scope. Simply awesome! Thanks.
Great read, very informative, bookmarked on del.icio.us!
Carl, you're looking at the wrong thing. The problem doesn't lie in putting p elements within td elements; the problem lies in having something stupid like font-size: 50% in a stylesheet without knowing how it would interact with a page. There's nothing inherently wrong with combining relative font sizes, and the rules are quite clear in how they are applied.
As for your other reason, well sorry, but sometimes what you are marking up is logically a paragraph within a table, so a p element within a td element is exactly what should be used.
Great article. One of the best I've seen on tables, I think. Very thorough, and bookmarked for my own reference in future. :D
Loved the article. However how do you code so that the blind reader actually picks up the table headers - or how do you adjust the blind reader to read correctly so that table cells are grouped?
Great article, the best I could find describing how to use tables.
Sorry, comments are closed for this post.