&不是“当前元素”,而是编译时静态拼出的上一层选择器字符串,只认紧邻父级规则,不依赖缩进;如.card { .header { &__title { } } }编译为.header__title而非.card__title,因&指向.header。

为什么 & 拼接出的选择器根本不存在
因为 & 不是“当前元素”,而是编译时静态拼出的**上一层选择器字符串**。它不关心你视觉上缩进几层,只认紧邻的父级规则。比如:.card { .header { &__title { } } } 编译结果是 .header__title,不是 .card__title——& 此刻指向的是 .header,而非你以为的 .card。
常见错误现象:
- 写
.btn { .icon { &--small { } } },期望生成.btn--small,实际是.icon--small - 在媒体查询里嵌套多层后用
&,结果拼出一长串带空格的选择器,如.layout .sidebar .nav__item:hover
关键检查点:
-
&前有没有空格?有空格就是后代选择器,没空格才是拼接 - 是否在
@at-root、@keyframes或@function里误用了&?这些上下文没有父选择器,会报错 - 用 VS Code 直接打开编译后的 CSS 文件,Ctrl+点击跳转,看它到底生成了什么
&:hover 为什么生成了超重选择器
& 会展开整个父链,不只是类名。比如 .modal .content .form { &:hover { } } 编译为 .modal .content .form:hover(权重 0-3-1),而你真正想控制的可能只是 .form 自身状态。
这会导致后续样式难以覆盖,比如 .form--highlight(0-1-0)完全压不过它。
安全做法:
- 把伪类绑定到最外层语义类上,如
.form:hover { },而不是嵌套里写&:hover - 避免在 ID 或属性选择器后使用
&:hover,例如#header { &:focus { } }→#header:focus(权重 100+,基本锁死) - 需要复用?抽成工具类:
.u-hover-bg-blue { &:hover { background: blue; } },再单独加到目标元素
BEM 场景下 & 拼接非法结构
直接用 #{&}__item 看似方便,但一旦父选择器含条件(如 .menu.is-active 或媒体查询内规则),& 就会把整段带进来,生成 .menu.is-active__item 这种违反 BEM 规范的类名——修饰符 --modifier 必须作用于块本身,不能挂到子元素上。
正确路径:
- 显式传入块名,用
@mixin bem($block)控制拼接源头 - 子元素用
element(),修饰符用modifier(),禁用&手动拼接 - BEM 不允许
__嵌套,如.card__header__title是错的;应改用.card__header-title或拆成独立块
为什么 DevTools 里看不到 & 生效的规则
不是 & 失效,而是整段 Sass 代码压根没编译进去。常见原因:
- Sass 变量未定义,导致条件编译被跳过(如
@if $theme == "dark" { ... }中$theme为空) -
:not()嵌套过深,比如&:not(.a):not(.b:hover)编译出非法选择器,浏览器直接丢弃,DevTools 里该规则灰掉且无报错 - 父容器不可交互:比如
div默认无法触发:hover,需加tabindex="0"或换用button
最省事的验证方式:打开编译后的 CSS 文件,搜索你预期生成的选择器字符串。没出现,问题就不在 &,而在编译流程或逻辑分支。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











