@mixin и @include
Миксины позволяют определять стили, которые можно повторно использовать в вашем стиле. Они упрощают избегание использования несемантических классов, таких как .float-left, и позволяют распространять коллекции стилей в библиотеках.
Миксины определяются с помощью правила @mixin, которое записывается как @mixin <name> { ... } или @mixin name(<arguments...>) { ... }. Имя миксина может быть любым идентификатором Sass, который не начинается с --, и он может содержать любые утверждения, кроме утверждений верхнего уровня. Они могут быть использованы для инкапсуляции стилей, которые можно включить в одно правило стиля; они могут содержать собственные правила стилей, которые могут быть вложены в другие правила или включены на верхнем уровне таблицы стилей; или они могут просто служить для изменения переменных.
Миксины включаются в текущий контекст с помощью правила @include, которое записывается как @include <name> или @include <name>(<arguments...>), с указанием имени миксина.
@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;
}// 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-list и reset_list оба ссылаются на один и тот же миксин. Это остаток из очень ранних дней Sass, когда в именах идентификаторов разрешались только подчеркивания. После того, как Sass добавил поддержку дефисов для соответствия синтаксису CSS, оба были сделаны эквивалентными, чтобы упростить миграцию.
Аргументы
Миксины также могут принимать аргументы, что позволяет настраивать их поведение каждый раз, когда они вызываются. Аргументы указываются в правиле @mixin после имени миксина, как список имен переменных в скобках. Затем миксин должен быть включен с тем же количеством аргументов в виде выражений SassScript. Значения этих выражений доступны внутри тела миксина как соответствующие переменные.
@mixin rtl($property, $ltr-value, $rtl-value) {
#{$property}: $ltr-value;
[dir=rtl] & {
#{$property}: $rtl-value;
}
}
.sidebar {
@include rtl(float, left, right);
}// 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 миксинов, которые могут использоваться простыми или сложными способами.
@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);
}// 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, и они даже могут ссылаться на предыдущие аргументы!
Аргументы по имени
При включении миксина аргументы можно передавать по имени, а не по их положению в списке аргументов. Это особенно полезно для миксинов с несколькими необязательными аргументами или с логическими аргументами, значение которых не очевидно без имени. Аргументы по имени используют тот же синтаксис, что и объявления переменных и необязательные аргументы.
@mixin square($size, $radius: 0) {
width: $size;
height: $size;
@if $radius != 0 {
border-radius: $radius;
}
}
.avatar {
@include square(100px, $radius: 4px);
}// 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 заканчивается на ..., то все дополнительные аргументы этого миксина передаются этому аргументу как список. Этот аргумент известен как список аргументов.
@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");// 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() принимает список аргументов и возвращает любые дополнительные ключевые слова, переданные миксину, в виде отображения от имён аргументов (исключая $) до значений этих аргументов.
@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,
)// 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(), этот список аргументов не позволит дополнительных ключевых аргументов. Это помогает вызывающим сторонам вашего миксина убедиться, что они случайно не неправильно написали имена каких-либо аргументов.
Передача произвольных аргументов
Так же, как списки аргументов позволяют миксинам принимать произвольные позиционные или ключевые аргументы, тот же синтаксис можно использовать для передачи позиционных и ключевых аргументов миксину. Если вы передаёте список, за которым следует ... в качестве последнего аргумента включения, его элементы будут обрабатываться как дополнительные позиционные аргументы. Аналогично, карта, за которой следует ..., будет обрабатываться как дополнительные аргументы по имени. Вы даже можете передать оба сразу!
$form-selectors: "input.name", "input.address", "input.zip" !default; @include order(150px, $form-selectors...);
// SASS $form-selectors: "input.name", "input.address", "input.zip" !default @include order(150px, $form-selectors...)
💡 Интересный факт:
Поскольку список аргументов отслеживает как позиционные, так и ключевые аргументы, вы можете использовать его для передачи обоих сразу в другой миксин. Это очень упрощает определение псевдонима для миксина!
@mixin btn($args...) {
@warn "The btn() mixin is deprecated. Include button() instead.";
@include button($args...);
}// SASS @mixin btn($args...) @warn "The btn() mixin is deprecated. Include button() instead." @include button($args...)
Блоки контента
Помимо принятия аргументов, миксин может принимать весь блок стилей, известный как блок контента. Миксин может объявить, что он принимает блок контента, включив правило @content в своём теле. Блок контента передаётся в фигурных скобках, как любой другой блок в Sass, и он вставляется вместо правила @content.
@mixin hover {
&:not([disabled]):hover {
@content;
}
}
.button {
border: 1px solid black;
@include hover {
border-width: 2px;
}
}// 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. Если это так, блок контента будет включаться отдельно для каждого правила @content.
Блок контента является лексически связанным, что означает, что он может видеть только локальные переменные в области, где миксин включён. Он не может видеть переменные, определённые в миксине, в который он передаётся, даже если они определены до вызова блока контента.
Передача аргументов в блоки контента
- Dart Sass
- с 1.15.0
- LibSass
- ✗
- Ruby Sass
- ✗
Миксин может передавать аргументы в свой блок контента так же, как он бы передавал аргументы другому миксину, написав @content(<arguments...>). Пользователь, пишущий блок контента, может принимать аргументы, написав @include <name> using (<arguments...>). Список аргументов для блока контента работает точно так же, как список аргументов миксина, и аргументы, переданные ему @content, работают так же, как передача аргументов миксину.
Если миксин передаёт аргументы своему блоку контента, этот блок контента обязательно должен объявлять, что он принимает эти аргументы. Это означает, что лучше передавать аргументы только по позиции (а не по имени), а также что передача большего количества аргументов является изменением, вносящим несовместимость.
Если вы хотите быть гибкими в том, какую информацию передать в блок контента, рассмотрите возможность передачи ему карты, содержащей необходимую информацию!
@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;
}
}
}// 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 и @include. Миксины определяются с помощью символа =, а включаются с помощью +. Хотя этот синтаксис более краткий, его также сложнее понять с первого взгляда, и пользователям рекомендуется избегать его.
// 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;
}
© 2006–2025 the Sass team, and numerous contributors
Licensed under the MIT License.
https://sass-lang.com/documentation/at-rules/mixin