屏幕阅读器无法正确识别中文语音输出,根本原因是 lang 属性未按 IETF 标准设置为 lang="zh-CN" 等有效值且必须写在 <html> 标签上;<main> 必须是 <body> 的直接子元素;标题层级不可断裂;表单与图片需严格遵循无障碍规范。

lang 属性写错或不写,屏幕阅读器就“听不懂中文”
直接后果不是报错,而是语音输出错乱:NVDA 或 VoiceOver 可能把简体中文当英文读、把“登录”读成“dēng lù”(拼音)甚至日文发音。根本原因在于 lang 值未被 AT 正确识别。
-
lang="zh"、lang="cn"、lang="ch"全部无效——IETF 标准只认lang="zh-CN"(简体)、lang="zh-TW"(繁体)、lang="zh-HK"(港澳) - 必须写在
<html>标签上,<meta>或局部lang无法覆盖根语言上下文 - React/Vue 中动态渲染时,SSR 输出的初始 HTML 必须带对
lang;用 JS 拼接lang值(比如lang={locale === 'zh' ? 'zh-CN' : 'en'})没问题,但若 SSR 阶段漏掉,首屏就已失效
嵌套或包裹在 div 里,AT 就“跳过正文”
<main> 是语义锚点,不是装饰性容器。一旦被 <div>、<section> 或 CSS Grid/Flex 容器包裹,NVDA 等工具会降级识别为普通区块,用户按 M 键快速跳转时直接跳过。
-
<main>必须是<body>的**直接子元素**,中间不能有任何父容器 - 禁止出现
<main><main>...嵌套,axe 工具会报 严重错误 - 多语言页面中,局部切换语言用
<p lang="en">...,但根<html lang="zh-CN">不可动摇
标题层级断裂,等于“砍掉导航目录树”
屏幕阅读器用户靠 H 键(H1→H2→H3)逐级跳转。一旦出现 <h2> 后紧跟 <h4>,中间缺 <h3>,他们就会误判章节结束,内容丢失率陡增。
- 常见断裂来源:
display: none隐藏了某个<h3>却没删 DOM;组件库默认用<h2>作卡片标题,嵌在<h2>主区域下,变成 H2→H2 - 每个
<section>应以<h2>或更高级别标题开头(HTML5 允许内部重置层级,但必须显式提供) - 视觉隐藏标题要用
aria-hidden="true"+ 视觉隐藏类(如visually-hidden),而非display: none
表单和图片的无障碍不是“加个 alt 就完事”
alt 文本空、重复、或写成“图片123”,会让 60.9% 的图片信息彻底丢失;表单缺少 for/id 关联或错误提示无 role="alert",75% 的辅助技术用户会卡在输入环节。
立即学习“前端免费学习笔记(深入)”;
-
<img>的alt必须描述图像内容与功能,纯装饰图用alt=""(空字符串),不是省略 -
<label>和<input>必须通过for/id显式绑定,或用<label><input></label>隐式包裹 - 表单错误要同时满足三点:视觉高亮 +
aria-invalid="true"+aria-describedby指向错误文案 +role="alert"区域实时播报
lang、<main> 或标题层级,首屏对 AT 用户已是残缺状态。



















