必须用 document.documentelement.lang 检查实际生效值,而非 html 源码;需符合 bcp 47 小写连字符格式(如 zh-cn),禁止下划线、大写或空值;同时校验所有带 lang 的元素是否合规,避免辅助技术失效。

必须先确认 lang 属性是否真实生效,而不是只看 HTML 源码里有没有写。很多项目在 上写了 lang="zh",但实际页面加载后被 JS 覆盖、拼写错误(如 zh_CN)、或根本没走 SSR,导致浏览器和屏幕阅读器读到的仍是默认值。
用 DevTools 快速验证当前 DOM 的 lang 值
打开 Chrome 或 Edge 的开发者工具,切换到 Console 面板,直接执行:
document.documentElement.lang
返回值必须是符合 BCP 47 标准的小写连字符格式(如 zh-CN、en-US),不能是 ZH-CN、zh_cn、chinese。如果返回空字符串或 en,说明 lang 没设对或被覆盖了。
常见干扰项:
-
document.querySelector('html').getAttribute('lang')可能读到原始 HTML 中的值,但不反映 JS 动态修改后的结果;务必用.lang属性读取 - 某些框架(如 Vue/Nuxt)在 hydration 前会先渲染服务端输出的
lang,之后又被客户端逻辑重写——此时document.documentElement.lang是最终生效值 - 若返回
zh,虽语法合法,但部分辅助技术可能降级处理,建议明确写成zh-CN或zh-Hans
批量检查所有带 lang 的元素是否合规
局部 lang(如 <blockquote lang="fr"></blockquote>)必须与全局语言一致或形成合理嵌套,否则会破坏语音朗读、字体回退和拼写检查。运行以下脚本一次性列出所有问题节点:
document.querySelectorAll('[lang]').forEach(el => {
const val = el.lang;
if (!/^[a-z]{2,3}(-[a-zA-Z0-9]{2,8})*$/.test(val)) {
console.warn('Invalid lang:', val, 'on', el);
}
if (el === document.documentElement && val === 'en') {
console.info('Root lang is "en" — double-check if this matches actual page language');
}
});
重点关注:
- 值中含下划线(
zh_CN)、大写字母(ZH-CN)、空格或非法字符 → 浏览器直接忽略该属性 -
的lang是en,但页面全是中文 → SEO 和 AT 行为将按英文处理 - 某个
<pre class="brush:php;toolbar:false;" lang="python"></pre>的值是py或code→ 语法高亮和可访问性工具无法识别
自动化扫描多个页面的 lang 状态
人工点开每个页面太慢,可用 Playwright 写个轻量脚本批量抓取:
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
const page = await browser.newPage();
for (const url of ['https://site.com/zh/', 'https://site.com/en/', 'https://site.com/ja/']) {
await page.goto(url);
const lang = await page.evaluate(() => document.documentElement.lang);
console.log(`${url} → lang="${lang}"`);
const invalidLangs = await page.evaluate(() =>
Array.from(document.querySelectorAll('[lang]'))
.filter(el => !/^[a-z]{2,3}(-[a-zA-Z0-9]{2,8})*$/.test(el.lang))
.map(el => ({ lang: el.lang, tag: el.tagName }))
);
if (invalidLangs.length) {
console.error(`${url} has invalid lang values:`, invalidLangs);
}
}
await browser.close();
})();
关键点:
- 必须用
page.evaluate()在页面上下文中执行,不能在 Node.js 环境里模拟 DOM - 别只校验根节点——多语种页面常有局部
lang错位(比如切到日语页,但某段引文仍为lang="fr") - CI 中集成时,建议加超时和重试逻辑,避免因网络抖动误报
最常被忽略的是:lang 属性一旦在 HTML 解析阶段被读取,后续 JS 修改对已激活的屏幕阅读器会话基本无效。所以批量检查不能只看“有没有”,而要看“有没有在正确时机、以正确格式、出现在正确节点上”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











