77 lines
3.4 KiB
Markdown
77 lines
3.4 KiB
Markdown
---
|
|
name: web-accessibility
|
|
description: Use when building or reviewing any user-facing web page/UI. Baseline WCAG-aligned accessibility practices to apply by default, not just when explicitly requested.
|
|
---
|
|
|
|
# Web Accessibility
|
|
|
|
Apply these by default on any real user-facing page — accessibility
|
|
issues are usually cheap to avoid at build time and expensive to retrofit.
|
|
|
|
## Semantic HTML first
|
|
|
|
Use the element that actually means what you're building, before
|
|
reaching for ARIA to patch a `<div>` into behaving like something else:
|
|
`<button>` for actions (not a `<div onclick>`), `<a href>` for
|
|
navigation, real heading levels (`<h1>`-`<h6>`) in a logical, non-skipped
|
|
order, `<nav>`/`<main>`/`<footer>`/`<article>` landmarks. A page built
|
|
from semantic elements gets most of its accessibility for free; a page
|
|
built entirely from `<div>`s needs everything added back manually via
|
|
ARIA, which is more work and easier to get subtly wrong.
|
|
|
|
## Images and media
|
|
|
|
- Every meaningful `<img>` needs real, specific `alt` text (not the
|
|
filename, not "image123") — describe what the image conveys, not that
|
|
it's an image.
|
|
- Purely decorative images: `alt=""` (empty, not omitted) so screen
|
|
readers skip them silently instead of reading a filename.
|
|
- Video/audio with meaningful content needs captions/transcripts.
|
|
|
|
## Keyboard navigation
|
|
|
|
- Everything clickable must be reachable and operable via keyboard alone
|
|
(Tab to focus, Enter/Space to activate) — test this literally, don't
|
|
assume a `<button>` or `<a>` is automatically fine (it usually is;
|
|
custom interactive widgets built from other elements usually aren't
|
|
without explicit `tabindex`/keydown handling).
|
|
- Visible focus indicators — never `outline: none` without providing a
|
|
real, visible replacement focus style. Removing focus indicators
|
|
entirely is a common and serious accessibility regression.
|
|
- Logical tab order matching visual/reading order.
|
|
|
|
## Color and contrast
|
|
|
|
- Text contrast ratio ≥ 4.5:1 for normal text, ≥ 3:1 for large text
|
|
(WCAG AA). Check this for real against the actual rendered colors, not
|
|
just "looks readable to me" — subtle brand colors on dark backgrounds
|
|
are a common failure point.
|
|
- Never convey information (an error state, a required field, a status)
|
|
through color alone — pair it with text, an icon, or a pattern.
|
|
|
|
## Forms
|
|
|
|
- Every input has a programmatically-associated `<label>` (via `for`/
|
|
`id`, or wrapping) — not just visual proximity.
|
|
- Error messages are associated with their field (`aria-describedby`) and
|
|
announced to assistive tech, not just visually styled red text.
|
|
- Required fields marked both visually and via the `required` attribute
|
|
or `aria-required`.
|
|
|
|
## ARIA: use sparingly, and correctly
|
|
|
|
ARIA attributes override the browser's default accessibility mapping —
|
|
using them incorrectly can make a page *less* accessible than using no
|
|
ARIA at all. The first rule of ARIA is "don't use ARIA if a native HTML
|
|
element already does what you need." When you do need it (custom
|
|
widgets: a modal, a tab panel, a combobox), match the established ARIA
|
|
Authoring Practices pattern for that widget type rather than improvising.
|
|
|
|
## Quick self-check before calling something accessible
|
|
|
|
- Can you operate the whole page with only a keyboard?
|
|
- Does every image have appropriate alt text?
|
|
- Do headings form a logical outline (one `<h1>`, nested levels not
|
|
skipped)?
|
|
- Does removing all color (grayscale) still leave the page understandable?
|