【问题标题】:Using @include vs @extend in Sass?在 Sass 中使用 @include 与 @extend?
【发布时间】:2013-08-03 05:46:18
【问题描述】:

在 Sass 中,我无法完全区分使用带有 mixin 的 @include 和使用带有占位符类的 @extend 之间的区别。它们不等于同一件事吗?

【问题讨论】:

标签: sass


【解决方案1】:

扩展不允许自定义,但它们产生非常高效的 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 日更新Extends 生成的 CSS 比 mixins 更紧凑,但是当 CSS 被 gzip 压缩时,这种优势会减弱。如果您的服务器提供 gzip 压缩的 CSS(它确实应该!),那么 extends 几乎不会给您带来任何好处。所以你总是可以使用mixins!更多信息在这里:http://www.sitepoint.com/sass-extend-nobody-told-you/

【讨论】:

  • 我认为这并不完全准确...您可以通过覆盖扩展父级来自定义@extends。当然你不能传递参数,但那是唯一的区别吗?在那种情况下,@extend 只是 @mixin 没有参数吗?我仍然没有看到优势或区别。
  • 这里还有一些其他的怪癖...stackoverflow.com/questions/30744625/…
  • 我会小心解释最后一段的“给你几乎没有任何好处”方面,那里。 Gzip 压缩是一种基于字典的 Huffman 编码器,因此如果重复发生的距离足够远,文本将不会出现在字典中,压缩率也会受到影响。在可能的情况下,我仍然总是更喜欢@extend,因为这生成更紧凑的 CSS,它仍然可以很好地压缩(毕竟它是 ASCII 文本)。
  • @amcgregor,差别可以忽略不计。
  • @AndreyMikhaylov-lolmaus 我同意!我希望这种差异基本上无法通过网络测量,无论选择任何高达 1 兆字节左右的生成 CSS,除了使用@extend 时内存中未压缩的最终结果将更加紧凑这一事实。这是一种看似基于直觉和直觉的微优化,而不是对所涉及的压缩方案如何实际工作的理解。 (另外:它忽略了按需 gzip 传输编码的可观开销;压缩不是免费的!;)
【解决方案2】:

我完全同意 d4nyll 之前的回答。有 a text 关于扩展选项,当我研究这个主题时,我发现了很多关于扩展的抱怨,所以请记住,如果有可能使用 mixin 而不是扩展,请跳过扩展。

【讨论】:

    【解决方案3】:

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

    鉴于 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-class 不再是蓝色的(对于许多浏览器)。 这到底是什么意思?如果您在任何时候使用了浏览器可能无法理解选择器的扩展,那么对扩展的所有其他使用都将失效。 这种行为也允许恶意嵌套:

    %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 是完全可以的,只要你从不将它与任何浏览器特定的选择器一起使用。如果你这样做了,它会突然破坏你使用过的样式。尝试使用 mixins!

    【讨论】:

    • 有趣的笔记
    【解决方案4】:

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

    @include opacity(0.1);
    

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

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

    【讨论】:

      【解决方案5】:

      一个好的方法是同时使用这两种方法 - 创建一个允许您进行大量自定义的 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);
      }
      

      这使您不必一遍又一遍地调用 my-button mixin。这也意味着您不必记住常用按钮的设置,但您仍然可以制作一个超级独特的一次性按钮。

      我以不久前的a blog post I wrote 为例。希望这会有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-08-25
        • 1970-01-01
        • 2023-04-03
        • 2014-07-03
        • 2023-03-06
        • 2021-11-27
        • 2018-01-30
        相关资源
        最近更新 更多