scss中&符号代表父选择器的完整展开结果,只在嵌套内有效,保留空格及关系符(如>、+),不可用于跨元素推导或模拟交集选择器。

SCSS中&符号拼装复合选择器的底层规则
&不是简单地“拼字符串”,它代表的是**父选择器的完整展开结果**,且只在嵌套作用域内有效。比如.btn里写&--primary,编译后是.btn--primary;但若父选择器是.card > .header,&__title会变成.card > .header__title——注意中间的>也被保留了。
常见错误现象:.nav { &__item { &__link { ... } } } 会生成.nav__item__link,但实际 DOM 中__link往往不是__item的子元素,而是其内部的a标签,这就导致样式失效。
- 父选择器含空格(如后代选择器)时,
&会展开为带空格的完整选择器,可能触发浏览器性能警告 - 父选择器含
>、+、~等关系符时,&会原样保留,不能靠它“跳级”或“跨兄弟”定位 - 想生成
.nav__item a,必须显式写出a,不能依赖&自动推导
交集/并集类复合选择器在SCSS中的安全写法
纯 CSS 的交集选择器如button.primary或input[type="text"],在 SCSS 嵌套中不能直接用&.primary来模拟——因为&指向的是外层选择器,而.primary是独立类名,二者逻辑上不构成嵌套关系。
正确做法是把这类组合提至顶层,或用@at-root脱离嵌套上下文:
.form {
@at-root button.primary {
background: #007bff;
}
@at-root input[type="text"] {
border: 1px solid #ddd;
}
}
- 避免在深层嵌套中强行用
&拼接属性选择器,如&[type="submit"],容易因父选择器过长导致 specificity 过高 - 并集选择器(逗号分隔)不能用
&生成,必须手写,例如h1, h2, .title无法用嵌套+&一次产出 - 如果多个组件共用同一组交集规则,建议抽成 mixin,而不是靠
&硬连
避免嵌套过深导致选择器爆炸的实际控制线
SCSS 编译后,每层嵌套都会叠加父选择器。三层嵌套(如.modal .content .body p)已接近可读与性能临界点;四层开始,Chrome 开发者工具会标黄提示“选择器过长”,Firefox 可能触发重排降级。
面包屑、表单控件、卡片网格等典型场景,推荐结构层级严格卡在三层以内:
.breadcrumb {
&__list { // 第一层:组件容器
&__item { // 第二层:单个条目(语义节点)
a, span { // 第三层:内部元素 —— 不再用 & 嵌套,直接写标签
color: #666;
}
}
}
}
- 第四层意图(如想单独控制
a:hover)应平级声明:.breadcrumb__item a:hover,而非&__item { a { &:hover { ... } } } - 伪元素
::before/::after不算嵌套层级,但需注意它不继承父级&的上下文,必须显式写出宿主类名 - 用
SCSS-lint或stylelint配置max-nesting-depth: 3可强制拦截越界写法
用&拼状态类和变体时的兼容性陷阱
&--disabled、&__item--active这类 BEM 风格变体看似简洁,但要注意:IE11 及部分旧版 WebView 不支持多类名连写选择器的高效匹配,且当类名动态拼接(如 JS 添加is-open)时,&.is-open无法覆盖&--open的 specificity。
更稳妥的做法是统一前缀,显式控制权重:
- 状态类统一用
is-前缀:&.is-active、&.is-disabled,和 JS 操作保持一致 - 避免混用
--和.两种变体语法,否则调试时 class 列表难以快速定位 - 如果项目需支持 IE,禁用
&:not(...)嵌套写法,改用独立选择器 +@at-root,因为:not在旧引擎中对嵌套解析不稳定
最易被忽略的一点:SCSS 的&不会做选择器归一化,.btn &__icon和.btn__icon在 specificity 上完全等价,但前者在 DOM 移动时极易断裂——写之前先问一句:这个关系在 HTML 结构里是否真正稳定存在。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











