zeroz-lab/unified-skills · Archived

verify-frontend-accessibility

可访问性保障——WCAG 2.1 AA 合规。当构建 UI 组件、表单、导航或交互?

First seen Jun 23, 2026

Installation

$ npx skills add zeroz-lab/unified-skills --skill verify-frontend-accessibility

Stronger alternatives

This repository is archived — consider an actively maintained alternative.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from zeroz-lab/unified-skills · top by installs.

npx skills add zeroz-lab/unified-skills

Browse all from zeroz-lab/unified-skills

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 16
License MIT
Default branch master
Open issues 0
Status Archived

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 8,863 B
  • docs SUMMARY.md 195 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 3 installs

SKILL.md

Accessibility — 可访问性保障

入口/出口

  • 入口: 构建 UI 组件、表单、导航、或交互元素
  • 出口: 通过 a11y 检查的组件
  • 指向: a11y 验证通过后继续 build 或进入 /review
  • 前置加载: CANON.md + build-frontend-ui-engineering/SKILL.md
  • 输出路径: 通过 a11y 检查的组件 → verify-workflow-review(进入审查)或继续 build

何时不使用

  • 变更不涉及用户可交互 UI、表单、导航或视觉呈现
  • 只是纯文案、后端、脚本或数据迁移
  • 需要先实现 UI,当前还没有可检查的界面

Iron Law

<HARD-GATE>

每个 UI 元素必须可被键盘访问、屏幕阅读器理解和视觉辨识。
WCAG 2.1 AA 是最低准入门槛,不是锦上添花。
没有通过 a11y 审查的 UI = 不可交付的 UI。

</HARD-GATE>

目标: WCAG 2.1 AA

AA 是达到的最低商业标准。AAA 在特定方面努力但不作为全局要求。

三大支柱

1. 键盘导航

每个交互元素必须通过键盘可达和可操作:
├── Tab → 进入元素
├── Shift+Tab → 离开元素(回到上一个)
├── Enter / Space → 激活按钮/链接
├── Escape → 关闭模态框/下拉
├── Arrow Keys → 在选项间移动(菜单、tabs、单选组)
└── 焦点顺序 → 逻辑顺序(DOM 顺序匹配视觉顺序)
// Bad: div 不可通过键盘操作
<div onClick={handleClick}>删除</div>

// Good: button 自动有键盘支持
<button onClick={handleClick}>删除</button>

焦点陷阱: 模态框打开 → 焦点困在模态框内(Tab 循环不逃逸)。模态框关闭 → 焦点回到触发元素。

2. 屏幕阅读器

// 图像: 始终有 alt
<img src="logo.png" alt="Company Name" />
// 装饰性图像: alt="" (空,不是缺失)

// 图标按钮: aria-label
<button aria-label="关闭对话框">
  <XIcon />
</button>

// 表单: label 和 input 关联
<label htmlFor="task-title">任务标题</label>
<input id="task-title" type="text" />

// 错误关联
<input id="email" aria-describedby="email-error" />
<span id="email-error" role="alert">请输入有效的邮箱地址</span>

ARIA 规则: 原生 HTML 元素(<button><input><a>)已有隐式 ARIA。不需要加 role="button"<button>。ARIA 仅在不使用原生元素时才需要。

3. 视觉

对比度 (WCAG AA):
├── 普通文本: ≥ 4.5:1
├── 大文本 (≥18px bold 或 ≥24px): ≥ 3:1
└── UI 组件/图形: ≥ 3:1

颜色不是唯一的信息传达方式:
├── 错误状态: 红色边框 + 图标 + 文字
├── 成功状态: 绿色边框 + 图标 + 文字
├── 链接: 下划线(不仅仅是颜色)
└── 图表: 图案/纹理 + 颜色

关键检查

表单

  • 每个 input 有 label
  • 必填字段有指示(星号 + "required" 文字,非仅颜色)
  • 错误信息关联到对应 input(aria-describedby
  • 提交前验证错误焦点跳转到第一个错误字段

图像

  • 内容图像有描述性 alt
  • 装饰性图像有 alt=""
  • SVG 图标有 aria-label 或用 aria-hidden="true" 隐藏

导航

  • 页面有 skip-to-content 链接
  • 当前页面/位置有 aria-current="page"
  • 主导航有 <nav> landmark

页面结构

  • 有语义标题层次(h1 → h2 → h3,不跳级)
  • <main><header><footer> landmarks
  • 信息不依赖纯视觉呈现("右侧面板"、"绿色按钮")

动态内容

  • Toast/通知有 role="alert"aria-live
  • 加载状态被宣告(aria-busy 或加载提示)
  • 模态框打开时焦点移到模态框内

测试工具

# 自动检查
npx axe-core          # 静态分析
npx pa11y-ci          # CI 集成
npx lighthouse        # Chrome DevTools 中的 Accessibility 审计

# 手动测试
Tab 遍历页面          # 键盘导航是否有逻辑顺序?
VoiceOver / NVDA     # 屏幕阅读器能否理解页面?

常见说辞

说辞 现实 后果
"可访问性最后加" 从第一个组件做起。最后加 = 永远不会加 = 重新写一遍。 最后加 = 全局 DOM 结构不支持键盘导航和 ARIA,改造工作量 = 重写前端 40-60%。项目永远不会做。
"用户基本没有残障人士" 可访问性也服务所有人:键盘用户、移动端、慢网络、临时障碍(手臂骨折)。(可访问性提升所有用户的体验) 全球 ~15% 人口有某种形式的残障。忽略 a11y = 排除 15% 潜在用户 + 法律合规风险(ADA 诉讼平均赔偿 $50K+)。
"自动检查通过了就行" aXe 能检测 ~30% 的问题。键盘手动测试和屏幕阅读器手动测试不可替代。 自动工具遗漏的 70% 包括焦点陷阱、语义结构、屏幕阅读器体验——这些是真实用户的日常障碍。
"用 div 比用 button 方便" div 没有键盘操作、没有 ARIA role、没有焦点管理。用 button。 div 做的按钮对键盘用户完全不可操作,对屏幕阅读器用户完全不可见——功能对他们来说不存在。
"颜色区分足够" ~8% 的男性有某种形式的色弱。信息永远不只通过颜色传达。 色弱用户看不到红色错误提示 → 提交错误数据 → 业务流程中断。纯颜色区分 = 对 8% 用户功能失效。

违反字面规则就是违反精神。 没有灰色地带。

输出模板

# Accessibility Audit Report — 可访问性审计报告

## 元信息
- **审查者**: [姓名/角色]
- **组件/页面**: [组件名或页面路径]
- **审查日期**: YYYY-MM-DD

## 自动检查结果
- **aXe**: [通过 / 发现 N 个违规] — 违规列表见下方
- **Lighthouse Accessibility**: [分数] — 最低准入: 90
- **pa11y-ci**: [通过 / 发现 N 个问题]

## 自动检查违规详情

| # | 规则 | 级别 | 位置 | 描述 | 修复状态 |
|---|------|------|------|------|---------|
| 1 | color-contrast | Critical | L42 | 文本对比度 2.8:1 < 4.5:1 | 🔴 待修复 |
| 2 | label | Critical | L78 | input #email 缺少 label | 🔴 待修复 |
| 3 | aria-valid-attr | Important | L91 | aria-label 值为空字符串 | 🟡 建议修复 |

## 手动检查结果

### 键盘导航
- [ ] Tab 顺序逻辑性: [通过 / 未通过 — 具体问题]
- [ ] 模态框焦点管理: [通过 / 未通过 — 具体问题]
- [ ] 所有交互元素键盘可达: [通过 / 未通过 — 具体问题]

### 屏幕阅读器
- [ ] 语义结构完整: [通过 / 未通过 — 具体问题]
- [ ] ARIA 标注正确: [通过 / 未通过 — 具体问题]
- [ ] 动态内容宣告: [通过 / 未通过 — 具体问题]

### 视觉
- [ ] 对比度达标: [通过 / 未通过 — 具体问题]
- [ ] 颜色不是唯一信息方式: [通过 / 未通过 — 具体问题]

## 审查结论
- **通过**: 自动检查评分 ≥ 90 + 手动检查全部通过
- **阻止**: Critical 违规未修复或手动检查关键流程失败

## 红旗 — STOP

- 只用颜色(红/绿)指示状态 —— 没文字、没图标
- 表单 input 没有 label(或 placeholder 作为唯一标签)
- 模态框打开后焦点没有移动进去
- Tab 顺序在视觉和逻辑上不一致
- 图像没有 alt(且不是装饰性的)
- 视频没有字幕
- `onClick` div 充当按钮(用 `<button>`)

## 验证失败处理

| 失败场景 | 处理方式 |
|---------|---------|
| aXe/Lighthouse 评分 < 90 | 标记具体违规项。逐条修复后重新运行自动检查。不得降级准入标准。 |
| 键盘无法完成主要流程 | 阻止交付。检查 Tab 顺序、焦点陷阱、交互元素键盘操作。修复后手动验证完整流程。 |
| 模态框焦点未正确管理 | 阻止交付。打开时焦点必须移入模态框、Tab 循环不逃逸、关闭时焦点回到触发元素。 |
| 表单 input 缺少 label | 阻止交付。每个 input 必须有 visible label 或 aria-label。placeholder 不可作为唯一标签。 |
| 颜色对比度 < 4.5:1(普通文本)| 调整颜色或增加辅助标识(图标、文字、边框)。对比度不达标 = 信息不可辨识。 |

## 验证清单

- [ ] Tab 顺序有逻辑性,所有交互元素可达
- [ ] 模态框焦点管理正确(进入+关回)
- [ ] 所有内容图像有 `alt`
- [ ] 颜色不是唯一信息传达方式
- [ ] 表单有 label、错误关联、必填指示
- [ ] aXe / Lighthouse Accessibility 审计通过(得分 ≥ 90)
- [ ] 键盘能完成主要用户流程