a11y-ops 是一套 Web 无障碍(accessibility)端到端工作技能,围绕 WCAG 标准与多司法管辖区的法律义务展开,既提供合规知识,也提供审计与修复的具体流程。它指出无障碍已从质量偏好变成带截止日期的法律要求,但常用工具能发现的问题不到一半,因此工作重点在于知道自动化在哪里停止。
【用途】 帮助回答「我们的网站合规吗」——取决于适用司法管辖区、标准版本与截止日期;开展能发现真实失败而非仅产出分数的审计;修复组件库中只支持鼠标的自定义控件;修复使用占位符当标签、仅用红色表示错误等导致屏幕阅读器与键盘用户流失的表单;处理 outline: none、焦点陷阱、模态框/下拉框/日期选择器焦点管理;撰写真实且可辩护的可访问性声明;以及将无障碍接入 CI,使修复成果得以保持。
【两个决定一切的原则】
- 自动化工具大约只发现 30–40% 的 WCAG 失败。绿色 axe 运行结果是下限而非结果,其余需要键盘和人工测试。
- 使用原生元素。button、a href、input、select、details 自带可聚焦、键盘激活、正确角色与状态播报。目录中几乎每个失败都来自用 div 替换它们并重建部分能力。推论是 ARIA 第一规则:无 ARIA 优于糟糕的 ARIA。
【标准与期限】 建议几乎所有项目以 WCAG 2.2 Level AA 为目标,它满足下列各制度。EAA(欧盟)适用 EN 301 549 v3.2.1 → WCAG 2.1 AA,自 2025 年 6 月 28 日起适用,2026 年为首个完整监管年,v4.1.1 预计 2026 年移至 WCAG 2.2,罚款约 €5k–€500k。ADA Title II(美国)适用 WCAG 2.1 AA,截止日期延长至 2026 年 4 月 20 日:2027 年 4 月 26 日(人口≥5 万)、2028 年 4 月 26 日(较小)。UK PSBAR 适用 WCAG 2.2 AA,公共部门,要求可访问性声明。EAA 具有域外效力。合规是逐页且全有或全无的,一个 AA 标准失败即页面不合规,没有部分分数或百分比。
【工作流——四遍,从最便宜开始】
- 静态源码扫描(数秒,CI 中):scripts/scan-a11y.py src/,退出码 10 表示有发现。可用 --min-severity serious、--json。可捕获缺少 alt、未标注输入、占位符当标签、仅图标控件无名称、非交互元素上的点击处理、正 tabindex、标题跳级、可聚焦元素上的 aria-hidden、无标题 iframe、未静音自动播放、重复 id 等。退出码:0 干净、2 用法错误、3 路径缺失、5 无可扫描内容、10 有发现。它读取源码,看不到计算后的对比度或条件渲染标记,是预过滤器而非审计。服务端模板(.twig、.blade.php)需先保存渲染后 HTML 再扫描。
- 自动化 DOM 扫描(数分钟,按路由):对渲染页面运行 axe-core,最好在已有 Playwright 套件内运行。替代:pa11y-ci 处理 URL 列表,Lighthouse 快速分类。要扫描状态而非仅页面。
- 键盘测试(10 分钟,收益最高):放下鼠标,Tab 遍历整页,检查焦点顺序、指示器是否始终可见且不被吸顶头遮挡(2.4.11)、鼠标可达是否键盘可达、能否退出每个模态框且焦点返回触发元素、跳过链接是否移动焦点。
- 屏幕阅读器测试(30 分钟以上):认真测试一个组合,如 Windows 上 NVDA + Firefox 或 macOS 上 VoiceOver + Safari。
【常见失败】 按频率排列,含从类层面而非实例层面移除的修复:表单字段无程序化标签、仅用颜色表示错误、仅图标控件无名称、键盘失效的自定义控件、outline: none、焦点陷阱、为字号选择标题、错误而非缺失的 alt 文本、无意义链接文本、撒谎的 ARIA、目标小于 24×24(2.5.8)、无法停止的动效、缺少跳过链接和地标。三个要点:可聚焦元素上的 aria-hidden="true" 会创建无无障碍名称的可聚焦元素,必然违反 4.1.2;tabindex 大于 0 会全局覆盖 DOM 顺序,仅 0 和 -1 值得使用;live region 必须在内容到达前存在于 DOM 中。
【服务端渲染 CMS 站点(Craft CMS + Twig)】 CMS 站点没有单一文件拥有页面,布局、分部、Matrix 循环、编辑器富文本与插件表单各自写入部分。应在产生失败的层修复(模板、字段设置或插件配置),并测试渲染后页面。三个陷阱:asset.getImg() 在 alt 为空时丢弃 alt,而无 alt 的 img 违反 1.1.1;CKEditor 默认允许 h1–h6,Formie 表单标题硬编码为 h2,都会破坏标题大纲;将 axe 过滤到 WCAG 标签会丢弃 heading-order 与地标规则(它们标记为 best-practice)。
【可访问性声明】 发布声明是 EAA 义务的一部分而非可选。从 assets/accessibility-statement.template.md 开始。不要过度声称。「部分合规」并列出问题与修复日期是正常且可辩护的;未经审计的「完全合规」则不是。
【不覆盖的内容】 对比度与调色板数学(WCAG 1.4.3、APCA)→ color-ops;图标与 logo 细节 → icon-ops;将 axe 接入浏览器测试套件 → playwright-ops;原生移动端无障碍(UIKit/Android API);法律建议——涉及金钱的合规决策需要律师。
【参考资料】 references/wcag-conformance.md(标准映射、EAA 日期与罚款、ADA 延期、合规声明的承诺);references/audit-workflow.md(四遍流程、工具对比、报告方式、回归门禁);references/common-failures.md(十二个反复出现的失败及前后代码);references/server-rendered-templates.md(Craft CMS + Twig 细节)。另有 scripts/scan-a11y.py 脚本与 assets/accessibility-statement.template.md 模板。