Texas Tech University

Accessible Tables

Quick Start: What You Need to Know

Data tables allow users to understand relationships between data points. Screen reader users rely on programmatic associations between header cells and data cells to navigate these grids without losing context.

Immediate Actions:

  • Use <th> for table headers (never just bold text)
  • Use the scope attribute (col or row) to define reading direction
  • Include a <caption> tag to title the table
  • Avoid using tables for layout (design) purposes
  • Do not merge cells unless absolutely necessary
  • Keep tables simple; avoid complex nesting

Why This Matters

Sighted users can quickly scan a table vertically or horizontally to match a data point (like "Price") with a category (like "Laptop"). Screen reader users navigate cell by cell.

  • Without proper markup, a screen reader might just read a stream of numbers: "500, 12, 400, 15."
  • With proper headers and scope, the screen reader announces the context: "Price: 500, Weight: 12, Quantity: 400."

This programmatic association is essential for users to understand the data without having to memorize the column order.

What to Look For: Detailed Checklist

Table Structure

Before creating a table, ask yourself: "Does this content rely on a grid structure to be understood?"

If you are using a table only to control where text or images appear on the screen (layout), you should likely use a different method. Tables should be reserved strictly for multivariate data—where a piece of information relies on both a row header and a column header to make sense.

The Rule of Thumb

If you can replace the table with Headings (H2, H3) and Lists (bullets) without losing the meaning of the content, do so. It is cleaner, more mobile-friendly, and more accessible.

Header cells must be marked up with <th> tags, not <td> tags with bold styling. This tells the browser "this cell is a label for other cells."

What to check:

  • Inspect the top row and/or first column of your table.
  • Are they using <th> tags?

The scope attribute tells the browser if a header applies to a "row" or a "col" (column).

Usage:

  • <th scope="col">Name</th> for vertical columns (headers at the top).
  • <th scope="row">Total</th> for horizontal rows (headers on the left).

Every data table should have a <caption> tag immediately after the opening <table> tag. This acts as a title for the table, allowing screen reader users to decide if they want to read the table or skip it.

Example:<caption>Fall 2025 Tuition Rates</caption>

Do not use HTML tables to position images or text on a page. Tables are for data only. Use CSS Grid or Flexbox for layout.

If you must use a layout table: Add role="presentation" to the table tag. This tells screen readers to ignore the table structure and read the content as if it were just paragraphs.

Code Examples & Best Practices

Standard Data Table

Bad Example: No semantics

<table>
  <tr>
    <td><b>Name</b></td>
    <td><b>Age</b></td>
  </tr>
  <tr>
    <td>John</td>
    <td>25</td>
  </tr>
</table>
Using bold tags inside standard cells does not create a programmatic header. A screen reader will not associate "John" with "Name," making the data hard to understand.

Good Example: Semantic headers

<table>
  <caption>Student Ages</caption>
  <thead>
    <tr>
      <th scope="col">Name</th>
      <th scope="col">Age</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>John</td>
      <td>25</td>
    </tr>
  </tbody>
</table>
This table uses a caption, explicit table head grouping, th tags, and scope attributes. A screen reader will explicitly announce "Name: John" and "Age: 25".

Complex Table Example (Using id and headers)

Advanced: Handling irregular headers

Use this method when a table has multiple levels of headers that break the flow (like sub-categories in the middle of a table). This ensures screen readers repeat the correct headers for every data cell.

<table>
  <caption>Coffee Prices</caption>
  <thead>
    <tr>
      <th id="h_item">Item</th>
      <th id="h_small">Small</th>
      <th id="h_large">Large</th>
    </tr>
  </thead>
  <tbody>
    <tr><th colspan="3" id="h_hot">Hot Drinks</th></tr>
    <tr>
      <th id="r_latte" headers="h_hot">Latte</th>
      <td headers="h_item r_latte h_hot h_small">$3.50</td>
      <td headers="h_item r_latte h_hot h_large">$4.25</td>
    </tr>
  </tbody>
</table>
By using id on headers and the headers attribute on data cells, we explicitly map the relationships. When reading "$3.50", the screen reader knows it relates to "Item: Latte", "Category: Hot Drinks", and "Size: Small".

Refactoring Layout Tables

Many older pages use tables just to put text next to an image or to align a list. These should be converted to standard headers and lists.

❌ Before (Inaccessible Layout Table):

Screen readers may read this left-to-right, confusing the order of information.

IT Help Central Office Hours
Box 43050
Lubbock, TX
M-F: 8am - 5pm
Sat: Closed
✅ After (Semantic HTML):

This structure is responsive and allows users to navigate by headings.

IT Help Central

Box 43050
Lubbock, TX

Office Hours

  • Mon-Fri: 8am - 5pm
  • Sat: Closed

WCAG 2.1 Success Criteria Summary

The following WCAG 2.1 Level A and AA success criteria apply to data tables:

1.3.1 Info and Relationships Level A

Information, structure, and relationships conveyed through presentation can be programmatically determined. This means visual relationships (like a column of numbers under a "Price" header) must be coded so software can understand them.

Real-World Impact: Why This Matters

The Tuition Matrix
Finding the right number

A prospective student using a screen reader visits the financial aid website to check tuition costs. The page features a large table with columns for "In-State," "Out-of-State," and rows for "Undergraduate," "Graduate," and "Law."

Because the table was coded properly with scope="col" and scope="row", as she navigates to the cell "$12,000," her screen reader announces: "Out-of-State, Graduate: $12,000." She knows exactly what the fee represents.

If the developer had only used <td> tags, she would have heard only "$12,000" and would have to memorize the column order or constantly navigate back to the top of the table to check which column she was in.

The "Missing" Title
Skipping irrelevant data

A researcher is quickly scanning a page with five different data tables looking for specific enrollment statistics. He uses a shortcut key to jump from table to table.

Because the tables use the <caption> tag, his screen reader announces: "Table: Fall 2023 Enrollment," "Table: Spring 2024 Enrollment," and "Table: Faculty Demographics." He can easily skip the first two and focus on the third.

Without captions, he would have to enter every single table and listen to the first few rows of data just to figure out what the table was about.

Additional Resources

WCAG Guidelines and Understanding Documents

Testing Tools

Digital Accessibility