应使用 :lang() 而非 [attr|="value"] 进行多语言样式区分,因前者支持语言继承、语义匹配且兼容 rtl 等复杂场景,后者仅字符串匹配、不继承、不处理缺失 lang 的嵌套元素。

为什么不用 [attr|="value"] 做多语言样式区分
它不适合——这个选择器本意是匹配「以 value 开头且后接连字符或结尾」的属性值,比如 [lang|="zh"] 能命中 lang="zh" 或 lang="zh-CN",但**不支持子语言继承、无法处理缺失 lang 的嵌套内容、也不兼容 RTL 语言的复杂匹配需求**。更重要的是,现代浏览器对多语言样式的原生支持早已转向语义更准、行为更可预测的 :lang() 伪类。
:lang() 和 [lang|="xx"] 的关键区别在哪
两者表面都“按语言前缀匹配”,但底层逻辑完全不同:
-
:lang(zh)是语义匹配:只要元素自身或任意祖先有lang="zh-CN"、lang="zh-HK"等,且未被更具体的lang覆盖,就生效;它尊重语言继承链 -
[lang|="zh"]是字符串匹配:只看当前元素的lang属性值是否以zh开头并紧接-或结尾,完全不关心父级设置,也不向下传递 - 若某段落没写
lang,但父容器是<article lang="ja"></article>,p:lang(ja)仍生效;而p[lang|="ja"]直接失效 -
:lang()在 CSS 变量、@font-face条件加载、伪元素内容中均可使用;[lang|="xx"]仅限基础选择器场景
实际项目中该用哪个?
直接用 :lang(),除非你明确需要绕过语言继承做硬隔离(极少见):
- 中文简体/繁体统一调行高、禁用连字:
:lang(zh) { line-height: 1.6; font-variant-ligatures: none; } - 仅对日文段落启用特定字体栈:
p:lang(ja) { font-family: "Noto Sans CJK JP", sans-serif; } - 阿拉伯语表格单元格右对齐+特定字体:
td:lang(ar) { text-align: right; font-family: "Tajawal", "Segoe UI", sans-serif; } - 避免写
[lang|="zh"]替代方案——它无法匹配lang="zh"(无连字符),必须写成[lang="zh"], [lang|="zh"]才完整,反而增加维护成本
容易被忽略的坑
:lang() 生效的前提非常具体,漏掉任一环都会静默失败:
- HTML 根元素或目标元素上必须真实存在
lang属性,仅靠<meta http-equiv="content-language">或 HTTP header 无效 - SPA 中动态切换语言时,必须显式修改
document.documentElement.lang,而不是只改某个 class 或 state -
:lang(en)不会匹配lang="en-US"的子元素,如果子元素自己没设lang且父级是lang="en-US",它仍能命中——这是继承行为,不是 bug - 服务端渲染时,若
lang值来自用户偏好而非路由,务必校验其格式合法性(如拒绝lang="x-hacker"),否则:lang(x-hacker)规则可能意外生效
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











