bem本身不定义目录结构,仅规范类名命名;所谓“bem目录”实为与7-1等架构绑定的工程实践,核心目的是防止.class覆盖、@import错序及跨block样式污染,强制components/下每个block独占文件且modifier必须基于block声明。

.block、.block__element、.block--modifier),**没有所谓“BEM官方推荐的目录结构”**。所有声称“BEM标准目录”的说法,实际都是工程实践者把 BEM 和某种分层架构(如 7-1、ITCSS)绑定后的产物。
真正起约束力的是协作场景下的工程需求:避免 .button 覆盖 .card,防止 @import 顺序错乱导致 .button--primary 失效。目录结构是为这些风险服务的,不是为 BEM 而存在。
为什么不能只按 BEM 命名就随便建文件夹?
常见错误是把所有 Block 都塞进 components/ 下一个平级目录:_button.scss、_card.scss、_header.scss 全堆在一起。结果是:
- 改按钮禁用态时,得在 3 个文件里翻
.button--disabled是否被重复定义 -
@import "components/_button"和@import "components/_theme"顺序一颠倒,.button--primary就可能被[class*="--"]这种泛义规则覆盖 - 新人无法判断
_card-button.scss是独立 Block 还是card的 Element —— 实际上它不该存在,.card__button必须写在_card.scss里
7-1 架构才是 BEM 在文件层的实际落地要求
当项目需要多人协作、长期维护时,7-1 不是“可选方案”,而是强制分层手段。它的每一层都对应明确职责,且直接约束 BEM 文件的存放位置和内容边界:
-
base/:放_reset.scss、_variables.scss、_mixins.scss—— 这里禁止出现任何 BEM 类名字符串 -
components/:每个 Block 独占一个文件,如_button.scss,且只允许定义.button、.button__icon、.button--primary,不允许跨 Block 引用或嵌套 -
layout/:写.header、.grid这类页面容器,可用 BEM,但不封装交互逻辑(JS 行为归组件自己管) -
pages/:仅允许组合已有 Block,如.page-home .card--featured,禁止新增.card规则
每个 _block.scss 文件必须满足的 BEM + Sass 约束
光有目录分层不够,单个文件内部也容易踩坑。比如 Modifier 写成独立选择器,会导致样式断裂:
// ❌ 错误:Modifier 脱离 Block 上下文
.button--primary {
background-color: #007bff;
}
// ✅ 正确:Modifier 必须基于 Block,用 & 连接
.button {
padding: 0.5em 1em;
border: none;
}
.button--primary {
@extend .button; // 或直接写 &--primary { ... }
}
- Block 样式必须是顶层声明,所有 Element/Modifier 都要基于它派生
- Element(如
.button__icon)极少需要,除非语义上确实不可拆分 - Modifier 必须用
&--xxx或@extend继承 Block 基础样式,否则禁用态可能丢失 padding/border - 禁止在
_button.scss里写.modal__close—— 跨 Block 的样式必须由各自文件负责
现代构建环境下,@import 已基本淘汰
哪怕目录结构再规范,如果还在用 @import 拼接样式,BEM 的隔离性就形同虚设:
-
@import会阻塞编译、绕过缓存、破坏 HMR,Vite/Webpack 中极易导致热更新失效 - Sass 推荐用
@use "base/variables" as *替代@import,变量作用域更安全 - 路径必须是相对或别名路径(如
@use "@/styles/components/button"),绝对路径/src/styles/...在某些配置下直接 404 - PostCSS 用户应启用
postcss-import插件,否则@import "./mixins.css"会被原样输出到最终 CSS 中
_block.scss 文件成为语义闭环:它定义什么、继承什么、禁止写什么,都要靠目录分层+预处理器约束+构建工具配合来守住。一旦某个人在 pages/ 里偷偷重写 .button,整个 BEM 的隔离前提就崩了。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











