合格block需脱离页面仍能独立渲染交互埋点;命名小写中划线;元素禁止嵌套子元素;修饰符避开颜色尺寸;禁用冗余父级/标签/属性选择器;类名必须静态可预测。

大型电商列表页的样式失控,往往不是因为写了太多CSS,而是类名没切到合理边界——product-list 是合法 Block,但 homepage-product-list 或 category-product-list 不是,一写就锁死上下文,后续复用必出错。
如何判断一个列表是不是合格的 Block?
核心就一条:它脱离当前页面后,是否还能独立渲染、交互、埋点?能,才是 Block。
-
product-list合格:结构稳定(标题+网格+分页)、数据源抽象(支持传入任意商品数组)、不依赖父级 DOM(比如不假设自己一定在.main-content里) -
search-result-list不合格:“search-result” 是业务位置,不是功能语义;挪到首页推荐位,类名就失焦,Sass 变量映射和 CI 校验全失效 - 命名必须小写 + 中划线:
productlist或ProductList都不行——grep查不到、VS Code 插件不补全、stylelint-selector-bem-pattern直接报错
列表里的卡片、分页、加载态怎么拆 Element?
BEM 明确禁止元素再带子元素,因为这等于把 DOM 层级硬编码进类名,破坏可移植性。
- ✅ 正确:
product-list__title、product-list__grid、product-list__pagination、product-list__loading - ❌ 错误:
product-list__item__image——这种写法会让工具链拒绝编译,CI 构建失败,且无法支持卡片在邮件模板中单独渲染 - 如果“图片下方的价格标签”总和图片强耦合,且在多个列表中重复出现,它不该是
product-list__item__price,而应抽成独立 Block:price-tag,然后在 item 里用product-list__item__price-tag
修饰符(Modifier)怎么写才不会后期全量替换?
避开颜色/尺寸类名。电商项目换主题色是常态,一旦用了 product-list--red,下次改品牌色就得全局搜改,还容易漏掉 JS 动态拼接的类名(比如 el.classList.add('product-list--red'))。
- ✅ 安全:
product-list--compact、product-list--loading、product-list--has-pagination - ❌ 危险:
product-list--red、product-list--large(尺寸应由修饰符控制,但需表达意图,如--dense而非--large) - 状态类统一用
is-前缀:is-loading、is-hidden,只作开关,不带样式逻辑;JS 控制时精准切换,避免product-list__item--loading.is-disabled这类叠加写法
为什么 .product-list .product-list__item 这种写法会拖慢滚动帧率?
浏览器 CSS 匹配是从右向左的。.product-list .product-list__item 会让引擎先找所有 product-list__item,再逐个验证是否在 product-list 内——完全废掉单类名优势,长列表滚动时 Recalculate Style 耗时飙升。
- 必须禁用的三类伪写法:
.product-list .product-list__price(冗余父级)、div.product-list__image(标签选择器前缀)、.product-list__badge[data-status="sale"](属性选择器触发 DOM 状态监听) - 正确做法只保留单类名:
product-list__price、product-list__image、product-list__badge--on-sale - 构建阶段必须加硬闸:用
stylelint-selector-bem-pattern校验,CI 中跑npx stylelint "**/*.{css,scss}"阻断违规提交
最易被忽略的是:BEM 类名必须静态可预测。SSR 场景下若服务端渲染出的类名和客户端不一致(比如用了随机 hash 或 useId()),会触发 hydration mismatch——所以 product-list__item--loading 这种名字,不能靠运行时生成,得写死在模板或常量里。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











