Components

Raw
GuidancelatestWCAG 2.2 (October 2023)Retrieved 2026-05-12

Component Accessibility — WCAG 2.2

Source: www.w3.org/TR/WCAG22/ §2.5.5, §2.5.8, §4.1.2


Quick reference

CriterionRequirementValueLevel
2.5.5Touch/pointer target size (enhanced)44×44 CSS pxAAA
2.5.8Touch/pointer target size (minimum, New in 2.2)24×24 CSS pxAA
4.1.2Name and role programmatically determinable; states programmatically settableA

2.5.5 Target Size (Enhanced) — Level AAA

The size of the pointer target is at least 44×44 CSS pixels, except when:

  • An equivalent control on the same page meets the size requirement
  • The target is inline within a sentence or block of text
  • The size is determined by the user agent and not modified by the author
  • A particular presentation is essential to the information conveyed

Note: AAA is aspirational. Most products target AA (2.5.8). The 44×44px threshold originates from Apple's Human Interface Guidelines and WCAG's research into minimum touch target sizes for motor-impaired users.


2.5.8 Target Size (Minimum) — Level AA (New in WCAG 2.2)

The size of the pointer target is at least 24×24 CSS pixels, except when:

  • Spacing: An undersized target (< 24×24px) is positioned so that a 24px-diameter circle centered on its bounding box does not intersect another target's circle — i.e., insufficient-sized targets are spaced far enough apart
  • Equivalent: The function is available through another control on the same page that meets this criterion
  • Inline: The target is in a sentence or its size is constrained by surrounding line height
  • User agent: Size is browser-controlled and not modified by the author
  • Essential: A specific presentation is required

Implementation notes:

  • Minimum AA target: 24×24 CSS px on the interactive area (not just the visible icon)
  • Best practice AA target: 44×44 CSS px (the AAA threshold is the industry-standard recommendation)
  • Use padding to expand the interactive area without changing the visual size:
    button {
      min-height: 44px;
      min-width: 44px;
      padding: 10px 16px;
    }
    
  • Icon buttons (close, menu, expand): wrap in a minimum 44×44px clickable area even if the icon is 20×20px
  • Inline links within body text are exempt (the spacing exception applies)
  • Touch targets in dense data tables may use the spacing exception if rows are clearly separated

4.1.2 Name, Role, Value — Level A

For all user interface components, the name and role can be programmatically determined; states, properties, and values that can be set by the user can be programmatically set; and notification of changes to these items is available to user agents, including assistive technologies.

Three requirements in one criterion:

  1. Name: Every interactive element has an accessible name. Screen readers announce this name when the component receives focus.
  2. Role: The component's function is exposed via semantics (HTML element role or ARIA role attribute).
  3. State/value: Dynamic properties (checked, expanded, selected, disabled, required, invalid) are programmatically exposed and updated when they change.

Accessible name sources (in precedence order)

SourceExampleNotes
aria-labelledby<div aria-labelledby="label-id">Highest priority; references another element's text
aria-label<button aria-label="Close dialog">Use when no visible label exists
HTML <label><label for="email">Email</label>Standard for form inputs
title attribute<input title="Search">Avoid — poor AT support, creates tooltip
Element content<button>Save</button>Implicit for buttons and links
alt attribute<img alt="Logo">For images that convey information

Rule: Never rely solely on visual placement or color to convey a component's name. An icon-only button with no aria-label has no accessible name.


Role assignment

Use semantic HTML elements first — they carry implicit roles:

HTML elementImplicit ARIA role
<button>button
<a href>link
<input type="checkbox">checkbox
<input type="text">textbox
<select>listbox
<nav>navigation
<main>main
<header>banner

When building custom components with non-semantic elements, assign the role explicitly:

<div role="button" tabindex="0" aria-label="Open menu">...</div>

State exposure

Dynamic state must be communicated through ARIA attributes — CSS class changes alone are not sufficient.

StateARIA attributeExample
Expanded/collapsedaria-expandedAccordion, dropdown, disclosure
Selectedaria-selectedTabs, listbox options
Checkedaria-checkedCustom checkbox, toggle
Pressedaria-pressedToggle button
Disabledaria-disabled or HTML disabledAny interactive element
Requiredaria-required or HTML requiredForm fields
Invalidaria-invalidForm validation state
Live updatesaria-live + aria-atomicStatus messages, notifications

Update states in JavaScript when they change — not just on initial render:

// When accordion opens:
button.setAttribute('aria-expanded', 'true');

// When form field fails validation:
input.setAttribute('aria-invalid', 'true');
input.setAttribute('aria-describedby', 'error-message-id');

Common violations

  • Icon buttons without labels: <button><svg>...</svg></button> — add aria-label
  • Custom dropdowns with no ARIA: Visual dropdown styled from div with no role="combobox" or role="listbox"
  • State not updated on change: Toggle button that changes visually but aria-pressed is never set
  • Form fields with no label: <input placeholder="Email"> — placeholder is not a label; <label> is required
  • Modal without role="dialog": Custom modal overlay with no role, no aria-labelledby, no focus trap