:extend()更省CSS体积因其合并选择器而非复制样式,如5个按钮类继承同一基类时仅输出一行联合规则;.mixin()每次调用均原样展开全部声明,导致体积倍增。

为什么用 :extend() 会比 .mixin() 更省 CSS 体积
因为 :extend() 不复制样式,只合并选择器;而 .mixin() 每次调用都原样展开全部声明。比如你有 5 个按钮类都继承 .btn-base,用 :extend() 编译后是 .btn-base, .btn-primary, .btn-secondary, ... { ... } 一行规则;用 .btn-base() 则生成 5 套完全相同的块,体积直接翻 5 倍。
常见错误现象:
- 项目里大量写
.button-variant(@color)生成不同颜色按钮,结果 CSS 里塞满重复的border、padding、transition - 用
@import "utils.less"引入基础类,但没加(reference),导致.sr-only、.clearfix这些工具类在多个文件里被重复输出
:extend() 必须满足的三个前提条件
它不是“写了就能用”的语法糖,而是依赖编译期静态匹配的机制。不满足以下任一条件,:extend() 就会退化成无效或静默失败:
-
.target必须在当前作用域(或@import (once)引入的文件中)真实存在且已定义,不能只靠@import (reference)提供——后者让类“可见但不输出”,:extend()找不到目标就无法合并 - 不能跨文件模糊匹配:
.x:extend(.utils > .text-muted)要求.utils > .text-muted这个完整选择器必须作为一条独立规则出现过,写成.utils .text-muted就不匹配 - 不能继承伪类:
.item:hover:extend(.base:hover)会报错Extend syntax is not allowed in pseudo-classes,连&:hover嵌套里调用:extend()都不支持
什么时候该强行用 .mixin(),而不是硬套 :extend()
当你要动态控制样式细节时,:extend() 根本无能为力,硬套只会卡死开发流程:
立即学习“前端免费学习笔记(深入)”;
- 需要传参:比如
.rounded(@r: 4px)或.btn(@bg, @color),:extend()不接受任何变量或计算 - 要响应断点变化:
@media (max-width: 768px) { .mobile-nav:extend(.nav all) }看似可行,但前提是.nav在该媒体查询内已有完整定义;否则它只继承外层.nav,不会把断点内的规则带进来 - 需配合 guard 或循环生成变体:例如栅格系统
.col(@span) { width: percentage(@span / 12); },@span值不同,产出的width就不同,:extend()只能继承固定值
如何验证 :extend() 是否真正生效
别信代码写了就起效,打开编译后的 CSS 文件肉眼确认才是唯一可靠方式:
- 找并列选择器:
.icon, .btn-icon, .menu-icon { ... }—— 这是成功合并的标志 - 如果只看到
.btn-icon { ... }单独成块,没有和.icon出现在同一行,说明继承链断了,大概率是.icon被@import (reference)引入但未输出,或定义位置在:extend()之后 - 检查是否误用了通配导入:
@import "components/*.less"会让(once)失效,不同路径下的同名.icon被视为不同选择器,最终 CSS 里出现多份几乎一样的规则
真正难的不是写对语法,而是让所有参与 :extend() 的类,在编译期被同一个上下文“看见”且“确定输出”。路径、导入方式、定义顺序,三者缺一不可。


















