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;
}
分享笔记