在 Sass 中使用 @include 与 @extend?

Posted

技术标签:

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

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

【问题讨论】:

include 没有给你扩展基类,它只是添加选项。只是建议你阅读sass-lang.com/docs/yardoc/…和sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#extend 另外,@CodeGroover,不是一个有用的评论,也许你误解了这个问题。阅读本文提供了更多有用的信息:gist.github.com/antsa/970172 只要你使用不带参数的 mixin,extend 会更有效率。 Courtesy Chris 【参考方案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 没有参数吗?我仍然没有看到优势或区别。 这里还有一些其他的怪癖...***.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 为例。希望这会有所帮助。

【讨论】:

以上是关于在 Sass 中使用 @include 与 @extend?的主要内容,如果未能解决你的问题,请参考以下文章

Sass @mixin 与 @include

node-sass 安装错误:找不到包“error-ex”

在带有 sass、css 和语义 ui 的 nextjs 中使用谷歌字体

Rails 上的 SASS 无效 CSS 错误

SASS混入

[Sass]混合宏