Sass @mixin 和 @include

Mixins 允许您定义可以在整个样式表中重复使用的样式。它们可以轻松避免使用非语义类(如 .float-left),并在库中分发样式集合。

Mixins 是使用 @mixin at-rule 定义的,它写@mixin { … } @mixin name() { … }。mixin 的名称可以是任何 Sass 标识符,并且可以包含除顶级语句以外的任何语句。它们可用于封装可拖放到单个样式规则中的样式;它们可以包含自己的样式规则,这些规则可以嵌套在其他规则中或包含在样式表的顶层;或者它们可以只用于修改变量。

Mixin 使用@include规则包含在当前上下文中,该规则@include@include() 编写,并包含 mixin 的名称。

SCSS

@mixin reset-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

@mixin horizontal-list {
  @include reset-list;

  li {
    display: inline-block;
    margin: {
      left: -2px;
      right: 2em;
    }
  }
}

nav ul {
  @include horizontal-list;
}

编译为 CSS 结果:

CSS

nav ul {
  margin: 0;
  padding: 0;
  list-style: none;
}
nav ul li {
  display: inline-block;
  margin-left: -2px;
  margin-right: 2em;
}

与所有 Sass 标识符一样,Mixin 名称将连字符和下划线视为相同。如reset-list 和reset_list 都引用相同的mixin。

参数

Mixins 还可以接受参数,必须以 SassScript 表达式的形式将 mixin 包含在相同数量的参数中。

SCSS

@mixin rtl($property, $ltr-value, $rtl-value) {
  #{$property}: $ltr-value;

  [dir=rtl] & {
    #{$property}: $rtl-value;
  }
}

.sidebar {
  @include rtl(float, left, right);
}

编译为 CSS 结果:

CSS

.sidebar {
  float: left;
}
[dir=rtl] .sidebar {
  float: right;
}

参数列表也可以有逗号结尾!这样可以在重构样式表时更轻松地避免语法错误。

可选参数

当包含mixin时,如果未传递该参数,则将使用该默认值。默认值使用与变量声明相同的语法:变量名称,后跟冒号和 SassScript 表达式。这使得定义可以简单或复杂方式使用的灵活混合 API 变得容易。

CSSS

@mixin replace-text($image, $x: 50%, $y: 50%) {
  text-indent: -99999em;
  overflow: hidden;
  text-align: left;

  background: {
    image: $image;
    repeat: no-repeat;
    position: $x $y;
  }
}

.mail-icon {
  @include replace-text(url("/images/mail.svg"), 0);
}

编译为 CSS 结果:

CSS

.mail-icon {
  text-indent: -99999em;
  overflow: hidden;
  text-align: left;
  background-image: url("/images/mail.svg");
  background-repeat: no-repeat;
  background-position: 0 50%;
}

默认值可以是任何 SassScript 表达式,甚至可以引用前面的参数!

关键字参数

当包含 mixin 时,除了按参数列表中的位置传递参数外,还可以按名称传递参数。这对于具有多个可选参数的maxin 参数特别有用,而对于布尔参数,如果没有名称,其含义并不明显。关键字参数使用与变量声明和可选参数相同的语法。

SCSS

@mixin square($size, $radius: 0) {
  width: $size;
  height: $size;

  @if $radius != 0 {
    border-radius: $radius;
  }
}

.avatar {
  @include square(100px, $radius: 4px);
}

编译为 CSS 结果:

CSS

.avatar {
  width: 100px;
  height: 100px;
  border-radius: 4px;
}

任意参数

有时,对于 mixin 来说,能够接受任意数量的参数是很有用的。如果 @mixin 声明中的最后一个参数以 …“ 结尾,则该 mixin 的所有额外参数都将作为列表(List)传递给该参数。此参数称为参数列表。

SCSS

@mixin order($height, $selectors...) {
  @for $i from 0 to length($selectors) {
    #{nth($selectors, $i + 1)} {
      position: absolute;
      height: $height;
      margin-top: $i * $height;
    }
  }
}

@include order(150px, "input.name", "input.address", "input.zip");

编译为 CSS 结果:

CSS

input.name {
  position: absolute;
  height: 150px;
  margin-top: 0px;
}

input.address {
  position: absolute;
  height: 150px;
  margin-top: 150px;
}

input.zip {
  position: absolute;
  height: 150px;
  margin-top: 300px;
}

任意关键字参数

参数列表也可用于获取任意关键字参数。meta.keywords() 函数接受一个参数列表,并返回传递给 mixin 的参数映射(Map)。

SCSS

@use "sass:meta";

@mixin syntax-colors($args...) {
  @debug meta.keywords($args);
  // (string: #080, comment: #800, variable: $60b)

  @each $name, $color in meta.keywords($args) {
    pre span.stx-#{$name} {
      color: $color;
    }
  }
}

@include syntax-colors(
  $string: #080,
  $comment: #800,
  $variable: #60b,
)

编译为 CSS 结果:

CSS

pre span.stx-string {
  color: #080;
}

pre span.stx-comment {
  color: #800;
}

pre span.stx-variable {
  color: #60b;
}

传递任意参数

就像参数列表允许 mixins 采用任意位置或关键字参数一样,相同的语法可用于将位置和关键字参数传递给 mixin。如果您传递一个列表(List),最后跟…,其元素将被视为附加位置参数。同样,映射(Map)后跟…将被视为附加关键字参数。两者可以同时使用!

实例

$form-selectors: "input.name", "input.address", "input.zip" !default;

@include order(150px, $form-selectors...);

内容块

除了获取参数之外,mixin 还可以采用整个样式块,称为内容块。mixin 可以通过在其正文中包含规则@content来声明它接受内容块。内容块使用大括号传入,就像 Sass 中的任何其他块一样,并且注入它来代替@content规则。

SCSS

@mixin hover {
  &:not([disabled]):hover {
    @content;
  }
}

.button {
  border: 1px solid black;
  @include hover {
    border-width: 2px;
  }
}

编译为 CSS 结果:

CSS

.button {
  border: 1px solid black;
}
.button:not([disabled]):hover {
  border-width: 2px;
}

一个混合可以包含多个规则@content。如果是这样,则每个@content将单独包含内容块。

参数传递给内容块

mixin 可以将参数传递给其内容块,就像通过编写 @content() 将参数传递给另一个 mixin 一样。编写内容块的用户可以通过使用 () 编写@include 来接受参数。内容块的参数列表的工作方式就像 mixin 的参数列表一样,@content 传递给它的参数就像将参数传递给 mixin 一样。

如果 mixin 将参数传递给其内容块,则该内容块必须声明它接受这些参数。最好只按位置(而不是按名称)传递参数,如果您想灵活地将哪些信息传递给内容块,可以用Map。

SCSS

@mixin media($types...) {
  @each $type in $types {
    @media #{$type} {
      @content($type);
    }
  }
}

@include media(screen, print) using ($type) {
  h1 {
    font-size: 40px;
    @if $type == print {
      font-family: Calluna;
    }
  }
}

编译为 CSS 结果:

CSS

@media screen {
  h1 {
    font-size: 40px;
  }
}
@media print {
  h1 {
    font-size: 40px;
    font-family: Calluna;
  }
}

缩进的Mixin语法

该缩进语法对定义和使用的混maxin,除了标准的特殊语法@mixin@include。Mixins是使用字符定义的=,而使用则包含在内+。尽管此语法比较简单,但一眼就很难理解,建议用户避免使用它。

Sass

=reset-list
  margin: 0
  padding: 0
  list-style: none

=horizontal-list
  +reset-list

  li
    display: inline-block
    margin:
      left: -2px
      right: 2em

nav ul
  +horizontal-list

编译为 CSS 结果:

CSS

nav ul {
  margin: 0;
  padding: 0;
  list-style: none;
}
nav ul li {
  display: inline-block;
  margin-left: -2px;
  margin-right: 2em;
}

Captcha Code

0 笔记

分享笔记

Inline Feedbacks
View all notes