HTML无障碍必须从<html lang="zh-CN">起层层对齐WCAG,依赖语义标签而非堆砌ARIA;lang须精确到地区码,禁用placeholder替代label,所有交互元素需键盘可达、状态同步、焦点可控。

HTML中无法靠“加几个属性”就建成无障碍标准体系——它必须从文档结构、语义选择、状态同步到交互逻辑层层对齐WCAG原则,否则aria-label写得再全,tabindex加得再多,也挡不住焦点跳失、读屏器静默或键盘断连。
从<html lang="">开始强制声明语言
没设lang的页面,屏幕阅读器会按默认语言(通常是系统语言)朗读,中英文混排时极易错读拼音、乱切词、忽略声调。这不是体验问题,是基础解析失败。
-
lang必须精确到地区码,比如<html lang="zh-CN">,不能只写zh或留空 - 多语言页面内嵌内容需局部覆盖:如英文段落加
<p lang="en">,否则NVDA可能把“iOS”读成“艾欧斯”而非“I-O-S” - 动态切换语言时,仅改
document.documentElement.lang不够,还要触发aria-live播报语言变更,否则视障用户无感知
用原生语义标签替代div + role
写<div role="button">不如直接用<button>——前者要手动补tabindex、keydown、aria-pressed,后者浏览器原生支持所有交互和语义。
- 导航区域优先用
<nav>,不是<div role="navigation">;主内容区必须是<main>,不是<section role="main"> -
<table>用于真实二维数据关系,纯布局用CSS Grid/Flex;滥用role="grid"反而破坏读屏器表格导航逻辑 - 自定义组件(如
<my-tabs>)若无法退化为原生语义,必须实现完整的WAI-ARIA Authoring Practices规范,包括aria-activedescendant、焦点循环、arrowkey行为等
表单控件必须绑定<label>且禁用placeholder替代
placeholder不是label,它在输入后消失、不被JAWS/NVDA稳定读出,且无法通过CSS高对比度模式保留——这是WCAG 3.3.2明确禁止的“仅靠视觉提示传达信息”。
立即学习“前端免费学习笔记(深入)”;
- 每个
<input>、<select>、<textarea>必须有显式<label for="id">,或包裹在<label>内 - 隐藏的
<label>要用visually-hidden类(非display: none),否则读屏器完全跳过 - 必填字段在
<label>中用<span aria-hidden="true">*</span>标星,再用aria-required="true"告诉辅助技术
所有交互元素必须可键盘到达并反馈状态
一个tabindex="0"只是起点,真正的问题在按下Enter/Space后有没有响应、状态变化是否被aria-live捕获、焦点是否被正确管理——尤其在模态框、下拉菜单、拖拽列表中,错误会立刻导致用户“卡死”。
- 模态框打开后,焦点必须立即移入第一个可聚焦子元素,并用
inert或aria-hidden="true"锁住背景内容 - 下拉菜单展开时,用
aria-expanded="true"同步状态,同时监听Escape关闭并回退焦点到触发按钮 - 拖拽排序必须提供完整键盘路径:
Tab进入 →↑↓移动焦点 →Space抓取 →↑↓定位 →Enter放置,全程更新aria-grabbed和aria-live
最常被跳过的环节是状态同步:aria-checked变了但没发aria-live播报,aria-expanded更新了但焦点没跟上,或者role="alert"区域被CSSopacity: 0藏起来——这些细节不处理,整个体系就塌在最后一环。



















