Home / Best Practices / Tables

Tables

Basics

  1. Avoid using tables for layout.
  2. Captions should be included where possible.
  3. Add a table summary attribute for complex tables.
  4. Mark up table data cells with the <td> element and table header cells with the <th> element.
  5. Use the scope attribute to associate data cells with the appropriate headers.
  6. Don't define a width for a table or table cells.

In depth

Tables on the web are difficult to read for everyone.  The best rule of thumb for tables is to keep them as simple as possible.

Don't use tables for layout

Tables were originally intended for tabular data and should be limited to that.  Occasionally, using a table for layout is unavoidable, but the content must be accessible--that is, it can be read linearly and can be scaled.  In general, though, avoid the use of tables for layout.

Note: One exception to this rule is email. Presently, tables are still the only reliable layout method for email. If you absolutely must use a table for layout, add the ARIA role="presentation" to the <table> element.  When a table has an ARIA   role="presentation", all HTML markup in that table (table, tr, td, etc.) is ignored, but the table contents is still available to assistive technologies.

Captions

Captions are not necessary for every table; however, they are often helpful and should be included where possible. The <caption> element is placed directly after the <table> element and identifies the subject of the table.

<table>
<caption>Student Grades</caption>
<tr>...

Table summary

Add a table summary attribute within the <table> element for complex tables.  Screen readers will read the summary, so users with no or limited vision can create a mental image of the table layout.

<table summary="This is a table of car prices for the five top manufacturers' (column headings)
for each class of car, Subcompact, Compact, Midsize and Large (row headings)">

Header cells

Mark up table data cells with the <td> element and table header cells with the <th> element.  Marking column and row header cells is extremely important for accessible tables.

<table>
  <tr>
    <th>Fruit</th>
    <th>Vegetables</th>
  </tr>
  <tr>
    <td>Apples</td>
    <td>Broccoli</td>
  </tr>
  <tr>
    <td>Bananas</td>
    <td>Carrots</td>
  </tr>
</table>

Scope

Use the scope attribute on table column and row header elements to associate the data cells with the appropriate headers:

<table>
  <caption>Student Grades</caption>
  <tr>
    <th scope="col">Name</th>
    <th scope="col">History</th>
    <th scope="col">Math</th>
    <th scope="col">English</th>
  </tr>
  <tr>
    <th scope="row">John</th>
    <td>C</td>
    <td>A-</td>
    <td>B-</td>
  </tr>
  <tr>
    <th scope="row">Marie</th>
    <td>A</td>
    <td>B</td>
    <td>B+</td>
  </tr>
</table>

Width of tables and cells

Don't define a width for a table or table cells. Not declaring a width allows table contents to wrap inside the cells and limits scrolling for users with vision impairments who must zoom text. If you must define widths, use relative (percentages) rather than absolute (pixel) values.

Note: The <thead> and <tfoot> elements provide no accessibility benefits (they are only used when a table is printed).

How to test

The most reliable way to test tables is with a screen reader.  You can also manually inspect tables:

Relevant W3C WAI documents