@extend 是编译时选择器合并机制,非样式继承;安全用法仅限语义一致、无参数、无嵌套的 %placeholder 原子复用,否则易致 css 膨胀、调试困难。

@extend 不是“让样式继承”,它是编译时选择器合并机制,用错反而会让 CSS 更大、更难调试。真正能减体积的用法只有一种:用 %placeholder 在语义一致、无参数、无嵌套的原子层做静态复用。
为什么直接 @extend .btn 很危险
它会把 .btn 规则里所有选择器(包括 .btn:hover、.btn.is-active)全拖进来,污染目标类的语义。更糟的是,如果 .btn 本身来自 .utility .btn 这种复合路径,@extend .btn 会生成 .card .utility .btn 这类冗余组合器。
- 编译后出现超长逗号分隔列表(如
.a, .b, .c, .d, .e {}),可能触发 IE 的 4095 字符限制 - 权重不会提升——你
@extend .btn-primary,但目标类仍是单类权重,压不住#header .btn - 若
.btn含&:hover或&::before,这些规则会被平铺展开,生成大量重复伪类选择器
必须用 %placeholder 而不是类名
%button-base 不会输出任何 CSS,只作为继承锚点;而 .button-base 一旦定义,就强制输出一条空规则,白白增加体积。
- 写
@extend %text-center安全;写@extend .text-center就可能把.text-center的整个规则链(含媒体查询、伪类)一并拉入 -
%占位符未被任何@extend调用时,编译后彻底消失,零体积 - 调试时可临时改名成
.debug-text-center查看效果,确认后再换回%
@extend 和 @mixin 到底怎么选
二者根本不是替代关系:@extend 合并选择器,@mixin 复制声明。选谁取决于你要复用的是“选择器归属”还是“样式逻辑”。
- 用
@extend %clearfix:多个不相关类(.list、.card、.modal)必须共用同一组clear: both声明,且不传参 - 用
@mixin responsive-text($size):需要根据$size计算font-size和line-height,或内联@media - 禁止在嵌套规则里写
.card { .title { @extend %heading; } }——这会导致 Sass 拼接出.card .title和%heading所有祖先路径,产出冗余选择器
跨文件 @extend 必须显式 @use
Dart Sass v7.0+ 默认禁用隐式跨文件 @extend。如果 %reset 定义在 _base.scss,你在 _card.scss 中想用,必须:
- 写
@use "base";,然后@extend base.%reset - 或写
@use "base" as *;,再直接@extend %reset - 不能靠
@import隐式加载,否则报错"%reset" is not a valid selector - 所有被
@extend的占位符,必须在继承语句之前定义(@use顺序很重要)
@extend 不会改变选择器权重,也不会让样式“动态继承”父级计算值——它只是编译时机械拼接选择器。只要涉及传参、媒体查询、伪类或嵌套上下文,@extend 就该立刻让位给 @mixin。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











