可访问性必须嵌入每个敏捷迭代的MVP,而非上线前补救;需在PR中同步提交label/alt、注入aria-live、用axe-devtools+pa11y-ci双层自动拦截,并严守语义化、触摸目标、焦点管理等底线。

敏捷迭代里HTML可访问性不是“额外任务”
可访问性必须嵌入每个迭代的最小可行交付单元(MVP),而不是等上线前集中补救。很多团队把 alt、label、aria-expanded 当作“验收后事项”,结果每次回归都得重写 DOM 结构,反而拖慢节奏。
- 每次新增表单字段,
label必须和input同时提交,不接受“先用 placeholder 顶着” - 所有图片在 PR 中必须带
alt值;装饰图明确写alt="",而非留空或删掉属性 - HTMX 或服务端渲染的动态内容,需同步注入
aria-live="polite"区域——不能靠 JS 后补
用工具链把可访问性检查变成保存动作
人盯人评审效率低还易漏,真正能跟上敏捷节奏的是编辑器+CI 双层自动拦截。VS Code 装 axe-devtools 插件后,保存 HTML 文件会实时标出缺失 alt 或未绑定 label 的节点;CI 阶段跑 pa11y-ci 扫描全站关键路径,失败即阻断合并。
-
pa11y-ci配置里禁用“跳过 iframe”选项——第三方嵌入内容(如地图、视频)常是可访问性黑洞 - 不要只测首页,至少覆盖登录页、核心表单页、搜索结果页三类典型页面
- 错误日志里出现
ARIA attribute is not allowed: aria-hidden="false"这类提示,说明用了无效值,需立刻修正而非忽略
语义化标签落地要分优先级,不强求一步到位
全量重构 div 套娃为语义标签会卡住迭代,但关键导航与主内容区必须严格落地。比如 <main></main> 必须唯一且只包用户真正要操作的部分,否则屏幕阅读器 M 键跳转直接失效——这属于不可妥协的底线。
- Next.js / Remix 等框架布局组件中,禁止在
Layout里写<main></main>;子路由页面自行提供,且只一个 -
<nav></nav>必须包裹全部导航链接,不能只包顶部菜单而漏掉页脚“关于我们”这类次要入口 - 用
eslint-plugin-jsx-a11y检查 JSX 模板,对img缺alt、button缺type等问题零容忍
移动端触摸目标和键盘焦点管理最容易被忽略
桌面端验证通过的 HTML,在手机上可能完全不可用。48×48px 触摸目标不是设计稿要求,而是 WCAG 强制标准;而 tabindex 的误用(比如给 div 加 tabindex="0" 却没配键盘事件)会让 TalkBack 用户陷入焦点陷阱。
立即学习“前端免费学习笔记(深入)”;
- 所有按钮、链接、表单控件,CSS 中必须设
min-width: 48px; min-height: 48px;,哪怕视觉上只显示图标 - 树状菜单、下拉筛选器这类交互组件,必须用
role="tree"+role="treeitem",不能仅靠 class 名模拟 - HTMX 触发的局部刷新后,焦点必须手动恢复到合理位置(如新加载的表单第一个
input),否则 VoiceOver 会停留在空白区域
真正难的不是写对一行 alt,而是让每个成员在写第一行 HTML 时就默认带上可访问性意识——这靠培训不如靠工具链拦截和 PR 模板强制项。一旦某次迭代因 aria-label 缺失被 CI 拦住,下次所有人就会记得先填再提交。



















