Use th elements for table headers in accessible tables
What
This practice applies when building data tables in React TSX. It recognizes violating code when table headers are mistakenly implemented with non-semantic elements like td or div without appropriate role attributes.
Why
Using the th element for headers ensures that assistive technologies correctly identify header cells, which improves accessibility and fulfills WCAG guidelines. It also simplifies the code by relying on built-in browser semantics.
Fix
Replace non-semantic cell elements with th for header cells, or add proper WAI-ARIA role attributes when using custom components, ensuring that each header is clearly defined.
Examples
Example 1:
Positive
This example correctly uses th elements with an appropriate scope attribute to define table headers, ensuring accessibility.
import React from "react";
const DataTable: React.FC = () => {
return (
<table>
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Age</th>
<th scope="col">City</th>
</tr>
</thead>
<tbody>
<tr>
<td>Alice</td>
<td>30</td>
<td>Paris</td>
</tr>
<tr>
<td>Bob</td>
<td>25</td>
<td>London</td>
</tr>
</tbody>
</table>
);
};
export default DataTable;
Negative
This example incorrectly uses td elements for headers, which does not provide the semantic meaning required for accessible tables.
import React from "react";
const DataTable: React.FC = () => {
return (
<table>
<thead>
<tr>
<td>Name</td>
<td>Age</td>
<td>City</td>
</tr>
</thead>
<tbody>
<tr>
<td>Alice</td>
<td>30</td>
<td>Paris</td>
</tr>
<tr>
<td>Bob</td>
<td>25</td>
<td>London</td>
</tr>
</tbody>
</table>
);
};
export default DataTable;