:lang()选择器需html元素显式声明合法lang属性才生效;:lang(zh)匹配zh、zh-cn等前缀,而[lang="zh"]仅精确匹配;应按语种拆分font-family并确保lang同步。

必须在 HTML 元素上显式声明合法的 lang 属性,否则 :lang() 规则完全不生效——浏览器不识别内容语言,只认这个属性值。
为什么 :lang(zh) 没换字体?先查 lang 属性有没有、对不对
最常见失效原因是: 根节点没写 lang,或子元素(比如一段日文)没继承/没显式声明。例如:
-
<p>こんにちは</p>即使页面全是日文,只要没lang="ja",:lang(ja)就不会匹配 -
不规范,应写成或(BCP 47 要求) - Safari 对动态 JS 修改
document.documentElement.lang无效,必须服务端注入或构建时写死
:lang(zh) 和 [lang="zh"] 的匹配逻辑完全不同
:lang() 是前缀匹配,[lang] 是精确字符串匹配——这点直接影响多区域中文站点的健壮性:
-
:lang(zh)能匹配lang="zh"、lang="zh-CN"、lang="zh-TW"、lang="zh-Hans" -
[lang="zh"]只匹配字面等于"zh"的属性,lang="zh-CN"完全不中 - 推荐写法:
html:lang(zh), html:lang(zh-CN), html:lang(zh-TW) { ... },避免漏掉变体
字体声明顺序错了,会直接导致英文段落用上中文字体
把中日韩字体堆进全局 body 的 font-family,是回退陷阱的高发区:
- 错误写法:
body { font-family: "Noto Sans CJK SC", sans-serif; }→ 所有文本(包括英文)都优先尝试该字体,缺字就 fallback 到系统默认英文字体,标点错位、字重发虚 - 正确做法:按语言拆开,每条
:lang()规则里只放该语种强支持的字体,且排最前::lang(zh) { font-family: "PingFang SC", "Noto Sans SC", sans-serif; }:lang(ja) { font-family: "Yu Gothic", "Hiragino Kaku Gothic Pro", sans-serif; } - 别用
SimSun这类旧字体:OpenType 特性缺失,引号、连字、字距微调全失效
混合内容和 Web Font 加载容易被忽略的细节
JS 渲染或 i18n 框架(如 React + i18next)更新文本后,lang 属性不会自动同步:
- data-i18n 属性或
textContent替换不会触发:lang()重新计算,必须手动补lang,例如:el.setAttribute('lang', 'ja') - Web Font 加载慢?
:lang()本身不控制加载,但你要管好@font-face:
确保不同:lang()规则引用的font-family名互不冲突(比如别都叫"BaseFont")
用<link rel="preload" as="font">提前加载关键语种字体 - Safari 要求
lang必须出现在目标元素自身或其任意祖先上——不能是 JS 插入的,服务端直出最稳
真正麻烦的不是写几行 :lang(),而是确保每个语种变体都有对应声明、每个字体栈都经过系统实测、每次语言切换都同步了 DOM 层的 lang 属性——漏掉任何一环,用户看到的就是方块、错位或闪动。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











