@extend 和 mixin 的最大区别在于 css 的编译方式。它在简单的示例中看起来并不多,但差异和含义是显着的,如果不小心使用,可能会在野外真正令人头疼。 @extend有点像傻瓜金,乍一看还不错,但是……
我们来看一个简单的例子:
@extend
.row {
width: 50px;
}
.new-row {
@extend .row;
}
.another-row {
@extend .row;
}
编译成:
.row,
.new-row,
.another-row {
width: 50px;
}
混合
@mixin row() {
width: 50px;
}
.new-row {
@include row();
}
.another-row {
@include row();
}
编译成:
.new-row {
width: 50px;
}
.another-row {
width: 50px;
}
一个 mixin 包括它所命中的任何地方的属性 - 每次都复制它们 - 而 @extend 将选择器分组并定义一次属性。这不是很明显,因为不同之处在于编译后的 css,但它有一些重要的含义:
加载顺序
使用@extend,选择器将在sass 中遇到它们的第一个点进行分组,这可能会导致一些奇怪的覆盖。如果您定义了一个选择器并使用@extend 来引入一个属性并尝试覆盖之前在您的sass 中定义的属性,但是在扩展属性在css 中分组之后,覆盖将不起作用。这可能非常令人困惑。
考虑一下这组逻辑有序的 css 定义和可能的 HTML:<div class='row highlight-row'></div>:
.red-text {
color: red;
}
.row {
color: green;
}
.highlight-row {
@extend .red-text;
}
编译成:
.red-text,
.highlight-row {
color: red;
}
.row {
color: green;
}
因此,即使 sass 排序使它看起来像行颜色是红色的,编译后的 css 也会使它变成绿色
分组不佳
@extend 可能导致生成的 CSS 中的选择器分组不佳。例如,您最终可能会得到三十或四十个不相关的事物,它们都共享相同的属性。将@extend 用于字体就是一个很好的例子。
嵌套
如果您使用深度嵌套的 sass(这不好,顺便说一句)并且您使用 @extend,您将为您使用的每个 @extend 复制完全嵌套的选择器,从而导致 css 臃肿。我见过很多:
.selector-1 .selector-2 .selector-3 .selector-4,
.selector-1 .selector-2 .selector-3 .selector-4 a,
.selector-1 .selector-2 .selector-3 .selector-4 li,
.selector-1 .selector-2 .selector-3 .selector-4 td {
font-family: arial;
}
如果您是 SASS 新手,查看编译后的 css 是值得的。
媒体查询
@extend 在媒体查询中不起作用,因为媒体查询不是选择器。
结论
我的经验法则是如果你没有参数并且如果你可以合理地定义@extend并在附近存在的几个紧密相关的选择器之间共享它,则在mixin上使用@extend例如,在 sass 中,在定义 sass 模块的同一文件中。按钮是很好用的@extend 的一个很好的例子:
%button {
padding: 10px;
}
.call-to-action {
@extend %button;
background-color: $green;
}
.submit {
@extend %button;
background-color: $grey;
}
帮助做出选择的最佳文章是here
PS,% 符号是 placeholder extends 的使用