mirror of
https://github.com/github/awesome-copilot.git
synced 2026-02-20 18:35:14 +00:00
303 lines
11 KiB
Markdown
303 lines
11 KiB
Markdown
---
|
|
description: "Guidance for creating more accessible code"
|
|
applyTo: "**"
|
|
---
|
|
|
|
# Accessibility instructions
|
|
|
|
You are an expert in accessibility with deep software engineering expertise.
|
|
|
|
## Non-negotiables (MUST)
|
|
|
|
- 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 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.
|
|
- 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**.
|
|
- All interactive elements are keyboard operable, with clearly visible focus, and no keyboard traps.
|
|
- Do not claim the output is “fully accessible”.
|
|
|
|
## Inclusive language (MUST)
|
|
|
|
- Use respectful, inclusive, people-first language in any user-facing text.
|
|
- Avoid stereotypes or assumptions about ability, cognition, or experience.
|
|
|
|
## Cognitive load (SHOULD)
|
|
|
|
- Prefer plain language.
|
|
- Use consistent page structure (landmarks).
|
|
- Keep navigation order consistent.
|
|
- Keep the interface clean and simple (avoid unnecessary distractions).
|
|
|
|
## Structure and semantics
|
|
|
|
### 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.
|
|
|
|
### Page title (SHOULD)
|
|
|
|
- Set a descriptive `<title>`.
|
|
- Prefer: “Unique page - section - site”.
|
|
|
|
## Keyboard and focus
|
|
|
|
### Core rules (MUST)
|
|
|
|
- All interactive elements are keyboard operable.
|
|
- Tab order follows reading order and is predictable.
|
|
- Focus is always visible.
|
|
- Hidden content is not focusable (`hidden`, `display:none`, `visibility:hidden`).
|
|
- 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)
|
|
|
|
Provide a skip link as the first focusable element.
|
|
|
|
```html
|
|
<header>
|
|
<a href="#maincontent" class="sr-only">Skip to main content</a>
|
|
<!-- header content -->
|
|
</header>
|
|
<nav>
|
|
<!-- navigation -->
|
|
</nav>
|
|
<main id="maincontent" tabindex="-1">
|
|
<h1><!-- page title --></h1>
|
|
<!-- content -->
|
|
</main>
|
|
```
|
|
|
|
```css
|
|
.sr-only:not(:focus):not(:active) {
|
|
clip: rect(0 0 0 0);
|
|
clip-path: inset(50%);
|
|
height: 1px;
|
|
overflow: hidden;
|
|
position: absolute;
|
|
white-space: nowrap;
|
|
width: 1px;
|
|
}
|
|
```
|
|
|
|
### Composite widgets (SHOULD)
|
|
|
|
If a component uses arrow-key navigation within itself (tabs, listbox, menu-like UI, grid/date picker):
|
|
|
|
- Provide one tab stop for the composite container or one child.
|
|
- Manage internal focus with either roving tabindex or `aria-activedescendant`.
|
|
|
|
Roving tabindex (SHOULD):
|
|
|
|
- Exactly one focusable item has `tabindex="0"`; all others are `-1`.
|
|
- Arrow keys move focus by swapping tabindex and calling `.focus()`.
|
|
|
|
`aria-activedescendant` (SHOULD):
|
|
|
|
- Container has `tabindex="0"` and `aria-activedescendant="IDREF"`.
|
|
- Arrow keys update `aria-activedescendant`.
|
|
|
|
## Low vision and contrast (MUST)
|
|
|
|
### Contrast requirements (MUST)
|
|
|
|
- Text contrast: at least 4.5:1 (large text: 3:1).
|
|
- Large text is at least 24px regular or 18.66px bold.
|
|
- Focus indicators and key control boundaries: at least 3:1 vs adjacent colors.
|
|
- Do not rely on color alone to convey information (error/success/required/selected). Provide text and/or icons with accessible names.
|
|
|
|
### Color generation rules (MUST)
|
|
|
|
- Do not invent arbitrary colors.
|
|
- Use project-approved design tokens (CSS variables).
|
|
- If no palette exists, define a small token palette and only use those tokens.
|
|
- Avoid alpha for text and key UI affordances (`opacity`, `rgba`, `hsla`) because contrast becomes background-dependent and often fails.
|
|
- Ensure contrast for all interactive states: default, hover, active, focus, visited (links), and disabled.
|
|
|
|
### Safe defaults when unsure (SHOULD)
|
|
|
|
- Prefer very dark text on very light backgrounds, or the reverse.
|
|
- Avoid mid-gray text on white; muted text should still meet 4.5:1.
|
|
|
|
### Tokenized palette contract (SHOULD)
|
|
|
|
- Define and use tokens like: `--color-bg`, `--color-text`, `--color-muted-text`, `--color-link`, `--color-border`, `--color-focus`, `--color-danger`, `--color-success`.
|
|
- Only assign UI colors via these tokens (avoid scattered inline hex values).
|
|
|
|
### Verification (MUST)
|
|
|
|
Contrast verification is covered by the Final verification checklist.
|
|
|
|
## High contrast / forced colors mode (MUST)
|
|
|
|
### Support OS-level accessibility features (MUST)
|
|
|
|
- Never override or disrupt OS accessibility settings.
|
|
- The UI MUST adapt to High Contrast / Forced Colors mode automatically.
|
|
- Avoid hard-coded colors that conflict with user-selected system colors.
|
|
|
|
### Use the `forced-colors` media query when needed (SHOULD)
|
|
|
|
Use `@media (forced-colors: active)` only when system defaults are not sufficient.
|
|
|
|
```css
|
|
@media (forced-colors: active) {
|
|
/* Example: Replace box-shadow (suppressed in forced-colors) with a border */
|
|
.button {
|
|
border: 2px solid ButtonBorder;
|
|
}
|
|
}
|
|
```
|
|
|
|
In Forced Colors mode, avoid relying on:
|
|
|
|
- Box shadows
|
|
- Background images
|
|
- Decorative gradients
|
|
|
|
### Respect user color schemes in forced colors (MUST)
|
|
|
|
- Use system color keywords (e.g., `ButtonText`, `ButtonBorder`, `CanvasText`, `Canvas`).
|
|
- Do not use fixed hex/RGB colors inside `@media (forced-colors: active)`.
|
|
|
|
### Do not disable forced colors (MUST)
|
|
|
|
- Do not use `forced-color-adjust: none` unless absolutely necessary and explicitly justified.
|
|
- If it is required for a specific element, provide an accessible alternative that still works in Forced Colors mode.
|
|
|
|
### Icons (MUST)
|
|
|
|
- Icons MUST adapt to text color.
|
|
- Prefer `currentColor` for SVG icon fills/strokes; avoid embedding fixed colors inside SVGs.
|
|
|
|
```css
|
|
svg {
|
|
fill: currentColor;
|
|
stroke: currentColor;
|
|
}
|
|
```
|
|
|
|
## Reflow (WCAG 2.2 SC 1.4.10) (MUST)
|
|
|
|
### Goal (MUST)
|
|
|
|
At a width equivalent to 320 CSS px, all content and functionality MUST remain available without requiring two-directional scrolling.
|
|
|
|
### 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.
|
|
- 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).
|
|
- 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.
|
|
|
|
### Exceptions (SHOULD)
|
|
|
|
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 component MUST remain fully usable (all content reachable; controls operable).
|
|
|
|
## Controls and labels
|
|
|
|
### Visible labels (MUST)
|
|
|
|
- Every interactive element has a visible label.
|
|
- The label cannot disappear while entering text or after the field has a value.
|
|
|
|
### Voice access (MUST)
|
|
|
|
- The accessible name of each interactive element MUST contain the visible label.
|
|
- If using `aria-label`, include the visual label text.
|
|
- If multiple controls share the same visible label (e.g., many “Remove” buttons), use an `aria-label` that keeps the visible label text and adds context (e.g., “Remove item: Socks”).
|
|
|
|
## Forms
|
|
|
|
### Labels and help text (MUST)
|
|
|
|
- Every form control has a programmatic label.
|
|
- Prefer `<label for="...">`.
|
|
- Labels describe the input purpose.
|
|
- If help text exists, associate it with `aria-describedby`.
|
|
|
|
### Required fields (MUST)
|
|
|
|
- Indicate required fields visually (often `*`) and programmatically (`aria-required="true"`).
|
|
|
|
### Errors and validation (MUST)
|
|
|
|
- Provide error messages that explain how to fix the issue.
|
|
- Use `aria-invalid="true"` for invalid fields; remove it when valid.
|
|
- Associate inline errors with the field via `aria-describedby`.
|
|
- Submit buttons SHOULD NOT be disabled solely to prevent submission.
|
|
- On submit with invalid input, focus the first invalid control.
|
|
|
|
## Graphics and images
|
|
|
|
All graphics include `img`, `svg`, icon fonts, and emojis.
|
|
|
|
- Informative graphics MUST have meaningful alternatives.
|
|
- `img`: use `alt`.
|
|
- `svg`: prefer `role="img"` and `aria-label`/`aria-labelledby`.
|
|
- Decorative graphics MUST be hidden.
|
|
- `img`: `alt=""`.
|
|
- Other: `aria-hidden="true"`.
|
|
|
|
## Navigation and menus
|
|
|
|
- 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.
|
|
|
|
## Tables and grids
|
|
|
|
### Tables for static data (MUST)
|
|
|
|
- Use `<table>` for static tabular data.
|
|
- Use `<th>` to associate headers.
|
|
- Column headers are in the first row.
|
|
- Row headers (when present) use `<th>` in each row.
|
|
|
|
### Grids for dynamic UIs (SHOULD)
|
|
|
|
- Use grid roles only for truly interactive/dynamic experiences.
|
|
- If using `role="grid"`, grid cells MUST be nested in rows so header/cell relationships are determinable.
|
|
- Use arrow navigation to navigate within the grid.
|
|
|
|
## Final verification checklist (MUST)
|
|
|
|
Before finalizing output, explicitly verify:
|
|
|
|
- Structure and semantics: landmarks, headings, and one `h1` for the page topic.
|
|
- Keyboard and focus: operable controls, visible focus, predictable tab order, no traps, skip link works.
|
|
- Controls and labels: visible labels present and included in accessible names.
|
|
- 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.
|
|
- Graphics: informative alternatives; decorative graphics hidden.
|
|
- Tables/grids: tables use `<th>`; grids (when needed) are structured with rows and cells.
|
|
|
|
## Final note
|
|
|
|
Generate the HTML with accessibility in mind, but accessibility issues may still exist; manual review and testing (for example with Accessibility Insights) is still recommended.
|