& 是 Sass 中引用直接外层选择器的编译期占位符,非字符串拼接符;它用于生成 BEM 类名(如 .card__header),但空格或换行会导致错误后代选择器,必须紧贴书写且避免嵌套过深。

什么是 & 在 Sass 中的真实作用?
& 不是“拼接符”,而是父选择器的引用占位符。它在嵌套规则中指向**直接外层选择器**,不是字符串拼接工具。BEM 类名(如 .card__header、.card--hover)依赖精确的父子/同级关系,用错 & 会导致生成错误结构,比如 .card .card__header(带空格)而非预期的 .card__header。
关键判断:只有当你要基于外层类名「扩展」出修饰符(--)或元素(__),且**不引入空格分隔**时,& 才是安全有效的。
怎样正确生成 BEM 元素类名(__)?
必须确保 & 后紧跟两个下划线和元素名,中间不能有空格或换行;否则 Sass 会把 & 解析为独立选择器并加空格。
- ✅ 正确:
.card { &__header { font-size: 1.2rem; } }→ 编译为.card__header - ❌ 错误:
.card { & __header { /* 多了个空格 */ color: red; } }→ 编译为.card __header(无效后代选择器) - ⚠️ 注意:
&__header必须写在同一行、紧贴&,Sass 不识别换行或缩进作为连接符
怎样安全添加 BEM 修饰符(--)并组合使用?
修饰符可与元素共存,但顺序和嵌套层级决定最终类名结构。常见错误是把修饰符写在元素内部,导致生成 .card__header--large 这类合法名,却意外丢失对 .card--large 的独立样式支持。
立即学习“前端免费学习笔记(深入)”;
- 推荐分层写法:
.card { // 基础类 &--hover { background: #f5f5f5; } <p>&__header { font-weight: bold;</p><pre class="brush:php;toolbar:false;">// 元素级修饰符(可选) &--large { font-size: 1.5rem; }} }
- 避免反模式:
.card { &__header { &--large { ... } /* OK,生成 .card__header--large */ } &--large &__header { ... } /* OK,生成 .card--large .card__header */ }但不要混用:&--large.__header这种写法不存在,Sass 不支持连写修饰符和元素 - 性能提示:嵌套过深(>3 层)会让 CSS 选择器权重升高,也增加维护成本;BEM 本意是扁平化,Sass 嵌套只是书写便利,别让它掩盖语义
为什么 & 有时编译出意料之外的选择器?
根本原因在于 & 总是代表「当前嵌套层级的直接父选择器」,而不是最外层的基类。多层嵌套时容易误判作用域。
- 典型陷阱:
.card { &__body { p { & a { ... } /* 这里的 & 指的是 p,不是 .card__body */ } } }→ 编译为p a,而非.card__body p a - 修复方式:显式复用基类或用
#{&}插值(谨慎):.card { &__body { p { #{$}& a { ... } /* → .card__body p a,但可读性差,少用 */ } } } - 更稳妥的做法:把复杂组合提一层,或改用 CSS 自定义属性 + 简单类名,BEM + Sass 的优雅前提是你没在用它模拟 JS 逻辑
BEM 类名的清晰性比 Sass 嵌套技巧更重要;& 是把双刃剑——用对了省事,用偏了反而让 HTML 和 CSS 两边都难定位问题。


















