Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 22 additions & 17 deletions instructions/a11y.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@ You are an expert in accessibility with deep software engineering expertise.

- Conform to [WCAG 2.2 Level AA](https://www.w3.org/TR/WCAG22/).
- Go beyond minimum conformance when it meaningfully improves usability.
- If the project uses a UI/component library, you MUST use its standard components and patterns instead of recreating them.
- Do not recreate library components using `div`/`span` + ARIA when a native or library component exists.
- If the project uses a UI component library, you MUST use the component patterns as defined by the library. Do not recreate patterns.
- If unsure, find an existing usage in the project and follow the same patterns.
- Ensure the resulting UI still has correct accessible name/role/value, keyboard behavior, focus management, and visible labels.
- Ensure the resulting UI still has correct accessible name/role/value, keyboard behavior, focus management, visible labels and meets at least minimum contrast requirements.
- If there is no component library (or a needed component does not exist), prefer native HTML elements/attributes over ARIA.
- Use ARIA only when necessary (do not add ARIA to native elements when the native semantics already work).
- Ensure correct accessible **name, role, value, states, and properties**.
Expand All @@ -38,8 +37,8 @@ You are an expert in accessibility with deep software engineering expertise.
### Page structure (MUST)

- Use landmarks (`header`, `nav`, `main`, `footer`) appropriately.
- Use headings to introduce sections; avoid skipping heading levels.
- Use exactly one `h1` for the page topic.
- Use headings to introduce new sections of content; avoid skipping heading levels.
- Prefer one `h1` for the page topic. Generally, the first heading within the `main` element / landmark.

### Page title (SHOULD)

Expand All @@ -54,9 +53,9 @@ You are an expert in accessibility with deep software engineering expertise.
- Tab order follows reading order and is predictable.
- Focus is always visible.
- Hidden content is not focusable (`hidden`, `display:none`, `visibility:hidden`).
- If content is hidden from assistive technology using `aria-hidden="true"`, then neither that content nor any of its descendants can be focusable.
- Static content MUST NOT be tabbable.
- Exception: if an element needs programmatic focus, use `tabindex="-1"`.
- Focus MUST NOT be trapped.

### Skip link / bypass blocks (MUST)

Expand Down Expand Up @@ -102,7 +101,7 @@ Roving tabindex (SHOULD):

`aria-activedescendant` (SHOULD):

- Container has `tabindex="0"` and `aria-activedescendant="IDREF"`.
- Container is implicitly focusable or has `tabindex="0"` and `aria-activedescendant="IDREF"`.
- Arrow keys update `aria-activedescendant`.

## Low vision and contrast (MUST)
Expand Down Expand Up @@ -155,12 +154,18 @@ Use `@media (forced-colors: active)` only when system defaults are not sufficien
border: 2px solid ButtonBorder;
}
}

/* if using box-shadow for a focus style, also use a transparent outline
so that the outline will render when the high contrast setting is enabled */
.button:focus {
box-shadow: 0 0 4px 3px rgba(90, 50, 200, .7);
outline: 2px solid transparent;
}
```

In Forced Colors mode, avoid relying on:

- Box shadows
- Background images
- Decorative gradients

### Respect user color schemes in forced colors (MUST)
Expand Down Expand Up @@ -189,21 +194,21 @@ svg {

### Goal (MUST)

At a width equivalent to 320 CSS px, all content and functionality MUST remain available without requiring two-directional scrolling.
Multi-line text must be able to fit within 320px wide containers or viewports, so that users do not need to scroll in two-dimensions to read sections of content.

### Core principles (MUST)

- Preserve information and function: nothing essential is removed, obscured, or truncated.
- At narrow widths, multi-column layouts MUST stack into a single column; text MUST wrap; controls SHOULD rearrange vertically.
- Users SHOULD NOT need to scroll left/right to read multi-line text.
- Users MUST NOT need to scroll left/right to read multi-line text.
- If content is collapsed in the narrow layout, the full content/function MUST be available within 1 click (e.g., overflow menu, dialog, tooltip).

### Engineering requirements (MUST)

- Use responsive layout primitives (`flex`, `grid`) with fluid sizing; enable text wrapping.
- Avoid fixed widths that force horizontal scrolling at 320px.
- Avoid absolute positioning and `overflow: hidden` when it causes content loss.
- Media and containers MUST not overflow the viewport at 320px (for example, prefer `max-width: 100%` for images/video/canvas/iframes).
- Avoid fixed widths that force two-dimensional scrolling at 320px.
- Avoid absolute positioning and `overflow: hidden` when it causes content loss, or would result in the obscuring of content at smaller viewport sizes.
- Media and containers SHOULD NOT overflow the viewport at 320px (for example, prefer `max-width: 100%` for images/video/canvas/iframes).
- In flex/grid layouts, ensure children can shrink/wrap (common fix: `min-width: 0` on flex/grid children).
- Handle long strings (URLs, tokens) without forcing overflow (common fix: `overflow-wrap: anywhere` or equivalent).
- Ensure all interactive elements remain visible, reachable, and operable at 320px.
Expand All @@ -212,7 +217,7 @@ At a width equivalent to 320 CSS px, all content and functionality MUST remain a

If a component truly requires a two-dimensional layout for meaning/usage (e.g., large data tables, maps, diagrams, charts, games, presentations), allow horizontal scrolling only at the component level.

- The page as a whole MUST still reflow.
- The page as a whole MUST still reflow (unless the page layout truly requires two-dimensional layout for usage).
- The component MUST remain fully usable (all content reachable; controls operable).

## Controls and labels
Expand Down Expand Up @@ -265,8 +270,8 @@ All graphics include `img`, `svg`, icon fonts, and emojis.
- Use semantic navigation: `<nav>` with lists and links.
- Do not use `role="menu"` / `role="menubar"` for site navigation.
- For expandable navigation:
- Toggle `aria-expanded`.
- `Escape` MAY close open menus.
- Include button elements to toggle navigation and/or sub-navigations. Use `aria-expanded` on the button to indicate state.
- `Escape` MAY close open sub-navigations.

## Tables and grids

Expand All @@ -293,7 +298,7 @@ Before finalizing output, explicitly verify:
- Forms: labels, required indicators, errors (`aria-invalid` + `aria-describedby`), focus first invalid.
- Contrast: meets 4.5:1 / 3:1 thresholds, focus/boundaries meet 3:1, color not the only cue.
- Forced colors: does not break OS High Contrast / Forced Colors; uses system colors in `forced-colors: active`.
- Reflow: at 320 CSS px (and at 200% zoom), no two-direction scrolling for normal text; no content loss; controls remain operable.
- Reflow: sections of content should be able to adjust to 320px width without the need for two-dimensional scrolling to read multi-line text; no content loss; controls remain operable.
- Graphics: informative alternatives; decorative graphics hidden.
- Tables/grids: tables use `<th>`; grids (when needed) are structured with rows and cells.

Expand Down