Table Missing Headers

Serious - WCAG Level AA

What the issue is:

The rule flags tables that are used for presenting data but do not contain semantic header cells (<th>) or tables that are used purely for layout but are not marked as presentation (role="presentation").

Why it matters:

Screen readers and other AT (assistive technologies) rely on table header semantics to convey row/column relationships. When headers are missing, users who are blind or have low vision cannot determine the meaning of individual cells. Keyboard-only users and people with cognitive disabilities also rely on predictable structure to understand tabular content.

How to fix it:

  1. Determine intent: is the table presenting data (a data table) or is it purely for layout? If it is layout, replace it with CSS layout (divs/grid/flex). If replacing is infeasible, add role="presentation" to the table to remove table semantics.

  2. For data tables, use semantic header cells: replace header-like <td> cells with <th>. Group headers in <thead> and rows in <tbody>.

  3. Mark header scope: add scope="col" for column headers and scope="row" for row headers so screen readers can map relationships automatically.

  4. For complex tables (multi-row/column headers or non-rectangular headers), use id on <th> and the headers attribute on <td>, or use aria-labelledby to point to header ids.

  5. Add a <caption> to succinctly describe the table.

Best practices:

  • Use semantic <table>/<thead>/<tbody>/<th>/<caption>

  • Keep headers concise

  • Avoid visually hiding headers with display:none (that removes semantics)

  • For responsive/complex tables, consider alternative views (lists) for small screens

Common mistakes:

  • Styling <td> to look like headers instead of using <th>

  • Marking data tables with role="presentation" (which hides semantics)

  • Omitting scope on ambiguous headers

  • Using tables for layout instead of CSS