:lang(zh)等伪类需html中合法lang属性(如lang="zh-cn")才生效,不支持下划线或空格分隔;它语义匹配且继承模糊,优于[lang="zh"]的精确字符串匹配。

直接用 :lang(zh)、:lang(en)、:lang(ja) 就能生效,但前提是 HTML 里真有对应语言声明 —— 很多页面样式“没反应”,根本不是选择器写错了,而是 lang 属性压根没传下去或写法非法。
为什么 :lang(zh) 有时不匹配中文元素
最常见原因是 HTML 结构里漏了 lang 属性,或者写了错误格式。比如:lang="zh_cn"(下划线)不合法,必须是 lang="zh-CN"(短横线);lang="zh zh-CN" 是无效写法,:lang() 不支持空格分隔多值。
另一个隐形陷阱:如果只在 设置顶层语言,但内部一段英文是 <p>Hello</p> 且没加 lang="en",那 p:lang(en) 永远不会命中 —— 浏览器不会“猜”语言,只查显式声明或继承链。
- 子元素自动继承父级
lang值,所以<section lang="en"><p>Hello</p></section>中的p会被:lang(en)匹配 - 但跨语言混排时(如中英双语评论),必须给具体文本容器加
lang,例如<span lang="en">API</span> - React/Vue 项目注意 SSR 阶段是否同步输出了正确的
lang值,否则首屏 CSS 规则不触发
:lang(zh) 和 [lang="zh"] 的关键区别
:lang(zh) 是语义匹配,支持子语言继承和模糊匹配;[lang="zh"] 是纯字符串等值匹配,非常脆弱。
比如父元素是 <div lang="zh-TW">,里面一个没设 <code>lang 的 <p></p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/code/12093" title="CSS婚礼策划服务机构宣传网站模板"><img
src="https://img.php.cn/upload/webcode/000/000/018/178607072210981.jpg" alt="CSS婚礼策划服务机构宣传网站模板" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/code/12093" title="CSS婚礼策划服务机构宣传网站模板" class="overflowclass">CSS婚礼策划服务机构宣传网站模板</a>
<p class="overflowclass">CSS婚礼策划服务机构宣传网站模板是一款适合提供婚礼策划和婚庆服务机构宣传网站模板下载。提示:本模板调用到谷歌字体库,可能会出现页面打开比较缓慢。</p>
</div>
<a rel="nofollow" href="/xiazai/code/12093" title="CSS婚礼策划服务机构宣传网站模板" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>:
-
p:lang(zh)✅ 能命中(因继承 + 模糊匹配) -
p[lang="zh"]❌ 不会命中(父级值是zh-TW,不等于zh) -
p[lang~="zh"]✅ 可作为兼容 fallback(~="zh"表示空格分隔的单词匹配,能覆盖zh-TW、zh-CN)
所以通用规则一律用 :lang(zh),只有需要精确控制某地区变体(如仅对 zh-HK 加繁体标点)时,才叠加 [lang="zh-HK"]。
字体堆栈怎么写才真正适配不同语言
别在 body 或 html 上用 :lang() 设全局 font-family,除非整站单语言。中日韩、拉丁、阿拉伯文字所需的字体族差异太大,强行统一反而导致回退失败或渲染错乱。
推荐按语言粒度定义字体堆栈,并利用继承降低冗余:
:lang(zh), :lang(ja), :lang(ko) {
font-family: "PingFang SC", "Hiragino Sans GB", "Noto Sans CJK SC", sans-serif;
}
:lang(en), :lang(de), :lang(fr) {
font-family: "Inter", "Segoe UI", system-ui, sans-serif;
}
:lang(ar), :lang(fa) {
font-family: "Tajawal", "Segoe UI", sans-serif;
direction: rtl;
}
注意几点:
- 中日韩共用一套堆栈没问题,但需确保字体文件实际支持全部字符(比如
"Noto Sans CJK SC"支持简体中文,但不支持阿拉伯数字排版优化) - 英文堆栈里放
system-ui是为了适配 macOS/iOS 的 San Francisco、Windows 的 Segoe UI -
:lang(ar)必须配direction: rtl,仅靠text-align: right无法改变内联流向
容易被忽略的排版细节:行高、断行、连字符
字体只是表层,真正影响可读性的是排版行为。不同语言对行高、断行、标点悬挂、连字符的处理逻辑完全不同。
- 中日韩建议更高行高:
:lang(zh), :lang(ja), :lang(ko) { line-height: 1.6; } - 日文启用严格断行:
:lang(ja) { line-break: strict; }(避免把助词拆到行首) - 英文开自动连字符:
:lang(en) { hyphens: auto; },中文禁用::lang(zh) { hyphens: none; } - 英文引号独立定义:
:lang(en) q::before { content: "“"; } :lang(en) q::after { content: "”"; }
这些规则一旦写进 CSS,就完全脱离 JS 控制,纯靠浏览器解析 lang 属性自动应用 —— 但这也意味着,如果某个 <blockquote lang="fr"></blockquote> 里嵌了一段中文 <span>你好</span> 却没设 lang="zh",那段中文就会沿用法语的行高和断行规则,视觉上明显突兀。










