:extend能减小css体积因其不复制样式而只合并选择器,如5个按钮类继承同一基类时仅输出一行联合规则;但需满足目标真实输出、选择器精确匹配及路径一致三个前提,且加all才继承伪类等嵌套规则。

为什么:extend能减小CSS体积——它不复制,只合并
因为 :extend() 的本质是让编译器把多个选择器“塞进同一组声明块”,而不是为每个类都生成一套完整样式。比如 5 个按钮类都写 .btn-primary:extend(.btn all),最终 CSS 里只有一行:.btn, .btn-primary, .btn-secondary, .btn-danger { display: inline-flex; padding: 8px 16px; }。而用 .btn() mixin 的话,这 4 行声明会原样复制 5 遍。
:extend() 生效的三个硬性前提
写了 :extend() 不等于生效,必须同时满足:
-
.target必须真实输出到最终 CSS 中——不能只靠@import (reference)引入;否则编译器找不到目标,退化为复制整块规则 - 被继承的选择器必须完整匹配,比如
.nav-item:hover不能被.mobile-nav:extend(.nav-item)匹配,得写成.mobile-nav:extend(.nav-item:hover all) - 路径和导入方式必须一致:多个文件都
@import "base.less",但一个用./base、一个用../shared/base,Less 就当它们是两个文件,:extend()各自找各自的目标,结果生成两套重复规则
为什么加了 all 才真正省体积
不加 all 时,:extend(.btn) 只继承 .btn 直接定义的样式;加了 all 才会把 .btn:hover、.btn.is-active 这些嵌套规则也一并合并进来。常见错误是写成 .btn-primary:extend(.btn),结果鼠标悬停样式没继承,最后还得单独补一遍,反而更乱。
验证是否生效,唯一可靠方式是打开编译后的 CSS 文件,搜索类似 .btn, .btn-primary, .btn-secondary { 这样的逗号分隔选择器——有,说明成功;只有孤立的 .btn-primary {,说明链路断了。
容易被忽略的副作用:选择器权重与覆盖难度
:extend() 是编译期合并,不是运行时注入。一旦 .title:extend(%truncate) 和 .subtitle:extend(%truncate) 同时存在,它们就“焊死”在同一组声明里:.title, .subtitle { overflow: hidden; }。这时候你想单独给 .title 加 text-overflow: clip,就得写更高权重的选择器(比如 .title.title-modified),否则会被合并后的规则覆盖。
这不是 bug,而是机制本身带来的约束:省体积的同时,牺牲了局部覆盖的灵活性。需要动态微调的地方,老老实实用 mixin 更稳妥。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











