How to Make HTML Tables Easy to Read
Use captions, headers, scope, and responsive wrappers so dense data keeps its meaning on every screen.
The short version
A data cell is only useful when its row and column context remain available.
Use tables for data, not layout
A table represents information with relationships across rows and columns. It is the right tool for a pricing comparison, experiment results, or a financial statement. Page layout belongs in CSS grid or flexbox.
Start with a caption that names the dataset. Use th for headers and td for data. For simple tables, scope="col" and scope="row" make those relationships explicit.
<div class="table-scroll" role="region" aria-label="Plan limits" tabindex="0">
<table>
<caption>Monthly publishing limits</caption>
<thead>
<tr><th scope="col">Plan</th><th scope="col">Pages</th></tr>
</thead>
<tbody>
<tr><th scope="row">Starter</th><td>100</td></tr>
</tbody>
</table>
</div>Keep complex tables honest
Multi-level headers may require id and headers attributes, but complexity itself is a signal. If readers need a legend to understand the grid, consider splitting it into smaller tables or offering a summary before it.
- Align numbers consistently and identify units.
- Do not communicate status with color alone.
- Keep abbreviations explained in nearby text.
- Preserve header markup when exporting to another format.
Plan for narrow screens
Large tables can scroll horizontally inside a labeled region. Avoid silently hiding columns on mobile because that removes information. If a card view replaces the table, ensure each value carries its label so the row context is not lost.