屏幕阅读器找不到元素的主因是DOM结构被浏览器自动修正导致语义丢失。需通过DevTools检查修复痕迹、用html-validate定位未闭合标签、确保lang属性符合IETF标准(如zh-CN)、避免空白文本节点干扰,并验证SSR输出的HTML完整性。

屏幕阅读器找不到<main>或<code><nav>?先确认DOM结构是否被浏览器硬修</H3>
<p>辅助技术依赖HTML语义角色(role)和隐式语义(如<code><main>代表主内容区),但浏览器解析器遇到未闭合标签时会强行补全,导致真实DOM和源码不一致。比如你写了<code><div><header><h1>标题</div></header>,浏览器可能把<code><header>当成普通<code><div>,<code><main>被吞进<code><section>里——阅读器根本看不到它。</p>
<ul>
<li>打开Chrome DevTools → Elements面板,找灰色斜体、缩进异常或边缘带红色高亮的节点,这是浏览器纠错留下的“修复痕迹”</li>
<li>右键任意元素 → <code>Edit as HTML
,随便改一个字符再回车,如果整个结构“跳变”,说明原始HTML已被重排过
document.querySelectorAll('main, nav, header, footer').length,结果为0?那不是没写,是被错包了用html-validate精准定位漏闭合的行号
W3C校验器能标出End tag for element "div" seen, but there were open elements这类错误,但本地开发更需要可集成的命令行工具。装html-validate后执行:
npx html-validate --config .htmlvalidate.json src/*.html
它会直接报:error: Tag <div> is not closed (no-close-tag) at line 42, col 5。注意两点:
-
.htmlvalidate.json里必须启用"no-missing-closing-tag"规则,否则默认不检查闭合 - 模板引擎(如Vue SFC、JSX)需额外配
parserOptions,否则<template>块内漏闭合会被忽略 - 别信Prettier——它格式化HTML但从不报闭合错误,
htmlWhitespaceSensitivity: 'strict'只管空格
lang属性写错比不写更伤无障碍
lang="zh"或lang="cn"看似简洁,实则触发IETF语言标签校验失败。屏幕阅读器要么跳过语言设置,用默认英语朗读中文,要么fallback到拼音式发音(“shu ju ku”而非“数据库”)。
立即学习“前端免费学习笔记(深入)”;
- 必须用
lang="zh-CN"或lang="zh-TW",地区码不可省略 - 嵌套内容需显式声明,比如英文段落加
<p lang="en">Hello</p>,否则继承父级lang值 -
<html lang="zh-CN">要放在最顶层,且不能写成<html lang="ch">——后者被多数阅读器直接忽略
修复后仍被阅读器跳过?检查里有没有<meta>混入
<meta charset="UTF-8">或<meta name="viewport">写在里,浏览器会自动把它移到外,导致开头实际是空白文本节点。部分阅读器把这种“无内容起始”当作无效文档,直接跳过整个语义结构。
- 用Elements面板展开
,看第一个子节点是不是#text(带引号的空白) - 所有
<meta>、<title></title>、<link>必须严格在内,哪怕模板引擎生成也要人工核对每条分支 - 服务端渲染(SSR)场景下,检查
renderToString()输出的HTML字符串开头是否含<html><head>完整结构,而不是从<body>开始截取
<main></main>补全了,如果它被包在意外的<div>里,role就被覆盖,语义就断了。</div>



















