@mixinと@include

ミックスインを使用すると、スタイルシート全体で再利用できるスタイルを定義できます。これにより、.float-leftなどの意味のないクラスの使用を避け、スタイルのコレクションをライブラリに分散することが容易になります。

ミックスインは@mixin Atルールを使用して定義されます。これは@mixin <name> { ... }または@mixin name(<arguments...>) { ... }と書かれます。ミックスインの名前は、--で始まらない任意のSass識別子にすることができ、トップレベルステートメント以外の任意のステートメントを含めることができます。これらは、単一のスタイルルールにドロップできるスタイルをカプセル化するために使用できます。独自のスタイルルールを含み、他のルールにネストしたり、スタイルシートのトップレベルに含めることができます。または、単に変数を変更するためだけのものでも構いません。

ミックスインは、@include Atルールを使用して現在のコンテキストに含めます。これは@include <name>または@include <name>(<arguments...>)と書かれ、ミックスインの名前が含まれています。

Playground

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;
}
Playground

Sass構文

@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出力

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











💡豆知識

ミックスインの名前は、他のすべてのSass識別子と同様に、ハイフンとアンダースコアを同じものとして扱います。つまり、reset-listreset_listはどちらも同じミックスインを参照します。これは、Sassの初期の頃、識別子名にアンダースコアしか許可されていなかった名残です。SassがCSSの構文に合わせるためにハイフンのサポートを追加すると、移行を容易にするために両方が同等になりました。

引数引数パーマリンク

ミックスインは引数も受け取ることができます。これにより、呼び出されるたびに動作をカスタマイズできます。引数は、ミックスインの名前の後に@mixinルールで、かっこで囲まれた変数名のリストとして指定されます。次に、ミックスインは、SassScript式の形式で同じ数の引数で含める必要があります。これらの式の値は、対応する変数としてミックスインの本体で使用できます。

Playground

SCSS構文

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

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

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

Sass構文

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

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



.sidebar
  @include rtl(float, left, right)

CSS出力

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





💡豆知識

引数リストには、末尾のカンマも付けることができます!これにより、スタイルシートのリファクタリング時の構文エラーを回避しやすくなります。

オプションの引数オプションの引数パーマリンク

通常、ミックスインが宣言するすべての引数は、そのミックスインが含まれているときに渡す必要があります。ただし、その引数が渡されなかった場合に使用される_デフォルト値_を定義することにより、引数をオプションにすることができます。デフォルト値は変数の宣言と同じ構文を使用します。変数名、コロン、SassScript式です。これにより、シンプルまたは複雑な方法で使用できる柔軟なミックスインAPIを簡単に定義できます。

Playground

SCSS構文

@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);
}
Playground

Sass構文

@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出力

.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式にすることができ、以前の引数を参照することもできます!

キーワード引数キーワード引数パーマリンク

ミックスインが含まれている場合、引数は、引数リストの位置で渡すことに加えて、名前で渡すことができます。これは、複数のオプションの引数を持つミックスイン、または名前がないと意味が不明なブール値引数を持つミックスインに特に役立ちます。キーワード引数は、変数の宣言およびオプションの引数と同じ構文を使用します。

Playground

SCSS構文

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

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

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

Sass構文

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

  @if $radius != 0
    border-radius: $radius



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

CSS出力

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







⚠️ご注意ください!

任意の引数を名前で渡すことができるため、ミックスインの引数を名前変更する際は注意してください…ユーザーの動作が中断される可能性があります!しばらくの間、古い名前をオプションの引数として残しておき、誰かが渡した場合に警告を出力すると、新しい引数に移行する必要があることがわかります。

任意の引数の取得任意の引数の取得パーマリンク

場合によっては、ミックスインが任意の数の引数を受け取れるようにすることが役立ちます。@mixin宣言の最後の引数が...で終わる場合、そのミックスインへの追加の引数はすべて、リストとしてその引数に渡されます。この引数は、引数リストとして知られています。

Playground

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");






Playground

Sass構文

@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出力

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()関数は引数リストを受け取り、ミックスインに渡された追加のキーワードを、引数名($を含まない)からその引数の値へのマップとして返します。

Playground

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,
)
Playground

Sass構文

@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出力

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

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

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







💡豆知識

meta.keywords()関数に引数リストを渡さない場合、その引数リストは追加のキーワード引数を許可しません。これにより、ミックスインの呼び出し元は、引数名を誤ってスペルミスしていないことを確認できます。

任意の引数の渡し任意の引数の渡しパーマリンク

引数リストにより、ミックスインは任意の位置引数またはキーワード引数を受け取れるようにしますが、同じ構文を使用して、位置引数とキーワード引数をミックスインに渡すことができます。リストに続けて...を引数の最後に渡すと、その要素は追加の位置引数として扱われます。同様に、マップに続けて...を渡すと、追加のキーワード引数として扱われます。両方同時に渡すこともできます!

Playground

SCSS構文

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

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

Sass構文

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

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

💡豆知識

引数リストは位置引数とキーワード引数の両方を追跡するため、これを使用して両方同時に別のミックスインに渡します。これにより、ミックスインのエイリアスを非常に簡単に定義できます!

Playground

SCSS構文

@mixin btn($args...) {
  @warn "The btn() mixin is deprecated. Include button() instead.";
  @include button($args...);
}
Playground

Sass構文

@mixin btn($args...)
  @warn "The btn() mixin is deprecated. Include button() instead."
  @include button($args...)

コンテンツブロックコンテンツブロックパーマリンク

引数を受け取ることに加えて、ミックスインは_コンテンツブロック_として知られるスタイル全体のブロックを受け取ることができます。ミックスインは、本体に@content Atルールを含めることで、コンテンツブロックを受け取ると宣言できます。コンテンツブロックは、Sassの他のブロックと同じように中括弧を使用して渡され、@contentルールの代わりに挿入されます。

Playground

SCSS構文

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

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

Sass構文

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



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


CSS出力

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






💡豆知識

ミックスインは複数の@content Atルールを含めることができます。その場合、コンテンツブロックは各@contentに対して個別に含まれます。

⚠️ご注意ください!

コンテンツブロックは_字句的にスコープされます_。つまり、ミックスインが含まれているスコープにあるローカル変数のみを参照できます。コンテンツブロックが呼び出される前であっても、渡されたミックスインで定義されている変数を参照することはできません。

コンテンツブロックへの引数の渡しコンテンツブロックへの引数の渡しパーマリンク

互換性
Dart Sass
1.15.0以降
LibSass
Ruby Sass

mixinは、`@content(<引数...>)`と記述することで、他のmixinに引数を渡すのと同様に、そのコンテンツブロックに引数を渡すことができます。コンテンツブロックを作成するユーザーは、`@include <名前> using (<引数...>)`と記述することで、引数を受け取ることができます。コンテンツブロックの引数リストはmixinの引数リストと全く同じように機能し、`@content`によって渡される引数は、mixinに引数を渡すのと全く同じように機能します。

⚠️ご注意ください!

mixinがコンテンツブロックに引数を渡す場合、そのコンテンツブロックはそれらの引数を受け入れることを必ず宣言する必要があります。これは、名前ではなく位置によってのみ引数を渡すのが良いアイデアであり、より多くの引数を渡すことは破壊的な変更になることを意味します。

コンテンツブロックに渡す情報を柔軟に変更したい場合は、必要な情報を含むマップを渡すことを検討してください!

Playground

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;
    }
  }
}
Playground

Sass構文

@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出力

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





インデントされたmixin構文インデントされたmixin構文 パーマリンク

インデント構文には、標準的な`@mixin`と`@include`に加えて、mixinの定義と使用のための特別な構文があります。mixinは`=`文字を使用して定義され、`+`を使用してインクルードされます。この構文は簡潔ですが、一見して理解するのが難しい場合もあるため、使用を避けることをお勧めします。

Playground

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出力

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