在Sass中使用@include vs @extend吗?


92

在Sass中,我无法完全分辨使用@includemixin和使用@extend占位符类之间的区别。他们不是同一件事吗?


2
include不会给您扩展基类,而只是添加选项。只要建议您阅读sass-lang.com/docs/yardoc/…sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#extend
CodeGroover 2013年

1
另外,@ CodeGroover并不是一个有用的注释,也许您误解了这个问题。阅读此内容会提供更多有用的信息:gist.github.com/antsa/970172
临时用户名

4
每当您使用不带参数的mixin时,扩展将更加有效。 克里斯
阿比耶特(Abhijeet)供图,2016年

Answers:


86

扩展不允许自定义,但是它们会产生非常有效的CSS。

%button
  background-color: lightgrey
  &:hover, &:active
    background-color: white

a
  @extend %button

button
  @extend %button

结果:

a, button {
  background-color: lightgrey;
}
a:hover, button:hover, a:active, button:active {
  background-color: white;
}

使用mixins,您将获得重复的CSS,但是可以使用参数来修改每种用法的结果。

=button($main-color: lightgrey, $active-color: white)
  background-color: $main-color
  border: 1px solid black
  border-radius: 0.2em

  &:hover, &:active
    background-color: $active-color

a
  +button

button
  +button(pink, red)

结果是:

a {
  background-color: lightgrey;
  border: 1px solid black;
  border-radius: 0.2em;
}
a:hover, a:active {
  background-color: white;
}

button {
  background-color: pink;
  border: 1px solid black;
  border-radius: 0.2em;
}
button:hover, button:active {
  background-color: red;
}

请遵循以下连续的代码示例集,以了解如何通过有效地使用扩展和混合来使代码更清洁,更可维护:http : //thecodingdesigner.com/posts/balancing

请注意,不幸的是,SASS不允许在媒体查询内部使用扩展(并且上述链接中的相应示例是错误的)。在需要基于媒体查询进行扩展的情况下,请使用mixin:

=active
  display: block
  background-color: pink

%active
  +active

#main-menu
  @extend %active // Active by default

#secondary-menu
  @media (min-width: 20em)
    +active // Active only on wide screens

结果:

#main-menu {
  display: block;
  background-color: pink;
}

@media (min-width: 20em) {
  #secondary-menu {
    display: block;
    background-color: pink;
  }
}

在这种情况下,复制是不可避免的,但是您不必太在意它,因为Web服务器的gzip压缩会处理它。

PS注意,您可以在媒体查询中声明占位符类。

2014年12月28日更新扩展生成的混合 CSS比混合生成的CSS更紧凑,但是压缩CSS时,这种好处会减弱。如果您的服务器提供压缩的CSS(确实如此!),那么扩展几乎没有任何好处。因此,您始终可以使用mixins!此处的更多信息:http : //www.sitepoint.com/sass-extend-nobody-told-you/


2
我认为这并不完全正确...您可以@extends通过覆盖扩展父项进行自定义。当然您不能传递参数,但这是唯一的区别吗?在这种情况下,是@extend@mixin不带参数?我仍然看不到优势或差异。
临时用户名

2
这里有一些其他怪癖...... stackoverflow.com/questions/30744625/...
托尼利

我会仔细解释最后一段的“给您几乎没有好处”方面。Gzip压缩是基于字典的霍夫曼编码器,因此,如果重复发生的间隔足够远,则文本将不会出现在字典中,压缩率将受到影响。我仍然总是希望@extend尽可能地使用它,因为这产生更紧凑的CSS,但仍然可以很好地压缩(毕竟是ASCII文本)。
amcgregor

@amcgregor,差异可忽略不计。
安德烈·米哈伊洛夫

@ AndreyMikhaylov-lolmaus我同意!我希望这种差异在本质上是无法测量的,无论选择使用兆字节左右的生成CSS,还是使用,最终结果在内存中的压缩都会更紧凑@extend。这似乎是基于直觉和直觉的微观优化,而不是基于对压缩方案实际工作方式的理解。(此外:它忽略了按需gzip传输编码的大量开销;压缩不是免费的!;)
amcgregor

18

一个好的方法是同时使用这两种方法-创建一个mixin,它将允许您进行大量自定义,然后扩展该mixin的常见配置。例如(SCSS语法):

@mixin my-button($size: 15, $color: red) {
  @include inline-block;
  @include border-radius(5px);
  font-size: $size + px;
  background-color: $color;
}
%button {
  @include my-button;
}
%alt-button {
  @include my-button(15, green);
}
%big-button {
  @include my-button(25);
}

这样可以避免您一次又一次调用“我的按钮” mixin。这也意味着您不必记住通用按钮的设置,但是您仍然可以选择一个超级独特的一次性按钮。

我以不久前写的博客文章为例。希望这可以帮助。


12

在我看来,扩展是纯粹的邪恶,应该避免。原因如下:

鉴于scss:

%mystyle {color: blue;}
.mystyle-class {@extend %mystyle}
//basically anything not understood by target browser (such as :last-child in IE8):
::-webkit-input-placeholder {@extend %mystyle}

将生成以下CSS:

.mystyle-class, ::-webkit-input-placeholder { //invalid in non-webkit browsers
  color: blue;
}

当浏览器不了解选择器时,它将使选择器的整行无效。这意味着您宝贵的mystyle类不再是蓝色的(对于许多浏览器而言)。这到底是什么意思?如果您在任何时候使用扩展程序而浏览器可能无法理解选择器,则该扩展程序的其他所有使用都会失效。此行为还允许进行邪恶嵌套:

%mystyle {color: blue;}
@mixin mystyle-mixin {@extend %mystyle; height: 0;}
::-webkit-input-placeholder {@include mystyle-mixin} 
//you thought nesting in a mixin would make it safe?
.mystyle-class {@extend %mystyle;}

结果:

::-webkit-input-placeholder, .mystyle-class { //invalid in non-webkit browsers
  color: blue;
}

::-webkit-input-placeholder {
  height: 0;
}

Tl; dr:@extend完全可以,只要您从未将其与任何浏览器特殊选择器一起使用即可。如果这样做,无论您在哪里使用它,它都会突然破坏样式。尝试依靠mixin代替!


4
有趣的笔记
simhumileco '04

4

如果mixins接受参数,请使用mixins,其中编译输出将根据传递给它的内容而改变。

@include opacity(0.1);

对任何静态的可重复样式块使用扩展(带有占位符)。

color: blue;
font-weight: bold;
font-size: 2em;

0

我完全同意d4nyll的先前回答。有一篇关于扩展选项的文章,当我研究这个主题时,我发现了很多关于扩展的抱怨,所以请记住,如果有可能使用mixin代替扩展,就跳过扩展。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.