Accessibility (WCAG 2.1 AA)

Every TableCrafter table ships WCAG 2.1 AA accessibility by default: 44px touch targets, semantic ARIA labels, live screen reader announcements, full keyboard navigation, and automatic high contrast and reduced motion support. No extra shortcode attributes are required.

44px Touch Targets ARIA Labels Screen Readers Keyboard Navigation High Contrast

Overview

Accessibility is built into the TableCrafter rendering engine rather than bolted on as an option. Whether you render a table through the [tablecrafter] shortcode, the Gutenberg block, or the Elementor widget, the same accessibility layer applies. Tables are rendered server-side with valid HTML table markup, then enhanced on the client with ARIA roles, live regions, and keyboard handlers.

The accessibility subsystem is enabled by default and covers six areas: semantic ARIA structure, screen reader announcements, keyboard navigation, focus management, touch target sizing, and respect for user system preferences (high contrast and reduced motion).

ℹ️

There is no accessibility="true" attribute to set. Accessibility features activate automatically on every table. This page documents the real behavior so you can verify, theme around, and test it.

Semantic Markup and ARIA

The server-rendered table uses standard, crawlable HTML: <table>, <thead>, <tbody>, <th>, and <td>. The client layer then enhances it with ARIA so assistive technology can describe the grid accurately.

Attribute / RoleApplied toPurpose
scope="col"Header cells (<th>)Associates each header with its column for screen readers.
role="columnheader"Header cellsIdentifies sortable column headers in the grid.
aria-sortSortable headersReports the current sort state: none, ascending, or descending. Rendered server-side and kept in sync on the client.
role="gridcell"Data cells (<td>)Identifies interactive data cells within the table.
aria-labelTable, search, pagination, sortable headers, editable cellsProvides descriptive labels (translatable via the plugin i18n layer).
aria-describedbyTable elementPoints to a visually hidden summary of row count, column count, and available features.
aria-current="page"Current pagination buttonMarks the active page in the pager.
aria-busy="true"Loading containerSignals that data is loading so screen readers announce the busy state.
role="searchbox"Search inputIdentifies the live search field.
role="navigation"Pagination wrapperExposes the pager as a navigation landmark.

The server-rendered header markup looks like this, so the correct sort state and focusability are present even before JavaScript runs:

<th class="tc-sortable" tabindex="0" aria-sort="none" data-field="price">Price</th>

Screen Reader Support

TableCrafter injects a visually hidden ARIA live region (the announcer) into the page so that dynamic changes are spoken without moving focus. The announcer uses aria-live and aria-atomic="true", with a default politeness of polite and a short delay before each announcement so it is reliably picked up.

Announcements fire automatically for the operations users care about:

When a sortable header receives focus, the announcer also reads the column name, its current sort state, and the activation hint ("Press Enter or Space to sort"), giving non-visual users the same context a sighted user gets from the arrow indicator.

Keyboard Navigation

The entire table is operable without a mouse. The container is made focusable, and a keyboard handler maps standard keys to grid actions. Sortable headers carry tabindex="0" so they are reachable in the normal tab order.

KeyAction
Tab / Shift+TabMove between interactive elements (search, headers, pager, controls).
Arrow Up / DownMove focus vertically between cells in the same column.
Arrow Left / RightMove focus horizontally between cells in the same row.
Home / EndJump to the first or last cell in the current row.
Page Up / Page DownGo to the previous or next page when focus is within the pager.
Enter / SpaceActivate the focused element — sort a header, trigger a pagination button, or begin editing an editable cell.
EscapeCancel an in-progress edit, close an open modal, or clear the search field.
Ctrl+F / Cmd+FMove focus directly to the table search input.

Arrow-key and Home/End navigation only intercept keys while focus is inside the table, so they never hijack the rest of the page. Outside the table, default browser behavior is preserved.

Focus Management and Indicators

Focus is tracked as it enters and leaves elements, and a high-visibility indicator is applied so keyboard users always know where they are. The default focus ring is a 3px solid outline (#005fcc) with a 2px offset, exceeding the AA non-text contrast requirement against typical table backgrounds.

Context-specific focus styling helps distinguish element types:

You can re-theme these states by overriding the focus rules. They are applied with !important to survive aggressive theme resets, so use an equally specific selector:

/* Override the default focus ring */
.tc-wrapper *:focus {
  outline: 3px solid #1a7f37 !important;
  outline-offset: 2px !important;
}

Touch Targets (44px Minimum)

On touch and mobile contexts, all interactive controls meet the WCAG 2.5.5 target-size guidance with a 44px minimum. This applies to sortable headers, pagination buttons, filter inputs and selects, the export control, and bulk-action buttons. The rules are scoped both to mobile breakpoints and to any coarse-pointer device via the @media (pointer: coarse) query, so a touchscreen laptop benefits too.

On mobile, tables reflow into a card layout that is also fully accessible: the card container is exposed as role="list" and each card as role="listitem", so screen readers announce the data as a navigable list rather than a broken table.

ℹ️

Filter and search inputs use a 16px font size on mobile specifically to prevent iOS Safari from auto-zooming when the field is focused — a small but important usability detail for touch users.

High Contrast and Reduced Motion

TableCrafter detects user system preferences at runtime and re-applies them if they change mid-session, without a page reload.

The plugin also includes baseline color-contrast tuning for sortable and editable cells and support for text scaling up to 200% via word-wrapping rules, so zoomed layouts do not clip content.

If you need high contrast on all the time for a specific deployment, you can add the class to the wrapper yourself:

/* Force high-contrast styling regardless of OS setting */
.tc-wrapper {
  /* add the tc-high-contrast class via a small JS snippet or filter */
}

Verifying Accessibility on Your Site

A standard table needs nothing special to be accessible:

[tablecrafter source="https://api.example.com/products.json" search="true" per_page="10"]

To confirm compliance after embedding a table:

  1. Keyboard pass: Tab into the table, sort a column with Enter, page with Page Up / Page Down, and clear the search with Escape — all without a mouse.
  2. Screen reader pass: with VoiceOver, NVDA, or JAWS active, sort and search and confirm the announcer reads the new state and result counts.
  3. Contrast pass: enable your OS high-contrast / increased-contrast setting and reload to confirm the high-contrast styling engages.
  4. Touch pass: on a phone or with device emulation, verify controls are at least 44px and the table reflows into accessible cards.
⚠️

Aggressive theme CSS or third-party "table styler" plugins can strip the focus outline or shrink touch targets. If an audit flags missing focus rings or small targets, check for a theme rule overriding .tc-wrapper *:focus or the min-height: 44px declarations before assuming a plugin issue.

Next, see mobile-responsive.html for how the card reflow and touch gestures work, and sorting.html for the keyboard and aria-sort behavior on sortable columns.