原生HTML元素本身就能提供系统级可访问性,前提是正确使用语义化标签、不绕开语义、不依赖ARIA“打补丁”掩盖结构缺陷;屏幕阅读器优先信任原生语义,如<button>自带焦点与交互,<nav>天然建立导航上下文,<fieldset><legend>确保表单分组可靠,标题必须用<h1>-<h6>维持逻辑层级,表单控件须为原生元素并正确绑定label,lang和charset是语音合成与字符解析的系统前提。

原生HTML元素本身就能提供系统级可访问性——前提是用对标签、不绕开语义、不靠ARIA“打补丁”去掩盖结构缺陷。
用对语义标签比加ARIA更有效
屏幕阅读器和辅助技术优先信任原生语义,而不是你手动塞的role或aria-label。比如:
-
<button>自带焦点、空格/Enter触发、disabled状态、表单集成,而<div role="button">什么都没有,得自己补全所有行为 -
<nav>被读屏软件识别为导航区,<div role="navigation">只是“看起来像”,但缺失语义继承链(比如嵌套<ul><li><a>时,<nav>会自动建立上下文) -
<fieldset>+<legend>天然形成逻辑分组,比<div aria-labelledby="xxx">更可靠:前者在表单重置、键盘导航、读屏上下文中都被一致支持
表单控件必须用原生input/select/textarea
自定义封装(如x-toggle)可以存在,但核心交互节点必须是原生表单控件:
- 任何参与表单提交、重置、验证的开关/输入,内部必须挂载真实
<input type="checkbox">或<input type="text"> - 不能只靠
shadowRoot.querySelector('input').checked = true就认为它接入了表单——必须声明static formAssociated = true,且构造函数第一行调用super() -
label必须用for属性或包裹方式绑定到原生控件,否则clicklabel 不会触发 focus + toggle,屏幕阅读器也无法建立关联
标题层级与文档流不能跳级或断裂
可访问性导航严重依赖<h1>–<h6>的逻辑嵌套,不是视觉样式问题:
立即学习“前端免费学习笔记(深入)”;
-
<h2>后面直接跟<h4>会导致读屏软件跳过中间层级,用户丢失内容结构感知 - 用
font-size模拟标题但不用<h3>,等于把内容降级为普通段落——<p class="h3">在AT眼里就是<p> - 动态渲染内容(如SPA路由切换)必须同步更新
<h1>,不能只靠JS改文本却不触发document.title或aria-live通知
lang属性和字符编码是系统级前提
这两个看似基础的设置,直接影响语音合成引擎能否正确发音、能否解析字符:
-
<html lang="zh-CN">必须存在且准确——lang="zh"或lang="cn"都不合法,会导致部分读屏软件回退到默认语言发音 -
<meta charset="UTF-8">必须在<head>最前面,否则中文、emoji等可能乱码,辅助技术直接报错或静音跳过 - 页面内多语言片段需局部标注,如
<span lang="en">API</span>,否则混用中英文时语音引擎会卡顿或错误切音
真正难的不是写role="tablist",而是克制住不用div替代button、不用span替代strong、不用JS模拟原生行为——系统级可访问性,始于对原生语义的敬畏,而非对ARIA的依赖。



















