@extend让CSS变大是因为它机械拼接选择器而非复用声明,导致相同样式被重复输出、组合爆炸、gzip和cssnano无法合并、PurgeCSS失效;嵌套调用、伪类/媒体查询继承、跨文件隐式引用及使用真实类名均会加剧膨胀。

@extend 不是复用样式,而是合并选择器 —— 编译时机械拼接所有调用点,导致重复声明、组合爆炸、压缩失效。
为什么 @extend 会让 CSS 文件变大
它不共享声明块,只把选择器列表“塞进”同一规则里。比如 .btn、.link、.tag 都 @extend %text-truncate,最终 CSS 就是:.btn, .link, .tag { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }。看上去省了三行,但每条声明都复制了一遍;更糟的是,如果其中某个类在嵌套中调用(如 .card__title {@extend %text-truncate;}),Sass 还会额外生成 .card .card__title 这类冗余组合。
- gzip 压缩不了分散在不同选择器里的相同声明,因为它们属于不同规则块
- cssnano 无法合并
.btn { margin: 0.5rem; }和.link { margin: 0.5rem; }—— 它们不是同一规则 - 构建后搜索
margin: 0.5rem,结果远多于你写的类数?基本就是@extend泛滥了
哪些 @extend 写法必然膨胀体积
以下模式几乎一定让输出失控:
- 在嵌套结构里用:
.card { .title { @extend %heading; } }→ 可能产出.card .title, .alert .title, .card .card .title - 继承目标含伪类或媒体查询:
%btn-hover { &:hover { color: blue; } }→ 所有调用者都强制获得 hover 样式 - 跨文件隐式引用:
Dart Sass v7.0+默认禁用未@use的占位符,找不到定义时可能静默失败或拼错路径,开发者误加更多@extend补救 - 用真实类名代替占位符:
@extend .clearfix→ 不仅输出无用的.clearfix,还把所有继承者卷入同一规则块
如何验证 @extend 是否已失控
别看 SCSS 源码是否“简洁”,重点检查编译后的 CSS 输出:
立即学习“前端免费学习笔记(深入)”;
- 打开
main.css,搜索一个基础声明如display: flex,如果出现次数远超组件数量,说明被多次展开 - 查是否有超长逗号分隔列表(如
.a, .b, .c, .d, .e, .f, .g {}),甚至触发 IE 的 4095 字符限制 - 在 DevTools 的 Styles 面板里,看某个元素匹配到的选择器是否带一堆无关前缀(如
.layout .card .header)
真正难察觉的是:@extend 让 PurgeCSS 失效——工具无法识别两个不同选择器背后是同一份逻辑,也就不敢删未用类。体积问题从构建阶段,一路拖到线上。


















