应使用html[lang]属性控制语言相关样式,而非BEM语言修饰符;.button--zh等写法违背语义、导致PurgeCSS误删、SSR首屏错乱及维护成本激增;正确做法是保持BEM类名中立,用[lang="zh"] .button等属性选择器统一管理字体、方向等排版规则。

不能把语言当BEM修饰符用,比如 .button--zh 或 .header--ar —— 这类写法会直接导致样式漏渲染、PurgeCSS误删、SSR首屏错乱,且违背BEM语义契约。
为什么.button--zh是错误的类名
语言不是按钮自身的状态,而是整个文档的上下文属性。同一个 .button 在中文页和阿拉伯语页都存在,只是字体、文字方向、字间距等排版表现不同。把它硬编码成 .button--zh,等于把全局环境当成组件变体,带来三类实际问题:
-
.button--zh类若未出现在服务端渲染的 HTML 中,PurgeCSS 会直接删掉对应 CSS 规则,首屏中文按钮就没了字体定义 - JS 切换语言时动态加
.button--ar,但 SSR 首屏已输出lang="zh",中间存在样式空窗期 - 所有组件都要配一套语言修饰符:
.card--zh、.input--ar、.nav--es……维护成本指数级上升
正确做法:用html[lang]锚定语言上下文
BEM 类名保持中立,只表达结构与状态;语言专属排版规则全部交给属性选择器统一控制。这是唯一能兼顾 SSR、构建工具、RTL 和可维护性的方案。
- HTML 根节点始终带
lang属性:、 - BEM 类名不掺杂语言信息:
.button、.button--primary、.card__title - 排版样式统一写在
[lang="zh"] .button、[lang="ar"] .button下,只覆盖字体、text-align、line-height、font-feature-settings等真正因语言而异的属性 - RTL 布局必须用
[lang="ar"]或[dir="rtl"]控制,不要写.button--rtl—— 按钮本身没有“右向布局”状态
复杂点在于字体栈和加载时机的耦合
中文字体名必须加双引号:"Noto Sans SC",否则编译后解析失败;字体栈顺序决定 fallback 行为,中文必须放最前:["Noto Sans SC", "system-ui", "sans-serif"]。更关键的是:lang 属性必须由服务端或初始化 JS 同步写入 document.documentElement,不能靠后续 JS 异步 patch —— 否则 CSSOM 构建时无法匹配 [lang="zh"] 规则,首屏排版就会回退到默认字体,方块或左对齐问题集中爆发。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











