bem的性能优势源于单类名选择器一次哈希查找,而非类名长度;其语义化设计使类名自解释作用域与状态,但需严守块-元素-修饰符规则,避免伪bem、跨块元素和修饰符滥用。

因为BEM把“这个样式属于谁、是什么、当前什么状态”三个问题直接塞进类名里,人眼一扫就懂,浏览器匹配也快——但前提是真正按规则写,不是只改个名字。
浏览器匹配快,不是因为名字长,而是因为没空格
BEM真正的性能优势来自单类名选择器(如 .card__title--hovered),浏览器查 class 哈希表一次命中;而 .card .card__title:hover 这种写法会让浏览器先遍历所有 p:hover 元素,再逐层往上找父级,DOM 越深越慢。
- 构建后用
grep -r "\.[a-z]\+ \.[a-z]" dist/快速揪出残留的空格选择器 - DevTools → Elements → Computed → Styles 面板里直接看:有没有空格?有没有意外混入的
div或[data-]? - Sass 中写
.card { &__title { } }是安全的,但.card { & .card__subtitle { } }就会编译出带空格的选择器
协作不翻文档,靠类名自己说话
header__logo--dark 比 logo-dark 或 dark-logo 明确得多:它是 header 块里的 logo 元素,启用 dark 变体。不用点开 HTML 或 JS 就能判断作用域和语义边界。
- Element 名必须描述结构角色,不是行为或样式:
user-card__action--delete✅,user-card__delete-btn❌(btn 是实现方式,不是角色) - Modifier 必须是可枚举的状态:
--disabled✅,--left❌(位置不是稳定状态,响应式下可能失效) - Block 名不能泛化:
product-card✅,box❌;search-form✅,form❌
团队落地时最容易破功的三个点
规范写得再好,只要这三点没守住,BEM 就退化成“带下划线的普通 CSS”。
- 伪 BEM:HTML 写
class="card card--featured",但 CSS 里只定义了.card--featured,漏掉基础块样式,删 modifier 整个组件就崩 - 跨 Block 的 Element:
card__title出现在非card容器里,或写成card__header__title(BEM 不允许 Element 嵌套 Element) - 修饰符滥用:
button--width-200px这类写法把具体值塞进类名,换单位或加媒体查询时就得新增一堆类,违背“修饰符描述状态”的原则
最常被忽略的是:BEM 不解决加载顺序问题。如果 .card__title--large 和 .card__title--small 冲突,不是命名错了,而是 CSS 文件引入顺序或层叠权重没管住——BEM 只管名字,不管谁覆盖谁。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











