Short Answer

Data tables fail audits when headers exist only visually. How to use th, scope, and caption so tables make sense to every visitor.

Why data tables keep failing audits

Pricing grids, store hours, comparison charts, order histories, class schedules. Business websites are full of tables, and audit reports are full of table findings.

The reason is simple. A table communicates through position. Sighted visitors see that a price sits under a Plan column and next to a Monthly row, and the meaning snaps into place. Strip away the visual grid and that meaning disappears unless the code carries it.

A screen reader does not see the grid. It walks the table cell by cell, and the only way it can tell a visitor what each cell means is by reading the headers the markup associates with it. When those associations are missing, every cell is just a floating value with no context.

What assistive technology needs from a table

WCAG Success Criterion 1.3.1 asks that information, structure, and relationships conveyed through presentation are also available in the code. For tables, that means three things.

First, the table should be a real table element, not a stack of divs styled into a grid. The table element is what tells assistive technology to switch into table navigation mode, where visitors can move by row and column and hear headers announced as they go.

Second, header cells should be th elements, not bolded td cells. A td styled bold looks like a header to a sighted visitor and behaves like ordinary data to everyone else.

Third, each th should declare its direction with the scope attribute. Use scope col for column headers and scope row for row headers. With those in place, a screen reader can announce Monthly, Pro plan, 49 dollars instead of just 49 dollars.

Captions give the table a name

A caption element directly inside the table gives the whole table an accessible name. Visitors who navigate by table can hear the list of tables on a page and jump straight to the right one.

This matters most when a page holds several tables. Three unlabeled tables on a pricing page force a visitor to enter each one and sample cells until they figure out which is which. Three captioned tables announce themselves.

The caption can be styled to match the design, or visually hidden with an accessible hiding technique if the design truly has no room for it. Removing it from the code removes it for everyone who needed it.

Complex tables usually need restructuring

Tables with merged cells, multiple header rows, or headers in the middle of the data are where simple scope attributes stop being enough.

The headers attribute can connect each data cell to specific header cell ids, and it works, but it is brittle and hard to maintain. Every content edit risks breaking the chain.

The more durable fix is usually editorial. Split one complex table into two simple ones. Repeat a header instead of merging across it. Move explanatory text out of the grid and into a paragraph above it. A table simple enough to mark up cleanly is almost always easier for every visitor to read, not just visitors using assistive technology.

Layout tables and fake tables

Two opposite problems show up in the same audit reports.

Old pages sometimes use table markup for visual layout. Assistive technology announces those as data tables, and visitors wade through rows and columns that mean nothing. If the table is purely decorative layout, modern CSS should replace it. Where that is not practical yet, a presentation role tells assistive technology to ignore the table semantics.

Newer pages have the reverse problem. A div grid styled with CSS looks exactly like a table and exposes none of its structure. If the content is tabular, the markup should be a table. CSS can make a real table responsive. It cannot make a div grid navigable by row and column.

Responsive tables without losing the structure

Small screens push teams toward patterns that quietly destroy table semantics. Common examples include rebuilding the table as stacked cards on mobile, or hiding columns with display none, which removes them from assistive technology as well as from view.

Safer responsive patterns keep the table element intact. Horizontal scrolling inside a labeled container is honest and predictable. Collapsing less critical columns behind a visible toggle keeps them reachable. If the design genuinely needs a card layout on small screens, the cards need their own labels so each value keeps its meaning.

How to verify the fix

Start with the keyboard and a screen reader if one is available. Enter the table and move through a few cells. If you hear headers announced as you change row or column, the associations work. If you hear bare values, they do not.

Then check the code directly. A real table element, th headers with scope, a caption naming the table. For the most important tables on the site, this is a five minute review per table.

Then re scan the page. An automated check confirms the structural markup is present and flags regressions when the template changes later.

A free scan takes about a minute and flags structural issues on the page you care about most. The full audit report maps each table finding to the WCAG criterion involved, with code context, so a developer can fix the template once instead of patching pages.

No scan certifies legal compliance, and this article is not legal advice. What table work does is make some of the densest information on your site readable to every visitor, and it supports remediation toward WCAG 2.1 and 2.2 AA in a way you can demonstrate.

Most table findings trace back to a handful of templates. Fix the pricing table component and the hours table component, and the finding count drops across the whole site. Our compliance guide puts table structure in context with the rest of the high frequency findings.

Want answers specific to your site?

A free scan takes 60 seconds. The sample report shows exactly what a paid audit artifact looks like before you buy.

Run Free Scan View Sample Report →