瀑布流必须定义为独立 masonry Block,子元素命名需语义化(如 masonry__preview),状态统一用 masonry--state-{value} 修饰符,JS 类名操作须封装 cn 函数确保 BEM 合规。

瀑布流容器必须是独立 Block,不能套用父级前缀
多列瀑布流(如 Masonry)不是“列表的变体”,而是一个具备完整布局逻辑、可复用、有明确边界的 UI 单元。把它写成 list__masonry 或 grid__columns 是典型误判——这会让瀑布流样式被绑定到某个页面区域,失去跨组件复用能力,也破坏了构建时提取和主题切换的路径。
✅ 正确做法:定义为独立 masonry Block,所有子结构都直属于它:
-
masonry—— 容器本身,负责 column-count、column-gap 等布局控制 -
masonry__item—— 每个瀑布流项,仅声明 break-inside: avoid;不设宽高、定位或 margin -
masonry__sizer(可选)—— 用于 JS 计算列宽的占位元素,仍属本 Block 范畴
❌ 错误示例:product-list__masonry、feed__item、masonry-item(缺双下划线,破坏工具链识别)
元素名必须表达语义,不能照搬 HTML 标签或 CSS 属性
瀑布流中常见视觉单元(如卡片、图片、标题)容易被直接命名为 masonry__card、masonry__img,但这违反 BEM 原则:元素名应描述“它是什么”,而非“它用什么标签实现”或“它长什么样”。
立即学习“前端免费学习笔记(深入)”;
比如一个瀑布流项内含主图和操作按钮,它们不是 masonry__img 和 masonry__btn,而是:
-
masonry__preview—— 表达“预览区域”,可渲染 img / video / placeholder -
masonry__actions—— 表达“操作区”,内部可嵌套独立buttonBlock -
masonry__meta—— 表达“元信息区”,含标题、时间、标签等
⚠️ 注意:masonry__preview--loading 合法,masonry__preview--w-200 违规——修饰符必须表达状态或意图,而非尺寸值。
Modifier 要收敛状态维度,避免视觉耦合
瀑布流常需响应不同场景:加载中、空态、错误态、触底提示。这些不该用 masonry--loading + masonry--empty + masonry--error 并列堆砌,而应统一收口为单一状态修饰符 masonry--state-{value},由 JS 控制 class 切换。
理由很实际:
- 避免 CSS 文件里重复写
masonry--loading .masonry__item、masonry--empty .masonry__item等冗余规则 - 防止多人协作时各自加
--no-data、--nodata、--empty-state导致类名失控 - 便于后续接入状态机或 React 的
useReducer统一驱动
示例结构:
<div class="masonry masonry--state-loading"> <div class="masonry__item"></div> <div class="masonry__item"></div> </div>
对应 CSS 中只需一条规则:.masonry--state-loading .masonry__item { opacity: 0.6; }
JS 动态控制类名时,必须封装 Block 常量
瀑布流高度依赖 JS(如 Masonry 库、ResizeObserver 监听、滚动加载),最容易在拼接类名时出错:漏双下划线、大小写混用、空格缺失、modifier 值未转义。
❌ 危险写法:el.className = `masonry__item ${isActive ? 'masonry__item--active' : ''}`(无防错、不可维护、CI 下易挂)
✅ 推荐封装:
const BLOCK = 'masonry';
const cn = (e, m) => `${BLOCK}${e ? '__' + e : ''}${m ? '--' + m : ''}`;
// 使用
cn('item', 'active') // → 'masonry__item--active'
cn('preview') // → 'masonry__preview'
cn(null, 'state-error') // → 'masonry--state-error'
这个 cn 函数可全局复用,且能配合 stylelint-selector-bem-pattern 在提交前校验输出是否合规。真正难的不是写对一次,而是在 37 个瀑布流实例、5 个主题分支、12 个 CI 环境里始终写对——靠人盯不如靠约束。


















