:extend()能减小CSS体积的前提是目标选择器真实输出、路径一致且加all;否则退化为复制样式,体积反而增大。

直接结论:用 :extend() 能减少重复代码量,前提是目标选择器真实输出、路径一致、且加 all;否则它会退化成复制整块样式,体积反而更大。
为什么 :extend() 有时不减体积反而增重
常见错误是写了 .btn-primary:extend(.btn),但编译后 CSS 里仍出现孤立的 .btn-primary { ... } 块——说明继承失败,Less 自动 fallback 成了样式复制。
- 目标
.btn是通过@import (reference) "base.less"引入的:它根本没输出,:extend()找不到目标,只能复制 -
.btn定义在.btn-primary之后:Less 不支持“向后查找”,必须前置定义 -
.btn被嵌套在.wrapper { .btn { ... } }里:非顶层选择器无法被:extend()匹配 - 用了
@import "./base"和@import "../shared/base"混用:路径不一致,Less 当作两个文件处理
:extend(.target all) 和 :extend(.target) 的实际差异
不加 all 只合并顶层声明;加了才把 &:hover、&:disabled、&.active 这类嵌套规则一并收进来。漏掉 all 是体积省不下来的核心原因之一。
-
.btn-primary:extend(.btn)→ 仅合并.btn { color: blue; } -
.btn-primary:extend(.btn all)→ 同时合并.btn:hover { color: darkblue; }、.btn.is-loading::after { content: "..."; }等所有嵌套块 - 如果基类用了
&:focus { outline: 2px solid @focus-color; },不加all就完全不会继承
什么时候该换用 %占位符而不是 .class
当你只想复用样式逻辑,又不想让基类本身出现在最终 CSS 中,就该用 % 占位符。它和 :extend() 配合最紧密,且天然规避“目标未输出”问题。
立即学习“前端免费学习笔记(深入)”;
-
%reset { margin: 0; padding: 0; }→ 编译后不生成任何 CSS -
.list-item { &:extend(%reset); }→ 编译为.list-item { margin: 0; padding: 0; } - 多个地方调用
&:extend(%reset),最终只输出一行联合选择器:.list-item, .table-cell, .card-header { margin: 0; padding: 0; } -
%必须顶层声明,不能嵌套:.wrapper { %inner-reset { ... } }是非法语法
验证是否真正生效的唯一方式
别信编辑器高亮或 Less 报错提示,打开编译后的 CSS 文件,搜索逗号分隔的选择器组合——这是 :extend() 生效的铁证。
- 看到
.btn, .btn-primary, .btn-secondary { display: inline-flex; }→ 成功 - 看到
.btn { ... }和.btn-primary { ... }分开两段 → 失败 - 检查是否误启了
@import (reference)导致基类消失 - 确认构建命令是否带
--strict-math=on --js,否则某些计算式可能干扰解析
真正难的不是写对语法,而是判断哪些样式适合 :extend():它只吃语义稳定、无参数、不随断点变化的原子类。一旦你开始想传颜色、改圆角、适配暗色模式,就得切回 .mixin()——不是不能,而是设计意图错了。


















