最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
如何在SCSS中使用父选择器生成CSS BEM类名
时间:2026-08-17 19:44:49 编辑:袖梨 来源:一聚教程网
@at-root #{&}__element是唯一安全生成BEM类名的方式,纯嵌套会产出带空格的后代选择器,违背扁平化原则;因&代表完整父选择器字符串,直接&__title编译为.card .card__title,而BEM要求无空格单类名.card__title。
SCSS里用 & 生成 BEM 的 block__element 类名
直接说结论:SCSS 的父选择器 & 是生成 BEM 类名最自然的工具,但必须配合字符串拼接(#{})和严格嵌套结构,否则容易产出错误层级或重复类名。
常见错误是写成这样:
.card {&__header { color: #333; }&__body { padding: 1rem; }}
这确实能编译出 .card__header 和 .card__body,但一旦加了伪类、媒体查询或嵌套子元素,& 就会带出完整路径,比如:
.card {&:hover {&__header { /* 编译为 .card:hover__header —— 错了! */ }}}
正确做法是把修饰符/状态/元素都作为独立层级处理:
- 所有
__element必须直接挂在 block 下,不嵌套在:hover或.card-content之类内部 - 需要状态修饰时,用
&.card--active而不是&:active(后者是伪类,BEM 不鼓励用伪类作修饰符) - 若真要组合状态+元素,写成
.card--active &__header,而不是靠&自动拼接
用 #{} 拼接避免 & 过度展开
当需要动态生成多个 BEM 元素(比如循环一组 icon 类型),& 无法满足,必须用 #{} 插值:
$icons: (home, search, user);.card {@each $icon in $icons {&__icon--#{$icon} {background: url('icon-#{$icon}.svg');}}}
这里 &__icon--#{$icon} 中的 & 展开为 .card,再拼上固定字符串和变量,结果是 .card__icon--home 等。关键点:
-
&只能代表当前选择器前缀,不能“截断”或“重置”,所以别指望&__item:hover在嵌套里还能干净输出 - 插值
#{}内部不能含空格或非法字符,$name建议用 kebab-case 验证 - 不要在插值里写
&,比如#{&}__bad—— SCSS 不允许,会报错Invalid CSS
BEM 修饰符 --modifier 和 SCSS 的 & 冲突点
BEM 要求修饰符与 block 同级(.card--featured),但 SCSS 嵌套时容易误写成子类:
.card {&--featured { /* 正确:编译为 .card--featured */ }&__content {&--compact { /* 错误:编译为 .card__content--compact,这不是标准 BEM 修饰符位置 */ }}}
真正合规的做法是把修饰符提一层,或用 @at-root 跳出嵌套:
.card {&--featured {@at-root .card--featured &__header {font-weight: bold;}}}
这样 .card--featured .card__header 才符合 BEM 规范 —— 修饰符作用于 block,再影响其内部元素。实际项目中更推荐直接写平级规则,避免过度依赖 @at-root。
为什么不用 @mixin 自动生成 BEM 类?
有人封装 @mixin bem($block) 来统一生成 __ 和 --,但多数场景反而增加复杂度:
- mixins 会让调用方失去对选择器结构的直观感知,调试时难以定位来源
- 参数传错(比如漏掉
$block)会导致编译出.__element这种非法类名 - BEM 类名本质是约定,不是逻辑,硬套抽象反而违背“命名即意图”的初衷
- 真正需要复用的是样式逻辑(如 spacing、typography),不是类名拼接本身
除非团队有强自动化需求(比如对接 Design Token 系统),否则手写 &__xxx + 人工校验,比引入 mixin 更可控。
BEM 类名生成看着简单,但每个 & 的展开时机、每个 #{} 的上下文、每个修饰符的挂载位置,都会在编译后暴露出来——它不报错,但会悄悄破坏命名一致性。写的时候多看一眼编译结果,比背熟语法更重要。
相关文章
- 小米4c路由器reset键在哪(小米4c路由器reset键位置详解) 08-20
- 生存33天如何选择宠物搭配 08-20
- 夸克网盘如何下载磁力链接 08-20
- 百度网盘客户端如何修改自动锁定方式 08-20
- 小米4c路由器重置怎么弄(小米4c路由器重置教程) 08-20
- 小米4c路由器支持mesh组网吗(小米4c路由器支不支持mesh组网) 08-20