ultra11y 2.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +223 -0
- package/docker/Dockerfile +7 -0
- package/docker/package.json +9 -0
- package/docker/runner.mjs +23 -0
- package/package.json +73 -0
- package/scripts/bench.mjs +151 -0
- package/scripts/build-act-corpus.mjs +143 -0
- package/scripts/build-adjudication.mjs +503 -0
- package/scripts/build-pack-rgaa.mjs +397 -0
- package/scripts/build-standards.mjs +548 -0
- package/scripts/copy-bundle.mjs +39 -0
- package/scripts/import-pack.mjs +107 -0
- package/scripts/sync-engine.mjs +84 -0
- package/scripts/sync-version.mjs +43 -0
- package/scripts/ultra11y.mjs +52739 -0
- package/scripts/vendor/act-testcases.json +12297 -0
- package/scripts/vendor/rgaa/SOURCE.json +8 -0
- package/scripts/vendor/rgaa/criteres.json +4144 -0
- package/scripts/vendor/rgaa/glossaire.json +480 -0
- package/scripts/vendor/wcag-2.2-fr.json +82 -0
- package/scripts/vendor/wcag-2.2-sc-universe.json +950 -0
- package/scripts/vendor/wcag-2.2-sc.json +574 -0
- package/scripts/verify-rgaa-source.mjs +126 -0
- package/scripts/verify-skill-bundle.mjs +91 -0
- package/skills/review-a11y/SKILL.md +123 -0
- package/skills/review-a11y/scripts/ultra11y.mjs +52739 -0
- package/skills/ultra11y/SKILL.md +292 -0
- package/skills/ultra11y/references/act.md +163 -0
- package/skills/ultra11y/references/adjudication.md +599 -0
- package/skills/ultra11y/references/audit.md +100 -0
- package/skills/ultra11y/references/authoring.md +37 -0
- package/skills/ultra11y/references/automation.md +113 -0
- package/skills/ultra11y/references/correction.md +41 -0
- package/skills/ultra11y/references/criteria.md +129 -0
- package/skills/ultra11y/references/cross-file.md +82 -0
- package/skills/ultra11y/references/dynamic.md +152 -0
- package/skills/ultra11y/references/false-positives.md +81 -0
- package/skills/ultra11y/references/fix.md +46 -0
- package/skills/ultra11y/references/focus-and-logic.md +64 -0
- package/skills/ultra11y/references/forbidden-patterns.md +61 -0
- package/skills/ultra11y/references/forms-and-errors.md +147 -0
- package/skills/ultra11y/references/guidance.md +55 -0
- package/skills/ultra11y/references/judgment.md +90 -0
- package/skills/ultra11y/references/media-and-motion.md +116 -0
- package/skills/ultra11y/references/methodology.md +72 -0
- package/skills/ultra11y/references/naming.md +117 -0
- package/skills/ultra11y/references/orchestration.md +44 -0
- package/skills/ultra11y/references/packs.md +193 -0
- package/skills/ultra11y/references/prd.md +104 -0
- package/skills/ultra11y/references/rendered.md +110 -0
- package/skills/ultra11y/references/scale.md +49 -0
- package/skills/ultra11y/references/standards.md +97 -0
- package/skills/ultra11y/references/structure.md +138 -0
- package/skills/ultra11y/references/verify.md +88 -0
- package/skills/ultra11y/references/widgets.md +106 -0
- package/skills/ultra11y/scripts/ultra11y.mjs +52739 -0
- package/src/act.ts +441 -0
- package/src/adjudicate.ts +630 -0
- package/src/aria.ts +230 -0
- package/src/audit.ts +396 -0
- package/src/auditor.ts +399 -0
- package/src/autofill.ts +102 -0
- package/src/axe-map.ts +294 -0
- package/src/baseline.ts +75 -0
- package/src/capture.ts +182 -0
- package/src/check.ts +243 -0
- package/src/cli.ts +1927 -0
- package/src/color.ts +102 -0
- package/src/config.ts +182 -0
- package/src/crawl.ts +75 -0
- package/src/criteria.ts +183 -0
- package/src/data/adjudication.json +770 -0
- package/src/data/guidance/rgaa.json +2395 -0
- package/src/data/standards/rgaa.glossary.json +478 -0
- package/src/data/standards/rgaa.json +3454 -0
- package/src/data/wcag-universe.json +530 -0
- package/src/data/wcag.json +1178 -0
- package/src/discover.ts +203 -0
- package/src/fix/codemods.ts +76 -0
- package/src/fix/diff.ts +64 -0
- package/src/fix/edits.ts +126 -0
- package/src/fix.ts +215 -0
- package/src/gh.ts +214 -0
- package/src/glob.ts +206 -0
- package/src/graph/build.ts +114 -0
- package/src/graph/engine-resolve.ts +0 -0
- package/src/graph/graph.ts +126 -0
- package/src/graph/imports.ts +359 -0
- package/src/graph/resolve.ts +73 -0
- package/src/graph/tsconfig.ts +113 -0
- package/src/grounding.ts +119 -0
- package/src/guidance/index.ts +45 -0
- package/src/guidance/types.ts +36 -0
- package/src/init.ts +113 -0
- package/src/mcp/handlers.ts +388 -0
- package/src/mcp/http.ts +260 -0
- package/src/mcp/prompts.ts +183 -0
- package/src/mcp/protocol.ts +187 -0
- package/src/mcp/resources.ts +136 -0
- package/src/mcp/server.ts +228 -0
- package/src/mcp/stdio.ts +119 -0
- package/src/mcp/tools.ts +347 -0
- package/src/messages.ts +1011 -0
- package/src/name.ts +174 -0
- package/src/orchestrate-templates.ts +231 -0
- package/src/orchestrate.ts +186 -0
- package/src/output.ts +108 -0
- package/src/pack.ts +187 -0
- package/src/parse/html.ts +258 -0
- package/src/parse/jsx-ast.ts +67 -0
- package/src/parse/jsx-bridge.ts +247 -0
- package/src/parse/jsx.ts +19 -0
- package/src/parse/source.ts +75 -0
- package/src/prd.ts +406 -0
- package/src/project-lock.ts +42 -0
- package/src/render.ts +307 -0
- package/src/report.ts +399 -0
- package/src/rules/colors.ts +125 -0
- package/src/rules/cross-registry.ts +264 -0
- package/src/rules/cross-rule.ts +83 -0
- package/src/rules/forms.ts +590 -0
- package/src/rules/frames.ts +33 -0
- package/src/rules/headings.ts +227 -0
- package/src/rules/images.ts +200 -0
- package/src/rules/links.ts +193 -0
- package/src/rules/mandatory.ts +173 -0
- package/src/rules/multimedia.ts +77 -0
- package/src/rules/navigation.ts +190 -0
- package/src/rules/presentation.ts +75 -0
- package/src/rules/registry.ts +57 -0
- package/src/rules/rule.ts +122 -0
- package/src/rules/scripts-aria.ts +636 -0
- package/src/rules/tables.ts +264 -0
- package/src/rules/timing.ts +55 -0
- package/src/sample.ts +176 -0
- package/src/scan-local.ts +866 -0
- package/src/scan.ts +538 -0
- package/src/standards/derive.ts +195 -0
- package/src/standards/index.ts +31 -0
- package/src/standards/pack-rules.ts +111 -0
- package/src/standards/pack.ts +81 -0
- package/src/standards/registry.ts +100 -0
- package/src/standards/types.ts +202 -0
- package/src/standards/validate.ts +544 -0
- package/src/standards/vocabulary.ts +75 -0
- package/src/types.ts +355 -0
- package/src/util.ts +32 -0
- package/src/vendor/codeindex-engine.d.mts +1009 -0
- package/src/vendor/codeindex-engine.mjs +13701 -0
- package/src/vendor/engine.meta.json +9 -0
- package/src/verify.ts +275 -0
- package/src/wcag.ts +128 -0
|
@@ -0,0 +1,599 @@
|
|
|
1
|
+
<!-- GENERATED from src/data/adjudication.json by `pnpm run build:adjudication` — do not edit by hand. -->
|
|
2
|
+
|
|
3
|
+
# Deciding the criteria the engine hands you
|
|
4
|
+
|
|
5
|
+
The static engine decides 3 of the 55 WCAG 2.2 AA success criteria outright. The other 52
|
|
6
|
+
come back as residual risks: 14 need a rendered page (the `scan` tier), 38 are judgment
|
|
7
|
+
calls. This page is the decision rule for each of them — what makes it Conforming, when
|
|
8
|
+
`NA` is legitimate, and the questions that get you there.
|
|
9
|
+
|
|
10
|
+
It is the same dataset `verify --manual` loads into `ADJUDICATE.md`, so the worklist and
|
|
11
|
+
this page can never disagree. Two rules govern every verdict below:
|
|
12
|
+
|
|
13
|
+
- **A non-conformity must cite a normative test that resolves.** The worklist proposes the
|
|
14
|
+
criterion's W3C techniques; `verify --apply` rejects a `normativeRef` that does not exist.
|
|
15
|
+
- **A good practice with no failing test is a recommendation**, not a non-conformity — it
|
|
16
|
+
never flips a criterion, never enters the conformance rate.
|
|
17
|
+
|
|
18
|
+
## 1.1 Text Alternatives
|
|
19
|
+
|
|
20
|
+
### 1.1.1 — Non-text Content · A · _judgment_
|
|
21
|
+
|
|
22
|
+
**Decide.** Conforming when EVERY non-text content carries an alternative serving the same purpose: a description of the meaning for an informative image, alt="" for a decorative one, a description of the action for a control. Non-conforming as soon as one alternative is missing, empty on a meaningful image, or off-topic (a file name, "image", "logo").
|
|
23
|
+
|
|
24
|
+
**Not applicable when.** No non-text content in scope.
|
|
25
|
+
|
|
26
|
+
**Ask.**
|
|
27
|
+
|
|
28
|
+
- For each alt: does it describe what the image CONTRIBUTES here, rather than what it depicts? The same photo can need two different alternatives in two contexts.
|
|
29
|
+
- Do the purely decorative images carry alt="" (not a missing alt)? A named decorative image is as harmful as a silent informative one.
|
|
30
|
+
- For a chart or infographic: does the alternative give the DATA (or point to an equivalent table), or does it merely name the chart?
|
|
31
|
+
|
|
32
|
+
**Citable references.** ARIA10, ARIA4, ARIA6, ARIA7, ARIA8, ARIA9, C9, F15, F19, F20, F3, F30 … (`criteria 1.1.1`)
|
|
33
|
+
|
|
34
|
+
## 1.2 Time-based Media
|
|
35
|
+
|
|
36
|
+
### 1.2.1 — Audio-only and Video-only (Prerecorded) · A · _judgment_
|
|
37
|
+
|
|
38
|
+
**Decide.** Conforming when every audio-only media has a text transcript, and every video-only media a transcript OR an equivalent audio track. Non-conforming when the media carries information available nowhere else.
|
|
39
|
+
|
|
40
|
+
**Not applicable when.** No audio-only or video-only media.
|
|
41
|
+
|
|
42
|
+
**Ask.**
|
|
43
|
+
|
|
44
|
+
- Is the transcript reachable from the media's own page (an adjacent link, a disclosure panel) rather than buried elsewhere?
|
|
45
|
+
- Does it cover ALL the content, including speaker identification and meaningful sounds?
|
|
46
|
+
|
|
47
|
+
**Citable references.** F30, F67, G158, G159, G166, G173, G58, G69, G78, G8, H96, SM6 … (`criteria 1.2.1`)
|
|
48
|
+
|
|
49
|
+
### 1.2.2 — Captions (Prerecorded) · A · _judgment_
|
|
50
|
+
|
|
51
|
+
**Decide.** Conforming when every prerecorded video carrying speech has synchronized captions (a <track kind="captions">, captions embedded in the container, or a player supplying them). Non-conforming when the speech is restituted by no caption at all.
|
|
52
|
+
|
|
53
|
+
**Not applicable when.** No prerecorded video carrying meaningful audio.
|
|
54
|
+
|
|
55
|
+
**Ask.**
|
|
56
|
+
|
|
57
|
+
- Does a missing <track> really prove there are no captions? Check the container and the player: captions can be embedded — which is why the engine does not class this as a non-conformity.
|
|
58
|
+
- Do the captions also cover meaningful non-speech sounds (music, alarm, laughter)?
|
|
59
|
+
|
|
60
|
+
**Citable references.** F74, F75, F8, G58, G87, G93, H95, SM11, SM12
|
|
61
|
+
|
|
62
|
+
### 1.2.3 — Audio Description or Media Alternative (Prerecorded) · A · _judgment_
|
|
63
|
+
|
|
64
|
+
**Decide.** Conforming when every prerecorded video with audio offers audio description OR a complete text alternative describing the visual information. Non-conforming when information carried only by the picture is restituted nowhere.
|
|
65
|
+
|
|
66
|
+
**Not applicable when.** No prerecorded video with audio.
|
|
67
|
+
|
|
68
|
+
**Ask.**
|
|
69
|
+
|
|
70
|
+
- What information exists ONLY in the picture (on-screen text, a demonstration, a chart)? Is it spoken or described elsewhere?
|
|
71
|
+
|
|
72
|
+
**Citable references.** F30, F67, G158, G159, G166, G173, G58, G69, G78, G8, H96, SM6 … (`criteria 1.2.3`)
|
|
73
|
+
|
|
74
|
+
### 1.2.4 — Captions (Live) · AA · _judgment_
|
|
75
|
+
|
|
76
|
+
**Decide.** Conforming when every live audio broadcast has real-time captions. Non-conforming otherwise.
|
|
77
|
+
|
|
78
|
+
**Not applicable when.** No live broadcast.
|
|
79
|
+
|
|
80
|
+
**Ask.**
|
|
81
|
+
|
|
82
|
+
- Is there a live stream (a webinar, a broadcast, an embedded conference) in scope? Is the captioning provider in place for EVERY session?
|
|
83
|
+
|
|
84
|
+
### 1.2.5 — Audio Description (Prerecorded) · AA · _judgment_
|
|
85
|
+
|
|
86
|
+
**Decide.** Conforming when every prerecorded video with audio has audio description (a dedicated track or an audio-described version). Note: at AA a text alternative alone no longer suffices, unlike 1.2.3.
|
|
87
|
+
|
|
88
|
+
**Not applicable when.** No prerecorded video with audio.
|
|
89
|
+
|
|
90
|
+
**Ask.**
|
|
91
|
+
|
|
92
|
+
- Does an audio-description track actually exist, or is only the 1.2.3 transcript provided?
|
|
93
|
+
|
|
94
|
+
**Citable references.** G173, G58, G78, G8, H96, SM1, SM2, SM6, SM7
|
|
95
|
+
|
|
96
|
+
## 1.3 Adaptable
|
|
97
|
+
|
|
98
|
+
### 1.3.1 — Info and Relationships · A · _judgment_
|
|
99
|
+
|
|
100
|
+
**Decide.** Conforming when every relationship and structure conveyed visually (headings, lists, tables, field groups, regions) is programmatically determinable. Non-conforming as soon as a relationship exists visually only — a bold <div> acting as a heading, a list built from <br>, a label/value pair in <span>s.
|
|
101
|
+
|
|
102
|
+
**Ask.**
|
|
103
|
+
|
|
104
|
+
- Technique consistency (RGAA 9.1): is the SAME structuring technique (hn vs caption, ul/ol/dl markup) used across ALL similar tables/pages — not instance by instance?
|
|
105
|
+
- Div-presented fields (RGAA 8.9): for each label/value pair shown with <div>/<span>, is the relationship anything other than visual (<dl>/<dt>/<dd> or an ARIA association)?
|
|
106
|
+
- Read without CSS, does the content keep the same meaning and the same order?
|
|
107
|
+
|
|
108
|
+
**Citable references.** ARIA11, ARIA12, ARIA14, ARIA16, ARIA17, ARIA4, ARIA6, ARIA9, C18, C22, C6, C8 … (`criteria 1.3.1`)
|
|
109
|
+
|
|
110
|
+
### 1.3.2 — Meaningful Sequence · A · _judgment_
|
|
111
|
+
|
|
112
|
+
**Decide.** Conforming when the DOM reading order produces a sequence that preserves meaning. Non-conforming when the visual and DOM orders diverge enough to change the meaning (columns reordered in CSS, `order`/`flex-direction: *-reverse`, absolute positioning).
|
|
113
|
+
|
|
114
|
+
**Ask.**
|
|
115
|
+
|
|
116
|
+
- Reading the DOM top to bottom, does the sequence stay understandable — or does a side column cut through the middle of a text?
|
|
117
|
+
- Does a CSS `order` or a reversed `flex-direction` visually move meaning-bearing elements?
|
|
118
|
+
|
|
119
|
+
**Citable references.** ARIA4, C18, C22, C6, C8, F1, F15, F32, F33, F34, F48, F49 … (`criteria 1.3.2`)
|
|
120
|
+
|
|
121
|
+
### 1.3.3 — Sensory Characteristics · A · _judgment_
|
|
122
|
+
|
|
123
|
+
**Decide.** Conforming when no instruction relies SOLELY on a sensory characteristic (shape, colour, size, position, sound). Non-conforming for "click the green button", "see the box on the right", "the field below" with no other cue.
|
|
124
|
+
|
|
125
|
+
**Ask.**
|
|
126
|
+
|
|
127
|
+
- Does each instruction also name its target (a label, a heading) in addition to its position or colour?
|
|
128
|
+
|
|
129
|
+
**Citable references.** F14, F26, G140, G96
|
|
130
|
+
|
|
131
|
+
### 1.3.4 — Orientation · AA · _needs-rendering_
|
|
132
|
+
|
|
133
|
+
**Decide.** Conforming when the content displays in both orientations. Non-conforming when display is locked (a blocking CSS `transform`/orientation media query, an app-level lock) without the orientation being essential.
|
|
134
|
+
|
|
135
|
+
**Ask.**
|
|
136
|
+
|
|
137
|
+
- Is the orientation genuinely ESSENTIAL (a piano keyboard, a cheque to photograph), or merely a layout choice?
|
|
138
|
+
|
|
139
|
+
### 1.3.5 — Identify Input Purpose · AA · _judgment_
|
|
140
|
+
|
|
141
|
+
**Decide.** Conforming when every field collecting information ABOUT THE USER declares its purpose with an `autocomplete` token from the WCAG list. Non-conforming when the token is missing or outside the vocabulary.
|
|
142
|
+
|
|
143
|
+
**Not applicable when.** No field collects information about the user.
|
|
144
|
+
|
|
145
|
+
**Ask.**
|
|
146
|
+
|
|
147
|
+
- Does the field collect data about the USER (name, email, address, phone) — rather than business data (an order number, a search keyword)?
|
|
148
|
+
|
|
149
|
+
**Citable references.** H98
|
|
150
|
+
|
|
151
|
+
## 1.4 Distinguishable
|
|
152
|
+
|
|
153
|
+
### 1.4.1 — Use of Color · A · _needs-rendering_
|
|
154
|
+
|
|
155
|
+
**Decide.** Conforming when no information is conveyed by colour ALONE. Non-conforming for an in-paragraph link distinguished only by colour, a red/green status with no text or icon, a field error signalled only by a coloured border.
|
|
156
|
+
|
|
157
|
+
**Ask.**
|
|
158
|
+
|
|
159
|
+
- Seen in greyscale, does every piece of information stay distinguishable?
|
|
160
|
+
|
|
161
|
+
**Citable references.** C15, F14, F26, F73, F78, G111, G117, G138, G14, G140, G149, G165 … (`criteria 1.4.1`)
|
|
162
|
+
|
|
163
|
+
### 1.4.3 — Contrast (Minimum) · AA · _needs-rendering_
|
|
164
|
+
|
|
165
|
+
**Decide.** Decided on the render (`scan`): 4.5:1 for body text, 3:1 for large text (>= 18.66px bold or >= 24px). The engine settles the inline-literal colour subset; everything else needs computed styles.
|
|
166
|
+
|
|
167
|
+
**Ask.**
|
|
168
|
+
|
|
169
|
+
- Have the states (hover, focus, disabled) and text over images/gradients been measured, not just the resting state?
|
|
170
|
+
|
|
171
|
+
**Citable references.** C29, F24, G136, G145, G148, G174, G18
|
|
172
|
+
|
|
173
|
+
### 1.4.4 — Resize Text · AA · _needs-rendering_
|
|
174
|
+
|
|
175
|
+
**Decide.** Decided on the render: at 200% text zoom no content or functionality is lost, truncated or overlapped. Non-conforming when a `meta viewport` blocks zooming.
|
|
176
|
+
|
|
177
|
+
**Ask.**
|
|
178
|
+
|
|
179
|
+
- At 200%, does any text overlap, or any button escape its container?
|
|
180
|
+
|
|
181
|
+
**Citable references.** C12, C13, C14, C17, C28, F69, F80, G146, G179, SCR34
|
|
182
|
+
|
|
183
|
+
### 1.4.5 — Images of Text · AA · _needs-rendering_
|
|
184
|
+
|
|
185
|
+
**Decide.** Conforming when text is real text, except for a logotype or an essential presentation. Non-conforming for a heading, a button or a quotation baked into an image.
|
|
186
|
+
|
|
187
|
+
**Ask.**
|
|
188
|
+
|
|
189
|
+
- Is the image of text a logo (exempt), or a styling that CSS could reproduce?
|
|
190
|
+
|
|
191
|
+
**Citable references.** C22, C30, G136, G140
|
|
192
|
+
|
|
193
|
+
### 1.4.10 — Reflow · AA · _needs-rendering_
|
|
194
|
+
|
|
195
|
+
**Decide.** Decided on the render: at 320 CSS px wide (equivalent to 400% on 1280px), no two-dimensional scrolling is required, except for content that inherently needs it (a map, a wide data table).
|
|
196
|
+
|
|
197
|
+
**Ask.**
|
|
198
|
+
|
|
199
|
+
- Does the remaining horizontal scrolling apply to genuinely exempt content, or to the whole page?
|
|
200
|
+
|
|
201
|
+
**Citable references.** C34, C37
|
|
202
|
+
|
|
203
|
+
### 1.4.11 — Non-text Contrast · AA · _needs-rendering_
|
|
204
|
+
|
|
205
|
+
**Decide.** Decided on the render: 3:1 for user-interface components (a field border, a button outline, the focus indicator) and for the meaningful parts of graphics.
|
|
206
|
+
|
|
207
|
+
**Ask.**
|
|
208
|
+
|
|
209
|
+
- Do the border identifying a field, and the focus indicator, reach 3:1 against their background?
|
|
210
|
+
|
|
211
|
+
**Citable references.** F78, G145, G174, G18, G183, G195, G207
|
|
212
|
+
|
|
213
|
+
### 1.4.12 — Text Spacing · AA · _needs-rendering_
|
|
214
|
+
|
|
215
|
+
**Decide.** Decided on the render: forcing line height 1.5x, paragraph spacing 2x, letter spacing 0.12x and word spacing 0.16x, no content is lost or clipped.
|
|
216
|
+
|
|
217
|
+
**Ask.**
|
|
218
|
+
|
|
219
|
+
- Do any fixed-height containers clip text once the spacing is increased?
|
|
220
|
+
|
|
221
|
+
**Citable references.** C21, C35, C36, C8
|
|
222
|
+
|
|
223
|
+
### 1.4.13 — Content on Hover or Focus · AA · _needs-rendering_
|
|
224
|
+
|
|
225
|
+
**Decide.** Decided on the render: any additional content shown on hover or focus must be dismissible (Escape), hoverable (the pointer can reach it) and persistent (it does not vanish on its own).
|
|
226
|
+
|
|
227
|
+
**Ask.**
|
|
228
|
+
|
|
229
|
+
- Does the tooltip survive the pointer moving onto it, and does Escape close it without moving focus?
|
|
230
|
+
|
|
231
|
+
**Citable references.** F95
|
|
232
|
+
|
|
233
|
+
## 2.1 Keyboard Accessible
|
|
234
|
+
|
|
235
|
+
### 2.1.1 — Keyboard · A · _judgment_
|
|
236
|
+
|
|
237
|
+
**Decide.** Conforming when every function is operable with the keyboard alone. Non-conforming as soon as an action exists only for the mouse (a handler on a non-interactive element, drag-and-drop with no equivalent, mandatory hover).
|
|
238
|
+
|
|
239
|
+
**Ask.**
|
|
240
|
+
|
|
241
|
+
- Does each `onClick`/`onMouseEnter` on a non-native element have a keyboard equivalent (a native element, or role + tabindex + Enter/Space handling)?
|
|
242
|
+
- Do the composite widgets (menu, tabs, combobox) follow the expected keyboard contract (arrows, Escape, Home/End)?
|
|
243
|
+
|
|
244
|
+
**Citable references.** F10, F42, F54, F55, G202, G21, G4, G90, H91, SCR2, SCR20, SCR29 … (`criteria 2.1.1`)
|
|
245
|
+
|
|
246
|
+
### 2.1.2 — No Keyboard Trap · A · _needs-rendering_
|
|
247
|
+
|
|
248
|
+
**Decide.** Decided on the render: focus must be able to ENTER and LEAVE every component with the keyboard alone. Non-conforming for a modal, an embedded player or an editor that captures focus permanently.
|
|
249
|
+
|
|
250
|
+
**Ask.**
|
|
251
|
+
|
|
252
|
+
- In every modal and third-party iframe, does Tab eventually get out — and does Escape hand control back?
|
|
253
|
+
|
|
254
|
+
**Citable references.** F10, G202, G21, G4, G90, H91
|
|
255
|
+
|
|
256
|
+
### 2.1.4 — Character Key Shortcuts · A · _judgment_
|
|
257
|
+
|
|
258
|
+
**Decide.** Conforming when every single-printable-character shortcut can be turned off, remapped, or is active only while its component has focus. Non-conforming when it is global and cannot be disabled.
|
|
259
|
+
|
|
260
|
+
**Not applicable when.** No single-character shortcut.
|
|
261
|
+
|
|
262
|
+
**Ask.**
|
|
263
|
+
|
|
264
|
+
- Could a speech-input user dictating text trigger this shortcut by accident?
|
|
265
|
+
|
|
266
|
+
**Citable references.** F99, G217
|
|
267
|
+
|
|
268
|
+
## 2.2 Enough Time
|
|
269
|
+
|
|
270
|
+
### 2.2.1 — Timing Adjustable · A · _judgment_
|
|
271
|
+
|
|
272
|
+
**Decide.** Conforming when every time limit can be turned off, adjusted (x10) or extended on request. Exemptions: real-time activity, an essential event, a limit longer than 20 hours.
|
|
273
|
+
|
|
274
|
+
**Not applicable when.** No time limit.
|
|
275
|
+
|
|
276
|
+
**Ask.**
|
|
277
|
+
|
|
278
|
+
- Does the session expire? Is the user warned BEFORE it does, and can they extend it?
|
|
279
|
+
|
|
280
|
+
**Citable references.** F16, F4, F40, F41, F47, F50, F58, F61, F7, G11, G110, G133 … (`criteria 2.2.1`)
|
|
281
|
+
|
|
282
|
+
### 2.2.2 — Pause, Stop, Hide · A · _judgment_
|
|
283
|
+
|
|
284
|
+
**Decide.** Conforming when any moving, blinking or scrolling content lasting more than 5 seconds and starting automatically can be paused, stopped or hidden. Same for any auto-updating content.
|
|
285
|
+
|
|
286
|
+
**Not applicable when.** No moving content and no automatic updates.
|
|
287
|
+
|
|
288
|
+
**Ask.**
|
|
289
|
+
|
|
290
|
+
- Do carousels, animations and scrolling banners have a pause control reachable by keyboard?
|
|
291
|
+
|
|
292
|
+
**Citable references.** F16, F4, F40, F41, F47, F50, F58, F61, F7, G11, G110, G133 … (`criteria 2.2.2`)
|
|
293
|
+
|
|
294
|
+
## 2.3 Seizures and Physical Reactions
|
|
295
|
+
|
|
296
|
+
### 2.3.1 — Three Flashes or Below Threshold · A · _needs-rendering_
|
|
297
|
+
|
|
298
|
+
**Decide.** Decided on the render: nothing flashes more than three times per second, unless it stays below the general and red flash thresholds.
|
|
299
|
+
|
|
300
|
+
**Not applicable when.** No flashing content.
|
|
301
|
+
|
|
302
|
+
**Ask.**
|
|
303
|
+
|
|
304
|
+
- Does any video or animation contain rapid flashes (explosions, strobe effects)?
|
|
305
|
+
|
|
306
|
+
**Citable references.** G15, G176, G19
|
|
307
|
+
|
|
308
|
+
## 2.4 Navigable
|
|
309
|
+
|
|
310
|
+
### 2.4.1 — Bypass Blocks · A · _judgment_
|
|
311
|
+
|
|
312
|
+
**Decide.** Conforming when a mechanism bypasses repeated blocks: a working skip link, or a structure of landmarks and headings. Non-conforming when the user must traverse the navigation on every page.
|
|
313
|
+
|
|
314
|
+
**Ask.**
|
|
315
|
+
|
|
316
|
+
- Is the skip link the FIRST focusable element, visible on focus, and does its target actually receive focus?
|
|
317
|
+
|
|
318
|
+
**Citable references.** ARIA11, ARIA12, ARIA4, F15, F66, G1, G10, G115, G123, G124, G130, G135 … (`criteria 2.4.1`)
|
|
319
|
+
|
|
320
|
+
### 2.4.3 — Focus Order · A · _judgment_
|
|
321
|
+
|
|
322
|
+
**Decide.** Conforming when the tab order preserves meaning and operability. Non-conforming when focus jumps incoherently, enters hidden content, or departs from the visual order where that order carries meaning.
|
|
323
|
+
|
|
324
|
+
**Ask.**
|
|
325
|
+
|
|
326
|
+
- SPA (RGAA 12.8): after a partial navigation, is focus moved to the new content (not left on the clicked link, nor reset to the top)?
|
|
327
|
+
- When a modal opens, does focus move into it; when it closes, does it return to the trigger?
|
|
328
|
+
|
|
329
|
+
**Citable references.** C27, F1, F15, F44, F66, F85, G1, G10, G123, G124, G135, G140 … (`criteria 2.4.3`)
|
|
330
|
+
|
|
331
|
+
### 2.4.4 — Link Purpose (In Context) · A · _judgment_
|
|
332
|
+
|
|
333
|
+
**Decide.** Conforming when each link's purpose is understandable from its text alone, or from its text plus its immediate context (sentence, list item, cell + headers). Non-conforming for "read more", "click here", a bare URL, or two identically-named links going to different destinations.
|
|
334
|
+
|
|
335
|
+
**Ask.**
|
|
336
|
+
|
|
337
|
+
- Read out of context, does the text say WHERE the link goes or WHAT it triggers?
|
|
338
|
+
- Do two links with the same text lead to the same destination?
|
|
339
|
+
- Does a download link state the format and size (a recommendation, not normative)?
|
|
340
|
+
|
|
341
|
+
**Citable references.** ARIA7, ARIA8, F63, F89, G53, G91, H30, H78, H79, H80, H81
|
|
342
|
+
|
|
343
|
+
### 2.4.5 — Multiple Ways · AA · _judgment_
|
|
344
|
+
|
|
345
|
+
**Decide.** Conforming when at least TWO ways lead to each page: a search engine, a site map, the main navigation, a breadcrumb, an index. Exemption: a page that is a step in a process.
|
|
346
|
+
|
|
347
|
+
**Ask.**
|
|
348
|
+
|
|
349
|
+
- Do the two ways exist across the WHOLE site, or only on the home page?
|
|
350
|
+
|
|
351
|
+
**Citable references.** G161, G61, G63, G64
|
|
352
|
+
|
|
353
|
+
### 2.4.6 — Headings and Labels · AA · _judgment_
|
|
354
|
+
|
|
355
|
+
**Decide.** Conforming when each heading describes the section it introduces and each label describes what the field expects. Non-conforming for a generic heading ("Section 2"), a vague label ("Value"), or a heading that does not match its content.
|
|
356
|
+
|
|
357
|
+
**Ask.**
|
|
358
|
+
|
|
359
|
+
- Read on their own, do the headings give an understandable outline of the page?
|
|
360
|
+
- Table-title concision (RGAA 5.5): is each <caption> a SHORT, relevant title? A clear but verbose title should become a brief intro, with the details moved into text associated via aria-labelledby/aria-describedby.
|
|
361
|
+
|
|
362
|
+
**Citable references.** ARIA12, ARIA14, ARIA16, ARIA4, ARIA6, ARIA9, F68, F82, F86, G115, G130, G131 … (`criteria 2.4.6`)
|
|
363
|
+
|
|
364
|
+
### 2.4.7 — Focus Visible · AA · _needs-rendering_
|
|
365
|
+
|
|
366
|
+
**Decide.** Decided on the render: every focusable element shows a visible focus indicator. Non-conforming for an unreplaced `outline: none`.
|
|
367
|
+
|
|
368
|
+
**Ask.**
|
|
369
|
+
|
|
370
|
+
- Is the indicator visible on ALL backgrounds (dark theme, hover, elements over images)?
|
|
371
|
+
|
|
372
|
+
**Citable references.** C15, F42, F54, F55, F73, F78, G149, G165, G183, G195, G202, G90 … (`criteria 2.4.7`)
|
|
373
|
+
|
|
374
|
+
### 2.4.11 — Focus Not Obscured (Minimum) · AA · _needs-rendering_
|
|
375
|
+
|
|
376
|
+
**Decide.** Decided on the render: the element receiving focus is not entirely hidden by author-created content (a sticky header, a cookie banner, an action bar).
|
|
377
|
+
|
|
378
|
+
**Ask.**
|
|
379
|
+
|
|
380
|
+
- Tabbing down then up, does a sticky header or footer cover the focused element?
|
|
381
|
+
|
|
382
|
+
## 2.5 Input Modalities
|
|
383
|
+
|
|
384
|
+
### 2.5.1 — Pointer Gestures · A · _judgment_
|
|
385
|
+
|
|
386
|
+
**Decide.** Conforming when every function using a multipoint or path-based gesture has a single-pointer alternative. Non-conforming for a pinch, a swipe or a path with no button equivalent.
|
|
387
|
+
|
|
388
|
+
**Not applicable when.** No complex gesture.
|
|
389
|
+
|
|
390
|
+
**Ask.**
|
|
391
|
+
|
|
392
|
+
- Do carousels, maps and sliders offer buttons in addition to the gesture?
|
|
393
|
+
|
|
394
|
+
**Citable references.** G215, G216
|
|
395
|
+
|
|
396
|
+
### 2.5.2 — Pointer Cancellation · A · _judgment_
|
|
397
|
+
|
|
398
|
+
**Decide.** Conforming when no function executes on the DOWN event, or when it is abortable/reversible. Non-conforming for an action fired on `mousedown`/`touchstart` with no way to abort by moving the pointer away.
|
|
399
|
+
|
|
400
|
+
**Ask.**
|
|
401
|
+
|
|
402
|
+
- Do any `onMouseDown`/`onTouchStart` handlers fire the action instead of `onClick`?
|
|
403
|
+
|
|
404
|
+
### 2.5.3 — Label in Name · A · _judgment_
|
|
405
|
+
|
|
406
|
+
**Decide.** Conforming when, for every control with a visible text label, that text is CONTAINED in the accessible name. Non-conforming when `aria-label` replaces the visible text with a different wording: voice control can no longer find the target.
|
|
407
|
+
|
|
408
|
+
**Ask.**
|
|
409
|
+
|
|
410
|
+
- Does the accessible name ideally START with the visible text, so voice control matches the first spoken word?
|
|
411
|
+
|
|
412
|
+
**Citable references.** ARIA14, ARIA16, ARIA18, ARIA19, ARIA4, ARIA5, ARIA6, ARIA7, ARIA8, ARIA9, F15, F19 … (`criteria 2.5.3`)
|
|
413
|
+
|
|
414
|
+
### 2.5.4 — Motion Actuation · A · _judgment_
|
|
415
|
+
|
|
416
|
+
**Decide.** Conforming when every function triggered by device motion (shake, tilt) has an equivalent in the interface AND can be disabled.
|
|
417
|
+
|
|
418
|
+
**Not applicable when.** No motion actuation.
|
|
419
|
+
|
|
420
|
+
**Ask.**
|
|
421
|
+
|
|
422
|
+
- Does a `devicemotion`/`deviceorientation` listener trigger an action with no equivalent button?
|
|
423
|
+
|
|
424
|
+
### 2.5.7 — Dragging Movements · AA · _judgment_
|
|
425
|
+
|
|
426
|
+
**Decide.** Conforming when every dragging action has a single-pointer alternative that does not require dragging (buttons, an input, a menu). Non-conforming for reordering, a slider or a kanban that only supports drag-and-drop.
|
|
427
|
+
|
|
428
|
+
**Not applicable when.** No dragging interaction.
|
|
429
|
+
|
|
430
|
+
**Ask.**
|
|
431
|
+
|
|
432
|
+
- Do the reorderable lists offer "move up"/"move down" buttons in addition to dragging?
|
|
433
|
+
|
|
434
|
+
### 2.5.8 — Target Size (Minimum) · AA · _needs-rendering_
|
|
435
|
+
|
|
436
|
+
**Decide.** Decided on the render: the pointer target is at least 24x24 CSS px, unless there is sufficient spacing, an equivalent elsewhere, an inline-in-text target, or a legally mandated size.
|
|
437
|
+
|
|
438
|
+
**Ask.**
|
|
439
|
+
|
|
440
|
+
- Do the small icons (close, edit, delete) reach 24px, or do they benefit from the spacing exception?
|
|
441
|
+
|
|
442
|
+
## 3.1 Readable
|
|
443
|
+
|
|
444
|
+
### 3.1.2 — Language of Parts · AA · _judgment_
|
|
445
|
+
|
|
446
|
+
**Decide.** Conforming when every passage in a language other than the page's carries a correct `lang`. Exemptions: proper nouns, technical terms, words that have entered the vernacular.
|
|
447
|
+
|
|
448
|
+
**Not applicable when.** No change of language.
|
|
449
|
+
|
|
450
|
+
**Ask.**
|
|
451
|
+
|
|
452
|
+
- Are quotations, work titles and foreign expressions marked — and does the subtag actually match the text's language?
|
|
453
|
+
|
|
454
|
+
**Citable references.** H58
|
|
455
|
+
|
|
456
|
+
## 3.2 Predictable
|
|
457
|
+
|
|
458
|
+
### 3.2.1 — On Focus · A · _judgment_
|
|
459
|
+
|
|
460
|
+
**Decide.** Conforming when receiving focus triggers NO change of context. Non-conforming when focus opens a window, submits a form or moves focus elsewhere.
|
|
461
|
+
|
|
462
|
+
**Ask.**
|
|
463
|
+
|
|
464
|
+
- Do any `onFocus` handlers navigate, open a modal or move focus?
|
|
465
|
+
|
|
466
|
+
**Citable references.** F22, F36, F37, F41, F55, F9, G107, G13, G76, G80, H32, H84 … (`criteria 3.2.1`)
|
|
467
|
+
|
|
468
|
+
### 3.2.2 — On Input · A · _judgment_
|
|
469
|
+
|
|
470
|
+
**Decide.** Conforming when changing a control's value does not by itself trigger a change of context, or when the user was warned beforehand. Non-conforming for a `<select>` that navigates on change.
|
|
471
|
+
|
|
472
|
+
**Ask.**
|
|
473
|
+
|
|
474
|
+
- Is the change announced BEFORE (help text above the field), or does the user discover it afterwards?
|
|
475
|
+
|
|
476
|
+
**Citable references.** F22, F36, F37, F41, F9, G107, G13, G76, G80, H32, H84, SCR19
|
|
477
|
+
|
|
478
|
+
### 3.2.3 — Consistent Navigation · AA · _judgment_
|
|
479
|
+
|
|
480
|
+
**Decide.** Conforming when repeated navigation mechanisms appear in the SAME relative order from page to page. Non-conforming when the menu entries reorder across pages.
|
|
481
|
+
|
|
482
|
+
**Ask.**
|
|
483
|
+
|
|
484
|
+
- Across the page sample, do the main navigation, the breadcrumb and the footer keep the same order?
|
|
485
|
+
|
|
486
|
+
**Citable references.** F66, G1, G123, G124, G59, G61, G63, SCR28
|
|
487
|
+
|
|
488
|
+
### 3.2.4 — Consistent Identification · AA · _judgment_
|
|
489
|
+
|
|
490
|
+
**Decide.** Conforming when components with the same function are identified the same way everywhere (same wording, same icon, same accessible name). Non-conforming when "Search" becomes "Find" from page to page.
|
|
491
|
+
|
|
492
|
+
**Ask.**
|
|
493
|
+
|
|
494
|
+
- Do the recurring icons (print, share, download) carry the same accessible name everywhere?
|
|
495
|
+
|
|
496
|
+
**Citable references.** F31
|
|
497
|
+
|
|
498
|
+
### 3.2.6 — Consistent Help · A · _judgment_
|
|
499
|
+
|
|
500
|
+
**Decide.** Conforming when, wherever a help mechanism (contact, chat, FAQ, contextual help) appears on multiple pages, it sits in the same relative order. New in WCAG 2.2.
|
|
501
|
+
|
|
502
|
+
**Not applicable when.** No help mechanism.
|
|
503
|
+
|
|
504
|
+
**Ask.**
|
|
505
|
+
|
|
506
|
+
- Does the contact link or chat widget sit in the same relative position on every page that carries it?
|
|
507
|
+
|
|
508
|
+
## 3.3 Input Assistance
|
|
509
|
+
|
|
510
|
+
### 3.3.1 — Error Identification · A · _judgment_
|
|
511
|
+
|
|
512
|
+
**Decide.** Conforming when every automatically detected input error is identified IN TEXT and the offending field is pointed out. Non-conforming for a red border alone, or a message not associated with its field.
|
|
513
|
+
|
|
514
|
+
**Not applicable when.** No automatic input-error detection.
|
|
515
|
+
|
|
516
|
+
**Ask.**
|
|
517
|
+
|
|
518
|
+
- Is the error message tied to the field (`aria-describedby`/`aria-errormessage`) and announced when it appears?
|
|
519
|
+
|
|
520
|
+
**Citable references.** ARIA1, ARIA16, ARIA2, ARIA21, ARIA6, ARIA9, F81, G184, G83, G84, G85, G89 … (`criteria 3.3.1`)
|
|
521
|
+
|
|
522
|
+
### 3.3.2 — Labels or Instructions · A · _judgment_
|
|
523
|
+
|
|
524
|
+
**Decide.** Conforming when every field carries a label or instruction where input is expected. Non-conforming when the expected format (date, password, phone) is stated nowhere before the error.
|
|
525
|
+
|
|
526
|
+
**Ask.**
|
|
527
|
+
|
|
528
|
+
- Are the format and constraints stated BEFORE input, not only in the error message?
|
|
529
|
+
|
|
530
|
+
**Citable references.** ARIA1, ARIA14, ARIA16, ARIA17, ARIA2, ARIA21, ARIA6, ARIA9, F68, F81, F82, F86 … (`criteria 3.3.2`)
|
|
531
|
+
|
|
532
|
+
### 3.3.3 — Error Suggestion · AA · _judgment_
|
|
533
|
+
|
|
534
|
+
**Decide.** Conforming when, where the correction is known, a suggestion is offered. Non-conforming for an "invalid field" that does not say what is expected, unless suggesting it would compromise security.
|
|
535
|
+
|
|
536
|
+
**Not applicable when.** No automatically detected input error.
|
|
537
|
+
|
|
538
|
+
**Ask.**
|
|
539
|
+
|
|
540
|
+
- Does the message say HOW to fix it ("the date must be DD/MM/YYYY"), or only that it is wrong?
|
|
541
|
+
|
|
542
|
+
**Citable references.** G177, G84, G85, G89, H89
|
|
543
|
+
|
|
544
|
+
### 3.3.4 — Error Prevention (Legal, Financial, Data) · AA · _judgment_
|
|
545
|
+
|
|
546
|
+
**Decide.** Conforming when legal, financial or data-modifying submissions are reversible, checked, or confirmed. Non-conforming for a one-click irreversible deletion or order.
|
|
547
|
+
|
|
548
|
+
**Not applicable when.** No legal, financial or data-modifying transaction.
|
|
549
|
+
|
|
550
|
+
**Ask.**
|
|
551
|
+
|
|
552
|
+
- Can the user review and correct before final submission?
|
|
553
|
+
|
|
554
|
+
**Citable references.** G155, G164, G168, G98, G99
|
|
555
|
+
|
|
556
|
+
### 3.3.7 — Redundant Entry · A · _judgment_
|
|
557
|
+
|
|
558
|
+
**Decide.** Conforming when no information already entered in the same process is asked for again, unless re-entry is essential (password confirmation) or the information is no longer valid. New in WCAG 2.2.
|
|
559
|
+
|
|
560
|
+
**Ask.**
|
|
561
|
+
|
|
562
|
+
- Does a multi-step flow ask again for an address or email already entered, with no prefill and no selection?
|
|
563
|
+
|
|
564
|
+
### 3.3.8 — Accessible Authentication (Minimum) · AA · _judgment_
|
|
565
|
+
|
|
566
|
+
**Decide.** Conforming when no authentication step requires a cognitive function test (memorise, transcribe, solve), unless an alternative, a mechanism, object recognition or user-provided content is available. Pasting and autofill must remain possible. New in WCAG 2.2.
|
|
567
|
+
|
|
568
|
+
**Not applicable when.** No authentication.
|
|
569
|
+
|
|
570
|
+
**Ask.**
|
|
571
|
+
|
|
572
|
+
- Is pasting possible in the credential fields, and can a password manager fill them?
|
|
573
|
+
- Is a transcription CAPTCHA or a code to retype from memory imposed with no alternative?
|
|
574
|
+
|
|
575
|
+
## 4.1 Compatible
|
|
576
|
+
|
|
577
|
+
### 4.1.2 — Name, Role, Value · A · _judgment_
|
|
578
|
+
|
|
579
|
+
**Decide.** Conforming when every user-interface component exposes a name, a role and — where it carries state — a value, all kept up to date. Non-conforming for a custom widget with no role, no name, or whose ARIA state does not track the real one.
|
|
580
|
+
|
|
581
|
+
**Ask.**
|
|
582
|
+
|
|
583
|
+
- For each custom widget: does the role match the actual behaviour, and does the state (`aria-expanded`, `aria-checked`, `aria-selected`) track the interaction?
|
|
584
|
+
- Does the accessible name match what the user sees and would say?
|
|
585
|
+
|
|
586
|
+
**Citable references.** ARIA10, ARIA11, ARIA12, ARIA14, ARIA16, ARIA18, ARIA19, ARIA4, ARIA5, ARIA6, ARIA9, C9 … (`criteria 4.1.2`)
|
|
587
|
+
|
|
588
|
+
### 4.1.3 — Status Messages · AA · _judgment_
|
|
589
|
+
|
|
590
|
+
**Decide.** Conforming when every status message (success, error, search results, loading) is exposed through a role or property allowing announcement WITHOUT receiving focus. Non-conforming for a message inserted into an ordinary container.
|
|
591
|
+
|
|
592
|
+
**Not applicable when.** No status message.
|
|
593
|
+
|
|
594
|
+
**Ask.**
|
|
595
|
+
|
|
596
|
+
- Does the live region exist IN THE DOM before the message is inserted (a region created together with its content is not announced)?
|
|
597
|
+
- Is the politeness right: `polite` for a status, `alert`/`assertive` for a blocking error?
|
|
598
|
+
|
|
599
|
+
**Citable references.** ARIA19, ARIA22, ARIA23
|