awesome-copilot 无障碍开发指南:基于 WCAG 2.2 AA 的 Web 可访问性标准实战手册
【免费下载链接】awesome-copilotCommunity-contributed instructions, agents, skills, and configurations to help you make the most of GitHub Copilot.项目地址: https://gitcode.com/GitHub_Trending/aw/awesome-copilot
本指南以 awesome-copilot 仓库中的 a11y.instructions.md 为核心,系统讲解现代 Web 应用的无障碍(Accessibility)开发标准。该指令文件以applyTo: '**'全局生效,内置 38+ 反模式(Anti-pattern)检查清单、WCAG 2.2 AA 准则映射、ARIA 模式与 React / Angular / Vue 等框架级修复方案。读完本文,你将掌握一套可直接用于日常开发与代码评审的无障碍基线:如何识别 CRITICAL / IMPORTANT / SUGGESTION 三级缺陷、如何用语义 HTML 替代 ARIA、如何修复键盘与焦点管理问题,以及如何对照 POUR 清单做最终验收。
1. 在 awesome-copilot 中定位:这是一份全局指令
在 awesome-copilot 仓库中,instructions/目录存放的是"按文件模式自动应用到 Copilot 行为"的自定义指令。a11y.instructions.md 的 front matter 声明了applyTo: '**',意味着它对任意文件生效,是仓库中覆盖面最广的无障碍规范之一;同时它也是 docs/README.instructions.md 指令索引表中的 "Accessibility Standards" 条目,可在 VS Code / VS Code Insiders 中一键安装。
除了这份指令,仓库还提供了一系列无障碍配套资源,可交叉参考:
- agents/accessibility.agent.md —— Accessibility Expert 智能体:面向设计师、开发者、QA 三方输出 WCAG 2.1/2.2 落地建议,并附 axe / pa11y / Lighthouse CI 命令;
- agents/accessibility-runtime-tester.agent.md —— Accessibility Runtime Tester:强调"运行态验证"而非静态检查,专注键盘流程、焦点陷阱、对话框行为与表单错误;
- instructions/markdown-accessibility.instructions.md —— Markdown 文档的无障碍审查规范(描述性链接、alt 文本、标题层级等);
- extensions/accessibility-kanban/ —— 一个基于 Copilot SDK 的看板扩展,用于对无障碍相关 issue 做 backlog → plan → ready → implement → done 的分诊。
本文后续内容均以a11y.instructions.md原文为主线展开,仓库源码仅作为佐证与延伸。
2. 严重级别定义:先学会给问题定级
该指令为每个反模式定义了统一的三级严重性,便于在 PR 评审中快速排序:
- CRITICAL— 用户完全无法访问内容(例如键盘不可达、无可访问名称)。必须合入前修复;
- IMPORTANT— 对辅助技术用户构成显著障碍(例如标题层级跳跃、焦点未还原)。应在同一迭代修复;
- SUGGESTION— 提升辅助技术可用性(例如冗余 ARIA、多 h1、动画尊重
prefers-reduced-motion)。规划到未来迭代。
这套分级与 agents/accessibility-runtime-tester.agent.md 中的运行态严重度(Critical/High/Medium/Low)互补:前者偏静态代码审查,后者偏运行时用户体验。
3. WCAG 2.2 AA 快速参考(按 POUR 四大原则)
3.1 Perceivable(可感知)
| Criterion | Level | Summary |
|---|---|---|
| 1.1.1 Non-text Content | A | 所有非文本内容有文本替代;装饰性图片使用alt="" |
| 1.2.1 Audio/Video-only | A | 纯音频提供转录文本,纯视频提供文本替代 |
| 1.2.2 Captions (Prerecorded) | A | 所有预录制视频有同步字幕 |
| 1.3.1 Info and Relationships | A | 结构(标题、列表、表格、标签、地标)以编程方式呈现 |
| 1.3.2 Meaningful Sequence | A | 视觉顺序与程序化顺序保持一致 |
| 1.3.3 Sensory Characteristics | A | 指令不单纯依赖形状、大小、位置或声音 |
| 1.3.4 Orientation | AA | 内容不限制为单一方向(除非必要) |
| 1.3.5 Identify Input Purpose | A | 收集用户信息时输入框带autocomplete属性 |
| 1.4.1 Use of Color | A | 颜色不是传达信息的唯一手段 |
| 1.4.3 Contrast (Minimum) | AA | 文本对比度:普通 4.5:1,大文本(18pt / 14pt 加粗)3:1 |
| 1.4.4 Resize Text | AA | 文本可放大到 200% 而不丢失内容或功能 |
| 1.4.10 Reflow | AA | 内容可在 320px CSS 宽度下呈现,无需二维滚动 |
| 1.4.11 Non-text Contrast | AA | UI 组件与图形相对相邻颜色至少 3:1 |
| 1.4.12 Text Spacing | AA | 用户覆盖行高(1.5x)等间距设置后不丢失内容 |
| 1.4.13 Content on Hover/Focus | AA | 悬停/聚焦出现的浮层内容:可关闭、可悬停、持续存在 |
3.2 Operable(可操作)
| Criterion | Level | Summary |
|---|---|---|
| 2.1.1 Keyboard | A | 所有功能可通过键盘操作 |
| 2.1.2 No Keyboard Trap | A | 用户可用键盘离开任何组件 |
| 2.2.1 Timing Adjustable | A | 时间限制可延长或禁用 |
| 2.2.2 Pause, Stop, Hide | A | 自动更新内容可暂停 |
| 2.3.1 Three Flashes | A | 内容每秒闪烁不超过 3 次 |
| 2.4.1 Bypass Blocks | A | 提供跳过重复导航的跳转链接 |
| 2.4.2 Page Titled | A | 页面有描述性<title> |
| 2.4.3 Focus Order | A | 焦点顺序保持语义与可操作性 |
| 2.4.4 Link Purpose | A | 链接目的可从文本或上下文确定 |
| 2.4.6 Headings and Labels | AA | 标题与标签描述主题或用途 |
| 2.4.7 Focus Visible | AA | 键盘焦点指示可见 |
| 2.4.11 Focus Not Obscured | AA | 焦点元素不被粘性页眉/页脚等遮挡(2.2 新增) |
| 2.5.1 Pointer Gestures | A | 多点手势提供单指替代 |
| 2.5.2 Pointer Cancellation | A | 在 up 事件触发,除非可中止/可逆或 down 触发是必要的 |
| 2.5.3 Label in Name | A | 可访问名称包含视觉呈现的标签文本 |
| 2.5.4 Motion Actuation | A | 设备运动有 UI 替代且可禁用 |
| 2.5.7 Dragging Movements | AA | 拖拽提供点击/轻触替代(2.2 新增) |
| 2.5.8 Target Size (Minimum) | AA | 交互控件目标或间距至少 24x24 CSS px(2.2 新增) |
3.3 Understandable(可理解)
| Criterion | Level | Summary |
|---|---|---|
| 3.1.1 Language of Page | A | <html lang="...">正确设置 |
| 3.1.2 Language of Parts | AA | 不同语言内容用lang属性标记 |
| 3.2.1 On Focus | A | 聚焦不触发意外的上下文变化 |
| 3.2.2 On Input | A | 改变输入不自动触发意外上下文变化 |
| 3.2.6 Consistent Help | A | 帮助机制在各页面保持相同相对顺序(2.2 新增) |
| 3.3.1 Error Identification | A | 错误以文本形式描述给用户 |
| 3.3.2 Labels or Instructions | A | 用户输入提供标签或说明 |
| 3.3.3 Error Suggestion | AA | 对检测到的错误给出修改建议 |
| 3.3.4 Error Prevention | AA | 提交可撤销、可检查或可确认 |
| 3.3.7 Redundant Entry | A | 同一流程中不重复询问已提供信息(2.2 新增) |
| 3.3.8 Accessible Authentication (Minimum) | AA | 不用认知功能测试(拼图验证码),允许粘贴与自动填充(2.2 新增) |
3.4 Robust(健壮)
| Criterion | Level | Summary |
|---|---|---|
| 4.1.2 Name, Role, Value | A | 所有 UI 组件具备可访问名称、角色与状态 |
| 4.1.3 Status Messages | AA | 状态消息无需获得焦点即可被屏幕阅读器播报 |
版本要点(重要):
- WCAG 2.2 中4.1.1 Parsing 已废弃(始终满足),其覆盖的问题现在由 1.3.1 与 4.1.2 承接;
- 2.2 新增AAA 级准则(非 AA 必需但推荐):2.4.12 Focus Not Obscured (Enhanced)、2.4.13 Focus Appearance、3.3.9 Accessible Authentication (Enhanced);
- 前瞻:WCAG 3.0 仍是 Working Draft(2026 年 3 月),将用 Bronze/Silver/Gold 一致性级别和 "Outcomes" 取代 pass/fail 与 "Success Criteria"。它还不是正式标准,请继续以 WCAG 2.2 AA 为达标目标。
4. 法律强制背景(2026):为什么现在必须重视
| 法规 | 关键节点 | 要求 |
|---|---|---|
| European Accessibility Act (EAA) | 2025 年 6 月起在欧盟全部 27 个成员国强制执行,覆盖数字产品与服务,罚款最高300 万欧元 | 引用 EN 301 549(映射到 WCAG 2.1 AA) |
| ADA Title II (US) | 面向服务 5 万+ 人口的州/地方政府,2026 年 4 月生效;小实体 2027 年 4 月生效 | 要求 WCAG 2.1 AA |
| Section 508 (US Federal) | 引用 WCAG 2.0 AA(预计刷新到 2.1/2.2) | 联邦采购合规 |
结论:以WCAG 2.2 AA为目标可覆盖当前全部法律要求(它是 2.1 AA 与 2.0 AA 的超集)。这也是 agents/accessibility.agent.md 所定义的专家能力基线("Standards & Policy: WCAG 2.1/2.2 conformance, A/AA/AAA mapping, regional policies")。
5. ARIA 五条规则:理解所有 ARIA 反模式的前提
- 优先使用原生 HTML—— 用
<button>而不是<div role="button">。原生元素自带键盘、焦点与语义; - 不要修改被禁止修改的原生语义—— 不要给
<button>加role="heading",应使用正确的元素; - 所有 ARIA 控件必须可键盘操作—— 若用了
role="button",必须处理 Enter 和 Space 键事件; - 不要对可聚焦元素使用
aria-hidden="true"—— 对辅助技术隐藏但仍在焦点序列中,会形成 "幽灵" 元素; - 所有交互元素都需要可访问名称—— 通过 label、
aria-label、aria-labelledby或可见文本内容提供。
这五条规则在后续 A1-A8 反模式中被逐条引用(例如 A1 对应规则 2、A2 对应规则 4、A5 对应规则 1)。
6. 语义 HTML 反模式(S1-S8)
S1: 缺少lang属性(CRITICAL,WCAG 3.1.1 A)
<!-- BAD --> <html> <!-- GOOD --> <html lang="en">各框架设置位置:Next.js 在app/layout.tsx;Angular 在src/index.html;Vue/Nuxt 在app.vue或nuxt.config。
S2: 每页多个<h1>(SUGGESTION,最佳实践,支撑 1.3.1)
每页只用一个代表主题的<h1>,章节用<h2>。多个<h1>不构成严格违规,但会干扰屏幕阅读器导航。
S3: 标题层级跳跃(IMPORTANT,WCAG 1.3.1 A)
检测:<h1>直接跟<h3>(跳过<h2>)。保持逻辑嵌套h1 > h2 > h3 > h4;用 CSS 控制样式,而不是靠更换标题级别。
S4: Div 汤——没有地标元素(IMPORTANT,最佳实践,支撑 1.3.1 / 2.4.1)
<!-- GOOD --> <header>...</header> <nav aria-label="Main">...</nav> <main>...</main> <footer>...</footer>S5: 布局表格未加role="presentation"(IMPORTANT,WCAG 1.3.1 A)
用 CSS Grid/Flexbox 做布局;如必须用表格布局,加role="presentation"。
S6: 数据表格无表头(CRITICAL,WCAG 1.3.1 A)
<!-- GOOD --> <table> <caption>User list</caption> <thead> <tr><th scope="col">Name</th><th scope="col">Email</th></tr> </thead> <tbody> <tr><td>Alice</td><td>alice@example.com</td></tr> </tbody> </table>S7: 无描述性链接文本(IMPORTANT,WCAG 2.4.4 A)
检测:click here、read more、learn more、here、more、link。
<!-- BAD --> <a href="/pricing">Click here</a> <!-- GOOD --> <a href="/pricing">View pricing plans</a>这条规则与 instructions/markdown-accessibility.instructions.md 的第 1 条(描述性链接)完全同源:辅助技术可以把链接呈现为"孤立列表",因此链接文本脱离上下文也要自明。
S8: 交互元素没有语义 HTML(CRITICAL,WCAG 4.1.2 A)
检测正则:<div.*(?:onClick|@click|\(click\))。
// BAD — 不可聚焦、无角色、无键盘支持 <div onClick={handleClick}>Submit</div> // GOOD <button onClick={handleClick}>Submit</button>7. ARIA 反模式(A1-A8)
A1: 原生元素上的冗余 ARIA(SUGGESTION,ARIA 规则 2)
检测:<button.*role="button"、<nav.*role="navigation"、<a.*role="link"。<button>本身已具备role="button",删除冗余 ARIA。
A2: 可聚焦元素上的aria-hidden="true"(CRITICAL,ARIA 规则 4)
不要在aria-hidden="true"内容里放置可聚焦元素,也不要在可聚焦元素上用aria-hidden="true"。正确处理方式:
- 原生控件(
<button>、<input>)如需禁用,用disabled; <a>或[tabindex]元素应移除可聚焦性(去掉href或tabindex);- 内容应完全不可交互且对辅助技术隐藏时,使用
inert、hidden或直接从 DOM 移除。
A3: 缺少必需 ARIA 属性(CRITICAL,WCAG 4.1.2 A)
检测:role="tab"无aria-selected、role="checkbox"无aria-checked。各角色必需属性速查:tab需aria-selected;combobox需aria-expanded/aria-controls;slider需aria-valuemin/aria-valuemax/aria-valuenow;checkbox需aria-checked。
A4: 无效 ARIA 角色值(CRITICAL,WCAG 4.1.2 A)
辅助技术会忽略无效角色。常见错误:role="input"、role="text"、拼写错误。
A5: 原生 HTML 可胜任时滥用 ARIA(IMPORTANT,ARIA 规则 1)
<!-- BAD — 需要手动管理键盘、焦点与状态 --> <div role="checkbox" aria-checked="false" tabindex="0">Accept terms</div> <!-- GOOD — 所有行为内置 --> <label><input type="checkbox" /> Accept terms</label>A6: 纯图标按钮缺少aria-label(CRITICAL,WCAG 4.1.2 A)
检测:<button>只有 SVG/图标子元素且无文本或aria-label。
<!-- GOOD --> <button aria-label="Close dialog"><svg aria-hidden="true">...</svg></button>A7: 可聚焦元素上的role="presentation"(IMPORTANT,ARIA 规则 4)
浏览器会忽略可聚焦元素上的 presentation 角色。
A8: 动态内容缺少 live region(IMPORTANT,WCAG 4.1.3 AA)
检测:Toast/通知组件没有role="alert"、role="status"或aria-live。
<!-- GOOD — 向已存在于 DOM 的 live region 注入内容时会被播报 --> <div role="status" aria-live="polite">Item saved successfully</div> <!-- 错误场景用 role="alert"(assertive) --> <div role="alert">Failed to save. Please try again.</div>关于 live region 的工程实践,可参考 agents/accessibility.agent.md 中的 SPA 路由播报器示例(aria-live="polite" aria-atomic="true"的route-announcer)以及 React/Angular/Vue 三种框架适配代码。
8. 键盘与焦点反模式(K1-K7)
K1: 非原生元素上只有onClick没有onKeyDown(CRITICAL,WCAG 2.1.1 A)
用<button>替代。若必须用 div:加role="button"、tabIndex={0},并处理 Enter 与 Space 键激活。
K2: 正的tabindex值(CRITICAL,WCAG 2.4.3 A)
检测:tabindex="[1-9]\d*"或tabIndex={[1-9]\d*}。只使用tabindex="0"(加入 Tab 序列)和tabindex="-1"(仅程序化聚焦)。
K3: 无 Escape 的焦点陷阱(CRITICAL,WCAG 2.1.2 A)
优先使用原生<dialog>+showModal():它自动阻止键盘焦点移入 inert 的非对话框内容、内置 Escape 关闭,并在关闭时自动把焦点还给调用元素(若存在)。若必须自定义模态框:
- 在对话框内 Trap Tab,或对非对话框内容使用
inert属性(不要在包含对话框的元素上用inert); - Escape 关闭(除非用户确认动作是必要的);
- 关闭时把焦点还给触发元素;若触发元素已不存在,还给最合理的逻辑位置。
K4: 缺少跳转链接(IMPORTANT,WCAG 2.4.1 A)
<a href="#main-content" class="skip-link">Skip to main content</a> <nav>...</nav> <main id="main-content" tabindex="-1">...</main>.skip-link { position: absolute; top: -40px; left: 0; padding: 8px 16px; background: #000; color: #fff; z-index: 100; } .skip-link:focus { top: 0; }K5:outline: none且无替代(CRITICAL,WCAG 2.4.7 AA)
/* GOOD */ button:focus-visible { outline: 2px solid #005fcc; outline-offset: 2px; }K6: 仅鼠标交互(IMPORTANT,WCAG 2.1.1 A)
检测:onMouseOver|onMouseEnter|@mouseenter无键盘等价物。用onFocus/onBlur与onMouseEnter/onMouseLeave成对出现。
K7: 自定义模态框关闭后焦点未还原(IMPORTANT,WCAG 2.4.3 A)
保存触发元素引用(触发元素不存在时保存最合理逻辑位置),关闭时调用triggerElement.focus()。React 中的落地写法可参考 agents/accessibility.agent.md 的useRef+useEffect焦点还原片段。
9. 表单反模式(F1-F6)
F1: 输入无关联标签(CRITICAL,WCAG 1.3.1 A / 3.3.2 A)
<!-- GOOD --> <label for="email">Email address</label> <input id="email" type="email" placeholder="you@example.com" />F2: 错误信息未关联输入(CRITICAL,WCAG 3.3.1 A)
<input id="email" type="email" aria-describedby="email-error" aria-invalid="true" /> <span id="email-error" class="error">Invalid email format</span>F3: 必填项仅用颜色或*表示(IMPORTANT,WCAG 3.3.2 A / 1.4.1 A)
<label for="name">Name <span aria-hidden="true">*</span></label> <input id="name" type="text" required /> <p class="form-note">Fields marked * are required</p>F4: 无错误汇总或焦点不落在首个错误(IMPORTANT,WCAG 3.3.1 A)
提交失败时:聚焦第一个无效字段,或展示并聚焦错误汇总。这对应 agents/accessibility.agent.md 的 "Forgiving forms" 原则(保留输入、就近描述错误、提供汇总)。
F5: 无无障碍替代的 CAPTCHA(IMPORTANT,WCAG 3.3.8 AA)
使用 reCAPTCHA v3(不可见)、hCaptcha 无障碍模式或替代认证方式。永远不要在密码框上拦截粘贴或自动填充——这违反 WCAG 3.3.8。
F6: 用 placeholder 当标签(IMPORTANT,WCAG 3.3.2 A)
placeholder 永远搭配可见<label>使用——placeholder 是提示,不是标签。
10. 视觉与颜色反模式(V1-V5)
V1: 文本对比度不足(CRITICAL,WCAG 1.4.3 AA)
/* BAD — #999 on #fff 约 2.5:1 */ .text { color: #999; background: #fff; } /* GOOD — #595959 on #fff 为 7.0:1 */ .text { color: #595959; background: #fff; }V2: 仅靠颜色传达信息(CRITICAL,WCAG 1.4.1 A)
错误/成功状态必须附加次要指示符:图标、文本、图案、下划线或边框。
V3: 固定字号阻碍缩放(IMPORTANT,WCAG 1.4.4 AA)
font-size使用rem或em。根字号可以用px,但内容字号应为相对单位。
V4: 320px 下无法重排(IMPORTANT,WCAG 1.4.10 AA)
用响应式布局(Grid、Flexbox),在 320px CSS 宽度下测试,避免固定宽度容器。
V5: 动画未遵循prefers-reduced-motion(SUGGESTION,WCAG 2.3.3 AAA)
最佳实践与 AAA 增强。将非必要动画置于媒体查询内,尊重用户的减动偏好:
@media (prefers-reduced-motion: no-preference) { .card { transition: transform 0.3s ease; } .card:hover { transform: scale(1.05); } }agents/accessibility.agent.md 还提供了更激进的全局降级写法(prefers-reduced-motion: reduce下将动画/过渡时长压缩到 0.01ms),可按项目强度选用。
11. 媒体反模式(D1-D4)
D1: 信息性图片无 alt 文本(CRITICAL,WCAG 1.1.1 A)
Alt 文本决策树:装饰性 =alt="";含文字 = 包含该文字;功能性 = 描述动作;信息性 = 描述内容。
D2: 装饰性图片带非空 alt(SUGGESTION,WCAG 1.1.1 A)
装饰性图片用alt="";装饰性 SVG 加aria-hidden="true"。
D3: 视频无字幕(CRITICAL,WCAG 1.2.2 A)
<video src="/tutorial.mp4" controls> <track kind="captions" src="/tutorial-en.vtt" srclang="en" label="English" default /> </video>D4: 音视频自动播放(IMPORTANT,WCAG 1.4.2 A)
永不自动播放音频;若视频自动播放,必须静音并提供控件。
12. 框架专项修复
12.1 React / Next.js(RX1-RX4)
| 编号 | 问题 | 严重级 | WCAG |
|---|---|---|---|
| RX1 | JSX 中<label for="...">应为htmlFor | IMPORTANT | 1.3.1 / 3.3.2 |
| RX2 | SPA 路由切换无焦点管理或 live region | IMPORTANT | 4.1.3 |
| RX3 | Fragment 根节点重渲染导致焦点丢失 | SUGGESTION | 2.4.3 |
| RX4 | 注入的 HTML 未考虑 ARIA | IMPORTANT | 1.3.1 |
RX2 细节:路由切换后聚焦主标题或通过 live region 播报新页面标题。Next.js 自 v13 起内置 route announcer,依次读取document.title→<h1>→ pathname,因此确保每个页面有唯一<title>即可受益。RX3 可用keyprop 保持 DOM 身份,或用useRef+useEffect手动还原焦点。
12.2 Angular(NG1-NG4)
| 编号 | 问题 | 严重级 | WCAG |
|---|---|---|---|
| NG1 | <div>/<span>上(click)无角色与键盘支持 | CRITICAL | 2.1.1 / 4.1.2 |
| NG2 | 模态组件缺cdkTrapFocus | IMPORTANT | 2.1.2 |
| NG3 | 路由切换未用LiveAnnouncer | IMPORTANT | 4.1.3 |
| NG4 | 模板驱动表单无可访问校验 | IMPORTANT | 3.3.1 / 3.3.3 |
NG2 示例:<div class="modal" cdkTrapFocus [cdkTrapFocusAutoCapture]="true">...</div>;Angular CDK 的Dialog服务会自动处理焦点陷阱与还原。NG3 示例:
router.events.pipe(filter(e => e instanceof NavigationEnd)).subscribe(() => { liveAnnouncer.announce(titleService.getTitle(), 'polite'); });NG4 要点:将[attr.aria-invalid]与[attr.aria-describedby]绑定到表单控件状态。
12.3 Vue(VU1-VU3)
| 编号 | 问题 | 严重级 | WCAG |
|---|---|---|---|
| VU1 | 非交互元素上@click无角色与键盘 | CRITICAL | 2.1.1 / 4.1.2 |
| VU2 | v-if切换无焦点管理 | IMPORTANT | 2.4.3 |
| VU3 | v-html注入无无障碍结构 | IMPORTANT | 1.3.1 |
VU1:用<button>,或加role="button"、tabindex="0"、@keydown.enter、@keydown.space.prevent。VU2 示例:
<script setup> import { ref, watch, nextTick } from 'vue'; const showPanel = ref(false); const panel = ref(null); watch(showPanel, async (val) => { if (val) { await nextTick(); panel.value?.focus(); } }); </script>VU3:注入前清洗并校验 HTML 的标题层级、alt 文本与 ARIA 结构。这条在 React 的 RX4 中同样成立,说明"富文本渲染必须经过无障碍校验"是跨框架的通用底线。
13. 键盘交互参考
13.1 基础键位
| Key | Expected Behavior |
|---|---|
Tab | 按 DOM 顺序移动到下一个可聚焦元素 |
Shift+Tab | 移动到上一个可聚焦元素 |
Enter | 激活按钮和链接 |
Space | 激活按钮、切换复选框、选中单选按钮 |
Escape | 关闭模态框、对话框、弹出层、下拉菜单 |
Arrow Up/Down | 在菜单、列表框、单选组、标签页中导航 |
Arrow Left/Right | 在标签栏、滑块、单选组中导航 |
Home | 移到列表、菜单或标签栏的第一项 |
End | 移到最后一项 |
13.2 组件级模式(Widget-Specific Patterns)
| Widget | Tab 进入 | 内部导航 | 激活 | 退出 |
|---|---|---|---|---|
| Tab bar | 聚焦活动标签 | Arrow Left/Right | 自动或 Enter | Tab 移出 |
| Menu | 聚焦第一项 | Arrow Up/Down | Enter | Escape |
| Dialog | 聚焦第一个元素 | Tab 循环 | 按钮上的 Enter | Escape |
| Combobox | 聚焦输入框 | Arrow Up/Down | Enter 选择 | Escape 关闭 |
| Tree view | 聚焦第一个节点 | 方向键 | Enter/Space | Tab 移出 |
这张表是 agents/accessibility-runtime-tester.agent.md 中"复合组件运行时验证"(菜单、标签页、combobox、listbox、accordion 的 Escape 与方向键行为)的静态版参照。
14. 颜色对比度快速参考
14.1 文本对比度(WCAG 1.4.3 AA)
| 文本类型 | 最低比例 |
|---|---|
| 普通文本(< 18pt / < 14pt 加粗) | 4.5:1 |
| 大文本(>= 18pt / >= 14pt 加粗) | 3:1 |
| 偶然性(禁用、装饰性) | 无要求 |
14.2 非文本对比度(WCAG 1.4.11 AA)
| 元素 | 最低比例 |
|---|---|
| UI 组件(边框、图标) | 相对相邻 3:1 |
| 图形对象 | 相对相邻 3:1 |
| 焦点指示 | 相对背景 3:1 |
15. POUR 验收清单:把标准变成可执行的检查项
Perceivable(可感知)
- 所有图片有合适的 alt 文本(描述性或装饰性为空)
- 视频有同步字幕
- 页面使用语义地标:
<header>、<nav>、<main>、<footer> - 标题遵循逻辑层级(h1 > h2 > h3,无跳跃)
- 文本对比度达到 4.5:1(普通)/ 3:1(大文本)
- UI 组件对比度达到 3:1
- 信息不只靠颜色传达
- 内容在 320px 下重排且无横向滚动
<html lang="...">正确设置- 文本可放大到 200% 而不丢失内容
Operable(可操作)
- 所有功能可通过键盘访问
- 无键盘陷阱(Escape 关闭浮层)
- 首个可聚焦元素是跳转链接
- 所有交互元素有可见焦点指示
- 焦点顺序与视觉顺序一致
- 焦点不被粘性页眉/页脚遮挡
- 模态框关闭后焦点还原到触发元素
- 触控目标至少 24x24 CSS px
- 动画尊重
prefers-reduced-motion - 无每秒闪烁超过 3 次的内容
Understandable(可理解)
- 所有表单输入有
<label>或aria-label - 错误信息通过
aria-describedby关联输入 - 必填字段用
required或aria-required标识 - 提交失败时有错误汇总或焦点落在首个错误
- 聚焦或输入不触发意外上下文变化
Robust(健壮)
- 所有交互元素有可访问名称、角色与状态
- ARIA 角色带有必需属性
- 可聚焦元素上无
aria-hidden="true" - 动态内容通过 live region 播报
- SPA 路由切换会播报给屏幕阅读器
- 原生 HTML 元素上无冗余 ARIA
16. 落地到工程:从静态检查到运行时验证
这份指令的价值在于"可执行",建议按以下闭环落地:
- 编码阶段:让 Copilot 在生成代码时默认遵循本指令。仓库中 agents/accessibility.agent.md 明确要求"回答代码前先做 a11y 预检:键盘路径、焦点可见性、名称/角色/状态、动态更新的播报",并提供了 CI 示例(axe CLI + pa11y + Lighthouse CI,可在 push/PR 上运行);
- 评审阶段:按指令中的检测正则(如 S8、K1、K2、V3)快速扫描 diff,并按 PR 评审模板(语义/键盘焦点/播报/对比度/表单错误)逐项打勾;
- 运行时验证:静态合规不等于运行可用。agents/accessibility-runtime-tester.agent.md 强调"不要只停在静态语义上"——用真实键盘路径走完登录、结账等关键流程,验证焦点陷阱、错误播报与动态更新,再将失败映射回具体代码区域;
- 回归跟踪:可借助 extensions/accessibility-kanban/ 看板对无障碍 issue 做分诊,配合 agents/insiders-a11y-tracker.agent.md 跟踪上游工具链的无障碍改进。
结语
instructions/a11y.instructions.md 提供的不是零散技巧,而是一套以 WCAG 2.2 AA 为锚点、以 38+ 反模式为检查单元、以 POUR 清单为验收标准的完整无障碍工程基线。在 EAA、ADA Title II 等法规相继强制的背景下,将这份指令作为 Copilot 的全局编码规范,可以让无障碍从"事后补课"变成"默认正确"。文中所有框架修复片段均可直接复制进 React、Angular、Vue 项目,配合第 15 节清单即可完成一次完整的无障碍审计。
【免费下载链接】awesome-copilotCommunity-contributed instructions, agents, skills, and configurations to help you make the most of GitHub Copilot.项目地址: https://gitcode.com/GitHub_Trending/aw/awesome-copilot
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考