真正符合bem的关键是每个class仅承担一种语义角色且不依赖dom位置,如card__title正确而card__header__title错误;禁止混搭角色(如btn btn__icon btn--loading),元素与修饰符须分属不同标签;重构时优先处理硬编码类名、高频修改css中的泛用类及工具类,并通过classnames库或常量管理避免手拼出错。

HTML里class写法怎么才算真正符合BEM
不是类名带__或--就合规。关键看每个class是否只承担一种语义角色,且不依赖DOM位置。
常见错误现象:card__header__title、nav__item__link——这类三段式命名看似“更细”,实则把结构假设硬编码进类名,违反BEM“元素不嵌套元素”的铁律。
-
card__title才对:哪怕它在DOM里嵌在card__header内部,语义上仍是card的直属元素 -
nav__item和link(独立block)并存,比nav__item__link更利于复用 - 禁止
class="btn btn__icon btn--loading"这种混搭:一个元素只能有一个角色,btn__icon是element,btn--loading是modifier,不能同时加在同一标签上(除非是不同用途,如按钮本身+图标状态)
重构老项目HTML时,哪些class必须优先动
别一上来就全局替换.btn→button。先定位三类高危类名,否则JS会直接报错、样式大面积崩塌。
- 被
document.querySelector('.nav')这类硬编码调用的类名——必须加别名过渡,比如保留.nav作alias,新代码只用main-nav - git blame显示高频修改的CSS文件(如
common.css),里面.sidebar大概率已混入业务逻辑,得先用wrapper隔离,再逐步拆解 - 工具类统一前缀迁移:
.clearfix→u-clearfix,和BEM业务类物理隔离,避免命名污染
Vue/React组件里怎么避免手拼BEM类名出错
写className={`button ${isDisabled ? 'button--disabled' : ''}`看着简单,但漏空格、拼错字符串、状态组合爆炸(button--primary button--disabled vs button--primary--disabled)全是线上隐患。
- 用
classnames库:classNames('button', { 'button--primary': isPrimary, 'button--disabled': isDisabled }) - 组件内定义常量:
const BUTTON_MODIFIERS = { primary: 'button--primary', disabled: 'button--disabled' },避免散落字符串 - 禁止在
class属性里写点号或空格:class="button .button--primary"是非法HTML,浏览器静默丢弃后半部分
BEM类名在构建工具里被截断或合并怎么办
Vite/Webpack默认启用cssnano的mergeLonghand或reduceTransforms,可能把button button--primary button--disabled压成button button--primary,导致修饰符失效。
- 检查构建配置,关闭这两项优化
- JS中永远用数组拼接:
className={["button", isPrimary && "button--primary"].filter(Boolean).join(" ")} - Vue模板中用数组语法:
:class="['button', isPrimary ? 'button--primary' : '']",避免字符串模板硬拼
__前,得想清楚这个节点是不是真的只属于当前block、能不能独立存在、删掉父容器后它是否还能渲染——这些判断没法靠工具自动完成,全靠人盯。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











