Accessibility Required
Give tables real headers
Mark up data tables with th, scope and a caption or label. Use tables only for data, never for layout.
How to do it
Use <th scope="col"> and <th scope="row"> with a <caption>. On narrow screens, let rows stack instead of scrolling, and keep explicit table roles so screen readers still read it as a table.
Example
<!-- Explicit roles, because stacked rows lose their table role in some browsers -->
<table class="table" role="table">
<caption>Opening hours</caption>
<thead><tr role="row"><th scope="col" role="columnheader">Day</th><th scope="col" role="columnheader">Hours</th></tr></thead>
<tbody><tr role="row"><th scope="row" role="rowheader">Monday</th><td role="cell" data-label="Hours">9:00 to 17:00</td></tr></tbody>
</table>
How to check
axe table rules pass. A screen reader reads each cell with its headers.
For agents: if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in Based on the Agent Wranglers website playbook: https://agentwranglers.se/playbook/website/accessibility/data-tables.