Jede künftige UI-Änderung entwickelt Barrierefreiheit direkt mit (Stefans Vorgabe nach Abschluss des WCAG-2.1-AA-Audits): verbindliche Checkliste als ADR, Kurzfassung in CLAUDE.md für jede Dev-Session, Eintrag im ADR-Index. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AGM8jo3hwoV9wsCVGfy8iq
3.6 KiB
ADR 0017: Accessibility (WCAG 2.1 AA) as a default requirement
- Status: accepted
- Date: 2026-07-21
Context
A full WCAG 2.1 AA audit (July 2026) found a solid baseline — enforced
accessible names on IconButton, the implicitly labelling Field
primitive, localized ARIA labels, a clean landmark structure — but also
systemic gaps that had accumulated because accessibility was checked
after the fact rather than built in: dialogs without focus management, a
hard-coded document language, broken listbox semantics, page-level
horizontal scrolling at 320 px viewport width. All findings were fixed in
issues #162–#171; an axe-core smoke pack (apps/web/e2e/a11y.spec.ts)
now pins the core screens in CI.
Retro-fitting accessibility is far more expensive than building it in. This ADR makes it a default requirement for every future feature.
Decision
Every user-facing change ships accessible. Concretely, a feature is not done until it satisfies this checklist:
- Reuse the accessible primitives. Icon-only controls go through
IconButton(enforces a name); form controls go throughField(label +aria-describedby/aria-invalidwiring); dialogs useuseModalFocus(focus trap, initial focus, focus return) plusaria-labelledbyon their heading. Do not hand-roll parallels. - Keyboard first. Everything reachable and operable by keyboard,
visible focus, Escape closes overlays, no focus loss on unmount. New
single-key shortcuts must respect the "disable single-key shortcuts"
setting (
lib/single-key-shortcuts.ts). - Name, role, value. New widgets carry correct roles and
localized (de+en) accessible names; state via
aria-expanded,aria-selected,aria-pressedetc. Decorative icons stayaria-hidden. - Both render paths. Anything that renders content must behave
identically in the editor/NodeView path AND the
docToHtml/server path (public view, comments, previews) — including labels and list semantics. Remember:page_content_cacherolls outdocToHtmlchanges lazily (on next persist). - Color and contrast. Use the design tokens; text ≥ 4.5:1, UI
boundaries and icons ≥ 3:1 (
--color-border-inputexists for field borders;--color-favoriteis icon-only). Color is never the only cue. Dark-rendered surfaces (public shell) keep their checked colors. - Reflow. New layouts must not force page-level horizontal
scrolling at 320 px (flex/grid children need
min-width: 0; intrinsically wide content scrolls in its own focusable container). - Motion and time. Respect
prefers-reduced-motion; no auto-updating or auto-dismissing content faster than users can perceive it. - Extend the CI pack. A new core screen or a new interaction
pattern gets added to
apps/web/e2e/a11y.spec.ts(axe, WCAG A/AA tags, empty allowlist — additions to the allowlist need a written justification in the spec).
Code review and issue acceptance criteria treat violations of this checklist like functional defects, not polish.
Consequences
- New features cost slightly more up front and no longer accumulate an accessibility backlog; the July 2026 audit stays the last big one.
- The axe CI pack fails builds on regressions of the fixed state; specs
may need locator updates when accessible names are added (a11y labels
can make
getByLabelmatchers ambiguous — scope them). - The full audit report (methodology, per-criterion matrix, measurement
harness) lives in the operator's workspace
(
doku/audit-barrierefreiheit-2026-07.md) and can be re-run after larger UI changes.