@extend Wrapper 又名 Mixtend

Avatar of Kitty Giraudel
Kitty Giraudel

使用 @extend 指令扩展选择器时,Sass 不会从被扩展的选择器中获取 CSS 内容并将其放入扩展选择器中。它的工作方式正好相反。它获取扩展选择器并将其附加到被扩展的选择器中。

由于它的工作方式,它使得从不同的范围使用它变得不可能。例如,你不能扩展在 @media 块中声明的占位符,也不能从根目录扩展占位符,如果你在 @media 指令中。

当然我们可以找到一种在可能的情况下使用 @extend 的方法,否则使用 mixin。实际上,这是可以做到的,但这有点棘手,我称之为 mixtend 技巧。在你的项目中无处不在实施之前,你可能需要三思而后行。也许只使用 mixin 会更容易。我会让你自己判断。

包裹 @extend

这个想法实际上很容易理解。首先我们定义 mixin。唯一的参数是 $extend,它定义了 mixin 是否应该尝试扩展而不是包含。显然,它是一个布尔值(默认值为 true)。

如果 $extendtrue,我们会扩展一个以 mixin 命名的占位符(不幸的是,这不会自动计算)。如果它为 false,我们会将 CSS 代码作为常规 mixin 所做的那样转储。

在 mixin 之外,我们定义了前面提到的占位符。为了避免在占位符中重复 CSS 代码,我们只需要通过将 $extend 设置为 false 来包含 mixin,这样它就会将 CSS 代码转储到占位符的核心。

/// *Mixtend* hack
/// @author Kitty Giraudel
@mixin mixtend-boilerplate($extend: true) {
  @if $extend {
    @extend %mixtend-boilerplate-placeholder;
  } @else {
    // Mixtend content
  }
}

%mixtend-boilerplate-placeholder {
  @include mixtend-boilerplate($extend: false);
}

示例

作为一个简单的例子,我们将使用来自 Nicolas Gallagher 的 微型清除浮动技巧

@mixin clearfix($extend: true) {
  @if $extend {
    @extend %clearfix;
  } @else {
    &:after {
      content: '';
      display: table;
      clear: both;
    }
  }
}

%clearfix {
  @include clearfix($extend: false);
}

使用它非常简单

.a { @include clearfix; }
.b { @include clearfix; }

@media (min-width: 48em) {
  .c {
    @include clearfix(false);
  }
}

生成的 CSS

.a:after, .b:after {
  content: '';
  display: table;
  clear: both;
}

@media (min-width: 48em) {
  .c:after {
    content: '';
    display: table;
    clear: both;
  }
}

Sublime Text 代码片段

如果你想保存代码模板以便使其高度可重用,你会很高兴地知道为它创建一个 Sublime Text 代码片段非常容易。在 Sublime 中,转到 工具 > 新代码片段... 并粘贴下面的内容。

随意更改 键以输入任何你喜欢的东西;它是在你按下 tab 键扩展代码片段之前要输入的单词。我使用的是 mixtend

<snippet>
    <content><![CDATA[
@mixin ${1:mixtend}(\$extend: true) {
  @if $extend {
    @extend %${1:mixtend};
  } @else {
    ${2}
  }
}

%${1:mixtend} {
  @include ${1:mixtend}(\$extend: false);
}
]]></content>
    <tabTrigger>mixtend</tabTrigger>
    <scope>source.scss</scope>
</snippet>