WEBDEVMASTERS
Perceivable and operable

Accessibility as interface engineering

Use native semantics, robust accessible names, predictable focus, and repeatable keyboard tests before adding ARIA or custom interaction.

A clear hierarchy of page landmarks and controls
Accessibility begins with the same document relationships that make an interface understandable to every browser user.

Build on the native baseline

Native HTML controls carry roles, states, keyboard behavior, focusability, and platform conventions. A button activates from keyboard and pointer; an anchor with an href navigates and exposes link semantics; a labeled input participates in form behavior. Rebuilding those contracts on a generic element means recreating all of them—and maintaining the result across browsers and assistive technologies.

Start by matching the element to the action. Use a link to move to a resource and a button to change the current interface. Use headings as a navigable outline, lists for collections, tables for relationships between row and column headers, and disclosure elements when they meet the interaction. The semantic HTML guide provides the source-order and form patterns behind this baseline.

<button type="button" aria-expanded="false" aria-controls="filters">
  Filters
</button>
<section id="filters" hidden>
  <h2>Filter guides</h2>
  <!-- labeled controls -->
</section>

Here ARIA exposes the button’s expanded state and relationship to the controlled region; it does not replace the button. JavaScript must keep aria-expanded and hidden synchronized with visible behavior.

Give every control a durable name and state

An accessible name answers “what is this?” in the accessibility tree. Visible text is the most robust source because it serves everyone. A form input should usually receive its name from a label. An icon-only button needs a concise name through visible text hidden visually or an appropriate ARIA label. Image alternative text should express the image’s purpose in context, not list visual details that do not affect the task.

State must also be exposed. A toggle communicates whether it is pressed or expanded; a current navigation item can identify the current page; invalid inputs connect to useful error text. Do not put a changing state only in color or only in an icon. Keep the visible wording and programmatic state consistent.

EntityAttributePreferred valueManual check
ButtonNameVisible action textRead controls list out of context
InputLabelPersistent, associated labelClick label; inspect accessibility tree
StatusAnnouncementConcise live-region update when neededTrigger change with screen reader
ImageAlternativePurpose in surrounding contextHide image and read sentence
ErrorRecoveryProblem plus correctionSubmit invalid data and retry

Make the keyboard path predictable

Keyboard accessibility requires more than reaching controls. Focus order should preserve meaning, the current focus indicator must remain visible, and focus must not become trapped. Avoid positive tabindex values because they create a second ordering system that is hard to maintain. Keep DOM order logical and use tabindex="-1" only when script must focus a normally non-tabbable target, such as an error summary.

Dialogs require deliberate focus management: move focus into the opened dialog, constrain interaction while it is modal, close on the expected action including Escape where appropriate, and return focus to the opener. Prefer the native dialog element when it meets support and design requirements, but still test its actual workflow.

const opener = document.querySelector("[data-open-dialog]");
const dialog = document.querySelector("dialog");

opener.addEventListener("click", () => dialog.showModal());
dialog.addEventListener("close", () => opener.focus());

Do not move focus simply because content updated. If a search count changes, announce the status without stealing the cursor. If form submission fails, focusing a linked error summary may help the user understand and navigate the problems. Context determines the correct transition.

Support visual, auditory, and cognitive perception

Text and essential interface elements need sufficient contrast under the applicable WCAG criterion. A focus indicator must be visible against adjacent colors. Instructions should not rely only on position, shape, or color. Captions and transcripts serve time-based media. Zoom and text resizing should reflow without clipping or hiding actions.

Respect prefers-reduced-motion when animation is not essential, and avoid movement that blocks reading or creates vestibular discomfort. Reduced motion is not necessarily “no transition”; it means removing or simplifying nonessential spatial movement while preserving understandable state changes.

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .panel { transition: none; }
}

Use a layered test matrix

Minimum repeatable review

  1. Keyboard: complete the primary task with Tab, Shift+Tab, Enter, Space, arrow keys where conventional, and Escape where applicable.
  2. Zoom and reflow: inspect at 200% zoom and a narrow viewport; look for clipping, overlaps, and hidden controls.
  3. Accessibility tree: inspect names, roles, states, headings, and landmarks in browser tools.
  4. Screen reader: test the critical path with at least one supported browser and screen-reader pairing.
  5. Automation: run an accessibility scanner and targeted component tests, then triage rather than equating zero findings with completion.

Record the task, environment, result, and unresolved risk. Accessibility defects often cross layers: a wrong source order belongs in HTML; a low-contrast state belongs in CSS; a stale announcement belongs in JavaScript. Fix the owning layer and rerun the entire task, not only the isolated rule.

Sources and further reading

These references support the standards and factual claims in this guide. The decision frameworks and worked examples are original editorial synthesis.

  1. W3C: WCAG 2 Overview
  2. W3C: How to Meet WCAG
  3. MDN: HTML accessibility
  4. MDN: ARIA

Questions practitioners ask

Does passing an automated scan make a page accessible?

No. Automated checks find important classes of issues, but they cannot confirm that a workflow makes sense, focus moves predictably, names are useful, or instructions are understandable.

Should every element receive a tabindex?

No. Native interactive controls already participate in focus order. Adding tabindex to static content creates extra stops and can obscure the meaningful path.

When is ARIA appropriate?

Use ARIA when HTML lacks the required semantics or when dynamic state must be exposed. Prefer a native element when one already supplies the role, states, and keyboard behavior.