Front-End-Checklist 无障碍规则实战:lang 与 xml:lang 属性一致性(WCAG 2.1 SC 3.1.1)
【免费下载链接】Front-End-Checklist🗂 The essential checklist for modern web development, for humans and AI agents项目地址: https://gitcode.com/gh_mirrors/fr/Front-End-Checklist
导读:本文基于开源仓库 Front-End-Checklist 中
skills/html-xml-lang-mismatch/SKILL.md及其配套规则文档,系统讲解<html>元素上lang与xml:lang属性必须保持一致这一无障碍规则。你将掌握三种文档类型(标准 HTML5、XHTML、polyglot 混合文档)各自的属性声明要求、BCP 47 语言标签的校验方法,以及如何把该规则接入你团队的代码审查与自动化审计流程。
规则概述:同一元素上的两个语言属性必须完全一致
当同一个元素上同时出现lang和xml:lang两个属性时,它们的值必须完全相同。这条规则在 Front-End-Checklist 仓库中被归类为accessibility(无障碍)类别下的visual子类,元数据中标注的优先级为medium(中等)、难度为beginner(入门)、预估耗时5 分钟(见 规则内容文件 的 frontmatter)。
HTML Living Standard 与 W3C 的语言声明指南都将这两个属性的取值不一致视为对解析器和用户代理(user agent)发出的矛盾语言信号——同一份文档,HTML 解析器读到的是一种语言,XML 解析器读到的却是另一种语言。
仓库中该规则有三个信息载体,职责分工明确:
- skills/html-xml-lang-mismatch/SKILL.md:Agent/LLM 可消费的技能指令文件,包含 check / fix / explain / code review 四个阶段的提示词模板;
- skills/html-xml-lang-mismatch/references/rule.md:给人类开发者看的完整规则说明,含代码示例、适用场景表格、最佳实践与验证方法;
- packages/content/rules/en/accessibility/html-xml-lang-mismatch.mdx:规则的结构化数据源,frontmatter 中定义了 whyItMatters、prompts、sources、relatedRules 等字段,供网站渲染与规则引擎消费。
为什么这条规则重要
屏幕阅读器会选错语音库
屏幕阅读器使用lang属性来选择正确的语音配置(voice profile)和发音引擎。如果lang和xml:lang取值不一致,基于 XML 的处理程序(包括部分 EPUB 阅读器和较旧的辅助技术)可能优先采用xml:lang的值,导致实际朗读语言与页面意图不符。规则文档给出了一个典型场景:法语文本被英语语音包朗读,对法语盲人用户而言输出完全无法理解。
解析器兼容性
- HTML 解析器使用
lang; - XML 解析器使用
xml:lang; - polyglot 文档(同时合法于 HTML 与 XML)必须同时满足两者。
翻译工具与拼写检查
浏览器自动翻译功能依赖lang检测源语言;拼写检查器也依据语言声明选用正确的词典规则。语言声明错误会连锁影响这些工具。
WCAG 合规要求
这条规则对应WCAG 2.1 SC 3.1.1(Language of Page,页面语言):要求每个网页的默认人类语言可以通过编程方式确定。lang服务于 HTML 解析器,xml:lang服务于 XML 解析器;当文档必须同时以 HTML 和 XML 解析时(polyglot),两个属性必须同时存在且一致。不一致意味着文档的语言声明取决于"谁在读它",这正是无障碍合规审计必须拦截的问题。
Check:如何检查是否存在不一致
按照 SKILL.md 中的 check 提示词,检查流程分三步:
- 检查属性存在性:检查
<html>元素上是否同时存在lang和xml:lang; - 比对取值:若两者都存在,确认其值完全一致——必须包含子标签(subtags)级别的比对,
en与en-US属于不匹配; - 校验 BCP 47 合法性:确认语言标签本身是合法的 BCP 47 语言标签(如
en、en-US、fr、zh-Hant)。
任何差异(包括主语言标签不同、方言子标签不同、标签非法)都应被标记为违规。
Fix:如何修复
修复策略取决于文档类型:
- 值不一致:将
lang与xml:lang都更新为同一个合法的 BCP 47 语言代码,且该代码必须匹配文档内容的主要语言; - 标准 HTML5 文档(以
text/html提供):直接移除xml:lang,它在此场景下是多余的; - XHTML 或 polyglot 文档:保留两个属性,并确保它们完全一致。
代码示例:正确与错误的写法
来自 references/rule.md 的完整示例:
<!-- ✅ Correct HTML5 document: only lang needed --> <!DOCTYPE html> <html lang="en"> <!-- ✅ Correct polyglot/XHTML document: both present and identical --> <html lang="fr" xml:lang="fr"> <!-- ❌ Incorrect: values differ --> <html lang="en" xml:lang="fr"> <!-- ❌ Incorrect: dialect mismatch — en vs en-US --> <html lang="en" xml:lang="en-US"> <!-- ❌ Incorrect: invalid language tag --> <html lang="english">注意最后一种情况:english不是合法的 BCP 47 标签,正确写法是en。方言子标签也必须一致——en-GB与en之间同样构成不匹配。
什么时候该用哪个属性
规则文档给出的决策表是这条规则最核心的实操依据:
| 文档类型 | lang | xml:lang |
|---|---|---|
标准 HTML5(text/html) | 必需 | 不需要 |
XHTML(application/xhtml+xml) | 推荐 | 必需 |
| Polyglot HTML(同时合法于两种解析) | 必需 | 必需(值相同) |
判断一份文档是否属于 polyglot,核心看它的 MIME 类型与DOCTYPE声明。现代前端项目绝大多数属于第一行"标准 HTML5"场景。
最佳实践
- 新 HTML5 项目只用
lang:在<html>上只写lang,省略xml:lang; - 保持同步:如果出于兼容性考虑添加了
xml:lang,必须始终与lang保持一致; - 子标签一致性:若一个属性写了
en-GB,另一个也必须写en-GB,不能简写为en; - 以渲染结果为准:规则文档的 Exceptions 部分提醒——在把静态代码异味当作阻断项之前,先评估实际渲染体验;交互时序、浏览器行为与辅助技术的实际输出往往决定问题严重程度。不是每个次要无障碍问题都值得同等的修复优先级,应优先处理最直接阻碍感知、操作或理解的项;同时避免为了满足规则而堆砌多余的标记或 ARIA,能通过更简单的语义实现消除问题时,就选择更简单的方案。
源码级实践:Front-End-Checklist 自身如何声明语言
规则文档还给出了"源码级最佳实践"的实证。Front-End-Checklist 的 Web 应用是一个 Next.js 项目,其根布局遵循"标准 HTML5 只用lang"的推荐做法:
- apps/web/app/layout.tsx 中,根
<html>元素声明为<html lang="en" ...>,只包含lang属性,没有xml:lang; - apps/web/app/global-error.tsx 中全局错误页同样使用
<html lang="en" contenteditable="false">【免费下载链接】Front-End-Checklist🗂 The essential checklist for modern web development, for humans and AI agents项目地址: https://gitcode.com/gh_mirrors/fr/Front-End-Checklist
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考