Techniques

Avoid using tables for layout purposes

Tables are intended for conveying tabular data. Avoid using tables to provide a column-based layout for your pages. CSS is able to produce layouts that replicate table layouts, without the semantics that tables imply.

Use the simplest data table possible

Simple data tables tend to be ones in which each cell corresponds with just one column or row header. Complex data tables often include nested columns or rows and each cell may correspond with several column or row headers. Complex tables can be very difficult to convey accessibly.

  • If you have a large, fairly complex table, split it into multiple, smaller, simple ones;
  • Design your content so that the table reads out logically – row by row;
  • Avoid merging columns or rows using rowspan and colspan – some screen readers have problems conveying their nature to users. If you find you have to merge rows or columns, ask yourself, could I change my table design, or split this into two tables, to make it easier to navigate?
  • Avoid leaving any table cells empty as these can cause confusion for screen reader users.

If your table is beginning to look complex, look at the data and ask yourself, ‘does this need to be in a table?’ This can be a good opportunity to consider a more appropriate format, for example, a narrative description with relevant data points and generalisations.

Use headings and table captions to convey the purpose of the table

  • The heading should appear directly above the table;
  • Ensure your content management system supports the use of table captions, so content creators can use this to describe the nature of the table;
  • You can also use figcaption to provide a heading to your table.

Implement important data table attributes 

  • Code header rows and columns <th>, to differentiate them from data cells <td>
  • Use the scope attribute to associate headers with data cells;
  • Code the text used to summarise the nature of the table inside a <caption> attribute, at the top of the table.

Do not use the table’s “summary” attribute

You used to be able to summarise the nature of the table in a <summary> attribute that sat inside the table. Since the introduction of HTML5, the <summary> attribute is no longer supported. Some screen readers will still announce it but you should not rely on that. Instead, you can use the <caption> attribute to convey the nature of the table, as that will make it available to all users. If necessary, you can use CSS to hide the <caption> from non-screen reader users.

For charts, provide a description in text and a data table of the chart data

  • Do not rely on colour alone to convey information in the chart.
  • If you are using a line chart, use different line styles (solid; dotted; dashed) and thicknesses;
  • If you are using a bar chart, apply patterns to each bar (horizontal, vertical, diagonal lines) and border thicknesses.

Example of good practice

There is a caption above the table; column and row headers have been specified and are distinctive in appearance; there is an indication of the unit of measurement for age in the column header; the initial column is left-aligned, making it easy to scan; there is a comfortable amount of cell margin, making it easier to read.

Birthdays for class eleven

Name

Age (years)

Birthday
Emily

8

3rd September
Francois

12

28th April

 

 

 

  • <table> 
  • <caption>Birthdays for class eleven</caption>
  • <tr>   
    • <th scope="col">Name</th>
    • <th scope="col">Age (years)</th>
    • <th scope="col">Birthday</th>
    • </tr>
    • <tr>
      • <th scope="row">Emily</th>   
      • <td>8</td>
      • <td>3rd September</td>
    • </tr>
    • <tr>
      • <th scope="row">Francois</th>   
      • <td>12</td>
      • <td>28th April</td>
    • </tr>
    • </table>

Example of bad practice

There is no caption above the table. Column and row headers have not been specified and are not distinctive in appearance. There is no indication of the unit of measurement for age. The initial column is right-aligned, making it less easy to scan. There is no cell margin so the text is pinned to the cell borders, making it harder to read.

Name

Age

Birthday

Emily

8

3rd September

Francois

12

28th April

 

 

 

  • <table> 
  • <tr>   
    • <td>Name</td>
    • <td>Age</td>
    • <td>Birthday</td>
    • </tr>
    • <tr>
      • <td>Emily</td>   
      • <td>8</td>
      • <td>3rd September</td>
    • </tr>
    • <tr>
      • <td>Francois</td>   
      • <td>12</td>
      • <td>28th April</td>
    • </tr>
    • </table>

Videos

References

WCAG 2.1

EN 301 549 v 2.1.2

  • 1.1.1 Non-text Content
  • 1.3.1 Info and Relationships
  • 1.4.1 Use of Colour

Further reading