extend() 不等于 css 继承,它是编译期样式合并机制,将目标规则搬至被扩展选择器,生成扁平冗余选择器链,不支持伪类、属性选择器及链式扩展;mixin 更适合组件派生,支持参数化、条件分支和嵌套上下文。

Less 的 & 选择器不是“继承”,它只是父选择器引用;真正能实现样式复用与派生的,是 extend() 和 mixin ——但两者语义和行为完全不同,选错会导致样式污染或编译失败。
为什么 extend() 不等于 CSS 继承?
extend() 是 Less 编译期的样式合并机制,它把目标选择器的规则“搬”到被 extend 的选择器上,生成冗余但扁平的选择器链。它不产生 DOM 层级关系,也不支持伪类、属性选择器等动态匹配。
-
.btn { color: blue; }可被.btn-primary:extend(.btn) {}复用 -
.btn:hover无法被.btn-primary:extend(.btn:hover)正确 extend —— Less 5.0+ 仍会报错或忽略 - 多个
:extend()链式调用(如A:extend(B):extend(C))在旧版本中可能顺序错乱,建议拆成独立声明
mixin 比 extend() 更适合组件派生
组件样式往往需要参数化、条件分支和嵌套上下文,mixin 天然支持这些。例如按钮变体:基础样式 + 尺寸 + 颜色 + 状态,用 extend() 很难解耦,而 mixin 可直接传参控制。
- 定义:
.btn-base(@bg: #007bff, @size: 1rem) { background: @bg; font-size: @size; } - 使用:
.btn-primary { .btn-base(#007bff); &:hover { .btn-base(darken(#007bff, 10%)); } } - 注意:
mixin中若含&:hover,必须写成&:hover { ... },不能省略&,否则编译后丢失父级上下文
避免 extend() 导致的选择器爆炸
当多个组件都 :extend(.base),Less 会为每个派生类重复输出 .base 的所有规则,再拼上自身选择器 —— 最终 CSS 体积激增,且难以调试。
- 现象:
.a:extend(.x){}+.b:extend(.x){}→ 编译出.a, .b { /* .x 规则 */ },看似合理,但若.x含display: flex等全局性声明,就容易覆盖预期 - 更糟的是:
.c:extend(.a)会触发二次扩展,生成.c, .a, .b并列选择器,逻辑已脱离原始设计意图 - 替代方案:用
@import (reference)引入基础文件,再配合mixin按需注入,彻底规避选择器膨胀
真正要快速派生组件样式,优先写可配置的 mixin,慎用 extend();如果必须用 extend(),只用于静态、无状态、无嵌套的原子类(比如 .clearfix),且确保目标选择器永不带伪类或属性选择器。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











