:lang()伪类必须依赖HTML的lang属性才生效,浏览器不会自动识别文本语言;应于根元素声明默认语言,并对多语言内容显式添加lang属性,支持子标签匹配但需注意连字符规则。

lang() 伪类必须依赖 lang 属性才生效
不写 lang 属性,:lang() 就是摆设。浏览器不会自动识别文本语言,也不会根据内容推测 lang 值——哪怕你写了“Bonjour”或“こんにちは”,:lang(fr) 或 :lang(ja) 依然不会命中。
实操建议:
- 在根元素(如
<html>)上声明默认语言:<html lang="zh-CN"> - 对多语言混排的内联内容,显式加
lang:<span lang="en">GitHub</span> - 避免只靠
hreflang或Content-LanguageHTTP 头——这些不影响:lang()匹配
:lang() 支持子标签匹配,但要注意连字符规则
:lang(zh) 能同时匹配 lang="zh"、lang="zh-CN"、lang="zh-TW",这是它的核心优势;但反过来,:lang(zh-CN) 不会匹配 lang="zh"。
常见错误现象:
立即学习“前端免费学习笔记(深入)”;
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
- 写了
q:lang(zh-CN) { quotes: "「" "」"; },但<q lang="zh">没生效——因为没覆盖到父级语言标签 - 误以为
:lang(en-US)可以匹配lang="en"——实际不行,子标签必须显式存在或完全一致
推荐做法:对需要统一处理的语系,用最宽泛的主标签,比如 :lang(zh)、:lang(ja)、:lang(ko)。
中日韩文字排版常用样式切换示例
真正实用的场景不是“换颜色”,而是调整标点挤压、引号、行尾禁则等。例如中文引号和英文引号的 quotes 值不同,日文需要禁止单字换行。
/* 中文环境用中文引号 */
:lang(zh) q { quotes: "“" "”" "‘" "’"; }
<p>/<em> 日文环境用日文引号 + 禁止单字断行 </em>/
:lang(ja) q {
quotes: "「" "」" "『" "』";
line-break: strict;
}</p><p>/<em> 英文保持默认,但可显式重置 </em>/
:lang(en) q { quotes: '"' '"' "'" "'"; }
注意:line-break 在 Safari 中需配合 -webkit-line-break 才可靠;quotes 在旧版 Edge 中支持有限,但现代 Chromium/Firefox/Safari 均已稳定支持。
不要用 :lang() 替代 CSS-in-JS 的语言检测逻辑
:lang() 是纯 CSS 层匹配,它不触发重排重绘以外的任何行为,也不能读取或响应语言变化。如果你在 SPA 中动态切换语言(比如通过 JS 修改 document.documentElement.lang),样式会立刻更新——但仅限于已声明的 :lang() 规则;它无法触发事件、调用函数或修改自定义属性。
容易被忽略的地方:
- 服务端渲染页面若未正确输出
lang属性,客户端 JS 补设后,:lang()才开始生效——中间有样式闪动风险 - 使用
translate属性或 i18n 库(如 i18next)时,别默认它会同步设置lang——多数库不自动操作 DOM 属性 -
:lang()无法区分“界面语言”和“内容语言”,比如一个英文 UI 里嵌入中文段落,必须给那段加lang="zh"才能触发对应样式


















