Tables Project
title: "Tables Project — Build Complete Accessible Data Tables" description: "Build production-ready accessible data tables with proper structure, sorting, responsive patterns, and screen reader navigation support." weight: 12 date: 2026-06-28 lastmod: 2026-06-28 tags: [accessibility, tables]
Apply everything you learned by building a production-ready data table with headers, caption, sorting, and responsive behavior.
## What You'll Learn
How to combine all table patterns into a complete, accessible data table component.
## Why It Matters
A complete accessible table handles headers, captions, sorting, and responsive design together. Each pattern reinforces the others.
## Real-World Use
Doda Browser's download manager shows a sortable table with file name, size, status, and progress columns. The table has proper headers, a caption, and is scrollable on mobile.
## Complete Table
```html
<div class="table-container">
<table aria-describedby="table-summary">
<caption>Employee performance review scores</caption>
<thead>
<tr>
<th scope="col" aria-sort="none">
<button onclick="sortTable(0)">Employee</button>
</th>
<th scope="col" aria-sort="none">
<button onclick="sortTable(1)">Department</button>
</th>
<th scope="col" aria-sort="descending">
<button onclick="sortTable(2)">Score</button>
</th>
<th scope="col" aria-sort="none">
<button onclick="sortTable(3)">Rating</button>
</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Alice Chen</th>
<td>Engineering</td>
<td>92</td>
<td>Excellent</td>
</tr>
<tr>
<th scope="row">Bob Smith</th>
<td>Marketing</td>
<td>78</td>
<td>Good</td>
</tr>
<tr>
<th scope="row">Carol Davis</th>
<td>Sales</td>
<td>85</td>
<td>Very Good</td>
</tr>
</tbody>
</table>
</div>
<p id="table-summary" class="sr-only">
This table shows employee performance review scores sorted by score descending.
Columns: employee name, department, score, and rating.
</p>
CSS
.table-container {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
max-width: 100%;
}
.table-container table {
width: 100%;
min-width: 500px;
border-collapse: collapse;
}
.table-container th {
background: #f5f5f5;
padding: 0.75rem;
text-align: left;
position: relative;
}
.table-container th[aria-sort] button {
background: none;
border: none;
font: inherit;
cursor: pointer;
padding: 0;
color: inherit;
}
[aria-sort="ascending"]::after {
content: " ▲";
}
[aria-sort="descending"]::after {
content: " ▼";
}
JavaScript
function sortTable(columnIndex) {
const table = document.querySelector('table');
const headers = table.querySelectorAll('th[aria-sort]');
const tbody = table.querySelector('tbody');
const rows = Array.from(tbody.querySelectorAll('tr'));
const clickedHeader = headers[columnIndex];
const currentSort = clickedHeader.getAttribute('aria-sort');
const newDirection = currentSort === 'ascending' ? 'descending' :
currentSort === 'descending' ? 'ascending' : 'ascending';
headers.forEach(h => h.setAttribute('aria-sort', 'none'));
clickedHeader.setAttribute('aria-sort', newDirection);
rows.sort((a, b) => {
const aVal = a.children[columnIndex].textContent.trim();
const bVal = b.children[columnIndex].textContent.trim();
const numA = parseFloat(aVal);
const numB = parseFloat(bVal);
const compare = isNaN(numA) || isNaN(numB)
? aVal.localeCompare(bVal)
: numA - numB;
return newDirection === 'ascending' ? compare : -compare;
});
rows.forEach(row => tbody.appendChild(row));
}
Common Mistakes
1. Missing responsive container
Without overflow-x: auto, the table breaks the layout on mobile.
2. Sort buttons not accessible
Buttons inside th must be focusable, keyboard-operable, and have visible focus indicators.
3. No summary for complex tables
Complex tables need a summary description explaining the structure.
4. Inconsistent sort indicators
Visual sort indicators must match aria-sort values. Arrow direction must be consistent.
5. No row hover or stripe styles
Visual striping or hover helps all users track rows across columns.
Practice Questions
1. What is the minimum data table needs for accessibility? Caption, th with scope, thead/tbody, and proper associations for complex cells.
2. How do sortable headers communicate state to screen readers? Via aria-sort on the th element (ascending, descending, none).
3. What responsive pattern preserves table accessibility on mobile? Horizontal scroll wrapper with min-width and sticky first column.
Challenge: Extend the table with row hover highlighting, zebra striping, and a sticky first column for mobile scrolling.
FAQ
Mini Project
Build a complete data table for an admin dashboard showing user accounts. Include sortable columns (name, email, role, status, last login), responsive scrolling, and proper ARIA.
What's Next
Now explore Accessible Images to learn how to make images and graphics accessible.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro