&符号在less中代表当前嵌套路径的完整祖先选择器序列,而非简单拼接;它绑定于所在规则块的直接父级,不支持字符串切片或运行时解析。

Less中&符号的基本行为:不是简单拼接,而是完整替换
很多人以为 & 就是“把父选择器字符串粘过来”,结果写 &.hover 却得到 .btn .btn.hover(多了一层空格),实际它代表的是**当前嵌套路径的完整祖先选择器序列**。比如在 .btn { &.hover {...} } 中,& 展开为 .btn;但在 .btn:hover { &::before {...} } 中,& 展开为 .btn:hover,不是 .btn。
- 嵌套层级越深,
&包含的内容越多——它反映的是 CSS 生成时的真实选择器上下文 -
&后面不能直接跟空格,否则会触发后代选择器逻辑(如& .icon→.btn .icon) - 想截取父级某一段?
&本身不支持切片,得靠结构设计或变量辅助
用&配合属性选择器或伪类实现“局部复用”
真正需要“引用父级特定部分”,往往是为了避免重复写长命名空间,比如 BEM 风格下的 .card__header 和 .card__body。这时不要试图拆解 &,而应让父选择器本身具备可组合性:
.card {
&__header { font-size: 1.2em; }
&__body { padding: 1rem; }
&--compact &__body { padding: 0.5rem; }
}
这里 &--compact &__body 中第一个 & 展开为 .card,第二个 & 在 &__body 内部展开也为 .card,最终生成 .card--compact .card__body。关键点在于:& 总是绑定到**它所在规则块的直接父级**,而不是最外层。
- 伪类组合常见坑:
&:hover &__icon会生成.btn:hover .btn__icon,但如果你本意是.btn__icon:hover,就得写成&__icon:hover或提前定义@icon: &__icon; - 属性选择器安全:用
&[disabled]比&.is-disabled更符合语义,且不会因类名变更失效
规避&歧义的三个实操策略
当嵌套过深或需跨层级复用某段选择器时,& 容易失控。这时候硬“拆父级”不如换思路:
- 用变量存基础名:
@block: card;,然后写.@{block} { .@{block}__header { ... } },比依赖&更可控 - 抽离混合宏(mixin)处理变体:
.theme-variant(@suffix) { &--@{suffix} { ... } },调用时.theme-variant(compact),避免在&上做字符串操作 - 对必须动态拼接的场景(如主题前缀),用
replace()函数:replace(&, 'btn', 'theme-btn'),但注意这属于运行时字符串处理,无法参与 CSS 选择器逻辑校验
为什么不要尝试用~"..."拼接&来“提取父级”
有人试过 ~".#{&}__suffix" 或 ~"#{str-slice(&, 1, 5)}",结果要么编译报错,要么输出不可预测的选择器。因为 & 不是字符串变量,它是 Less 编译器在生成 CSS 阶段才解析的上下文占位符,无法被 str-slice 等字符串函数读取——这些函数只作用于已知字符串字面量。
-
&的值在编译时由嵌套结构决定,不是运行时可计算的表达式 - 所有试图“解析
&”的操作,本质都是在对抗 Less 的嵌套模型,代价是可读性下降和维护风险上升 - 真正复杂的条件选择器逻辑,建议后移至 JS(如动态加类)或用 CSS 自定义属性配合 :is() / :where()
复杂嵌套里最常被忽略的,是 & 的作用域只到直接父级这一条规则——它不会自动“向上穿透”到更外层的媒体查询或容器查询内部,除非你显式把那层也写成嵌套规则。










