How to Build Accessible Data Tables

Mobile & Accessibility2 min readBy the Monopage team

Tables are a good way to present comparisons such as pricing, schedules, and specifications. Done properly, they're easy to scan and navigate with a screen reader. Done badly, with merged cells, missing headers, or visual tricks, they turn into a jumble.

Use tables for data, not layout

Tables are for information with rows and columns. Don't use them to arrange page layout. Use CSS for layout. A layout table forces screen readers to read the cells in an order that may not make sense.

Mark up headers

Tell the browser which cells are headers:

  • Use th for header cells, and td for data cells
  • Add scope="col" to column headers and scope="row" to row headers
  • Put column headers in a thead and data in a tbody

This lets a screen reader announce the relevant headers as users move through the table, so each value is understood in context, for example "Standard plan, price, 29 dollars."

Add a caption

A caption element gives the table a title that assistive technology announces. It also helps all users understand what the table shows. Put it first inside the table element.

<table>
  <caption>Monthly plans and what's included</caption>
  <thead>
    <tr><th scope="col">Plan</th><th scope="col">Price</th></tr>
  </thead>
  <tbody>
    <tr><th scope="row">Basic</th><td>$19</td></tr>
  </tbody>
</table>

Keep structure simple

  • Avoid merged cells (colspan and rowspan) unless you truly need them, and if you do, use more advanced header associations carefully
  • Don't leave header cells empty. Give the top-left cell a label if it's meaningful
  • Avoid nesting tables inside tables
  • Keep tables small. If a table is huge, consider splitting it into several focused ones

Make content understandable

  • Use clear header text
  • Don't use color alone to convey meaning. Add text or icons. See color blindness and web design
  • Align numbers consistently so they can be compared
  • Use plain text in cells, avoiding unnecessary formatting
  • Add units in headers or cells

Think about small screens

Wide tables can overflow on phones. Common solutions:

  • Let the table scroll horizontally inside a container, and make the container keyboard accessible
  • Reflow rows into stacked cards on narrow screens, while preserving the relationships between headers and values
  • Show only the most important columns by default

Never hide headers visually in a way that removes them for screen readers. See responsive design basics.

Responsive tables and pricing

For pricing comparisons, consider whether a table or cards communicate better. See pricing page best practices.

Check contrast and readability

Zebra stripes and borders should keep text readable. See color contrast and readable text.

Test it

Tab through the page and use a screen reader to navigate the table cell by cell. Verify that it announces headers and the caption. See how to test with a screen reader.

Don't use images of tables

A screenshot of a table can't be read, searched, or resized. Use a real table. See alt text best practices.

The bottom line

Use real table markup with captions and header cells, keep structures simple, and plan for small screens. Then everyone can read your data.