Data Tables

Create accessible data tables with proper headers, captions, and semantic structure for screen reader users.

beginner
1.3.1 Info and Relationships (Level A)4.1.2 Name, Role, Value (Level A)2.4.6 Headings and Labels (Level AA)
❌

The Bad (Inaccessible)

<div class="table">
  <div class="row">
    <div class="cell header">Name</div>
    <div class="cell header">Email</div>
  </div>
  <div class="row">
    <div class="cell">John Doe</div>
    <div class="cell">john@example.com</div>
  </div>
</div>
βœ…

Accessibility-Ready Code

<!-- Gold Standard: Semantic table with proper structure -->
<table class="data-table">
  <caption>
    Company Employees
    <span class="sr-only">
      - A list of employee names, emails, and roles
    </span>
  </caption>

  <thead>
    <tr>
      <th scope="col">Name</th>
      <th scope="col">Email</th>
      <th scope="col">Department</th>
      <th scope="col">Role</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <th scope="row">John Smith</th>
      <td><a href="mailto:john@example.com">john@example.com</a></td>
      <td>Engineering</td>
      <td>Senior Developer</td>
    </tr>
    <tr>
      <th scope="row">Sarah Johnson</th>
      <td><a href="mailto:sarah@example.com">sarah@example.com</a></td>
      <td>Design</td>
      <td>UX Designer</td>
    </tr>
    <tr>
      <th scope="row">Mike Williams</th>
      <td><a href="mailto:mike@example.com">mike@example.com</a></td>
      <td>Marketing</td>
      <td>Marketing Manager</td>
    </tr>
    <tr>
      <th scope="row">Emily Brown</th>
      <td><a href="mailto:emily@example.com">emily@example.com</a></td>
      <td>Engineering</td>
      <td>Junior Developer</td>
    </tr>
  </tbody>

  <tfoot>
    <tr>
      <td colspan="4">
        Total: 4 employees across 3 departments
      </td>
    </tr>
  </tfoot>
</table>

The Standard

Data tables present tabular data with proper semantic structure. Use native HTML table elements for accessibility, not CSS layouts that look like tables.

WCAG Criteria

  • 1.3.1 Info and Relationships: Semantic table structure.
  • 4.1.2 Name, Role, Value: Proper table roles.
  • 2.4.6 Headings and Labels: Clear captions and headers.

❌ The Bad (Inaccessible)

What’s Wrong?

  1. Using div for layout: Screen readers can’t navigate as a table.
  2. No caption: No context for table contents.
  3. Missing scope: Screen reader can’t map headers.
  4. Using tables for layout: Confusing for screen readers.

βœ… The Good (Accessibility-Ready Code)

Why This Works

  1. Semantic <table>: Creates a table landmark for screen readers.
  2. Caption: Provides context for all users.
  3. scope Attributes: Maps headers to data cells.
  4. Row Headers: scope="row" for the first column header.

Accessibility Checklist

  • Use <table> for tabular data, not layout.
  • Always include a <caption> describing the table.
  • Use <thead> and <tbody> to structure sections.
  • Add scope="col" to column headers.
  • Add scope="row" to row headers (first column).
  • Use <th> for headers, <td> for data cells.
  • Include <tfoot> for summary rows if applicable.
πŸ“ Perfect Implementation Reference
<table>
  <caption>
    Monthly Sales Report
    <span class="sr-only">
      - Sales by product and region
    </span>
  </caption>

  <thead>
    <tr>
      <th scope="col">Product</th>
      <th scope="col">Q1</th>
      <th scope="col">Q2</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <th scope="row">Widget A</th>
      <td>$10,000</td>
      <td>$12,000</td>
    </tr>
  </tbody>
</table>

<style>
  .sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
  }
</style>

Technical Deep Dive

Screen Reader Announcements

  • NVDA: β€œTable with 4 columns and 4 rows, John Smith, row 1, column 1, Email”
  • VoiceOver: β€œCompany Employees, table, 4 columns, 4 rows”
  • JAWS: β€œCompany Employees, table, John Smith, row 1, column 1, Email link”

Best Practice: Tables vs. Layout Grids

Only use <table> for tabular data relationships, not for layout. When you have complex data with multiple levels of headers, use the headers attribute to explicitly associate each cell with all applicable headers. Use scope="col" for simple column headers and scope="row" for row headers in the first column.

πŸ§ͺ

Interactive Behavioral Lab

πŸ’»

Interactive Sandbox

LIVE PREVIEW

πŸ”¬ Technical Internals

Understand how this component is processed by the browser and Assistive Technology (AT). This section bridges the gap between visual code and the hidden logic that powers accessibility.

🌲 Accessibility Tree

The data structure used by screen readers to "see" your page. It translates HTML roles and attributes into standardized objects.

βš™οΈ Event Logic

Expected behavioral standards for keyboard navigation and state transitions. Crucial for users who don't use a mouse.

  • Focus: Highlights via :focus-visible
  • Activation: Responds to Enter and Space
  • Role: Identified as Table

🌐 Browser & Screen Reader Compatibility

Browser
Screen Reader
Status
🍎 Safari
VoiceOver
βœ“ Safe
πŸͺŸ Chrome
NVDA
βœ“ Safe
πŸͺŸ Edge
JAWS
βœ“ Safe
🦊 Firefox
NVDA
βœ“ Safe
πŸ“± iOS Safari
VoiceOver
βœ“ Safe
πŸ€– Chrome Android
TalkBack
βœ“ Safe