& 是完整展开外层所有嵌套路径的字符串拼接符,不截断、不降级;错误使用会导致选择器过长、语义断裂或样式失效,应配合 @at-root 隔离或手动截断父路径。

为什么 & 在多层嵌套里会拼出错误选择器
因为 & 不是“当前缩进层级的父级”,而是**完整展开外层所有嵌套路径**。它不做截断、不智能降级,只做字符串拼接。你写三层嵌套,& 就带三层前缀,哪怕你只想修饰子元素。
常见错误现象:.layout .dashboard .card { &__title { } } 编译为 .layout .dashboard .card__title —— 但 HTML 中只有 class="card__title",根本没 .layout 和 .dashboard,样式完全不生效。
-
&后不能加空格,& :hover会报错或产出.btn :hover(后代选择器),而非预期的.btn:hover - 在
@media块内用&,外层若还有嵌套,&会展开全部路径,比如生成@media (min-width:768px) { .page .main .card__body { } } - 嵌套中混用
&和无&的子选择器,如.card { .header { color: red; } &__body { } },前者变成顶层规则.header,后者才是.card__body,语义断裂
如何安全使用 & 控制拼接范围
关键不是少用 &,而是明确它拼什么、不拼什么。真正可控的方式是:用 & 显式绑定,不用缩进“猜”关系;需要局部修饰时,手动截断父路径。
- 想只拼最近一层?写成
.card { &__header { } }→.card__header;别依赖缩进让 SCSS “理解”你要什么 - 要拼子元素而非修饰符?用
& > .item或&.is-active,避免& .item(空格=后代,深度+1) - 需要脱离某层?用
@at-root提级:.modal { @at-root .u-text-center { text-align: center; } }→ 输出.u-text-center,不带.modal - 复杂拼接可读性差?改用插值:
.card { #{"&__header"} { } }或直接写.card__header { },比嵌套更直白
哪些场景下 & 必须配合 @at-root
当样式逻辑属于组件内部,但语义上不该继承任何父前缀时,硬套 & 只会让选择器越来越长、权重越来越高——这时 @at-root 不是“偷懒”,而是必要隔离。
- 工具类(如
.u-text-center、.u-mt-2):写在组件块里必须@at-root,否则产出.card .u-text-center,失去工具类意义 - 兄弟组件样式(如
.card要控制紧邻的.tooltip):.card { @at-root .tooltip { top: -8px; } },避免.card .tooltip这种强耦合 - 媒体查询内需独立输出:
@media (min-width: 768px) { .card { @at-root .card--lg { max-width: 800px; } } },防止@media { .layout .dashboard .card--lg }这种爆炸路径
嵌套超过 3 层时,& 已经不是问题,而是信号
当你发现必须靠 .a { .b { .c { &__d { } } } } 才能命中目标,说明结构正在失控。浏览器匹配 .a .b .c .d 是从右往左查所有 .d 再逐级回溯父级,4 层就是性能临界点,5 层在低端设备上滚动就卡。
- BEM 类名不是命名习惯,是匹配路径切断协议:
.card__title只依赖一个 class,浏览器零回溯 - HTML 必须真实存在
class="card__title",否则再对的 SCSS 也无效;别指望靠嵌套“模拟”DOM 结构 - 真要组合状态?用 modifier:
.card--loading .card__title比.card .card__header .card__title更轻、更可控
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











