混入
约 1410 字大约 5 分钟
2025-04-17
混入(Mixins)是 Stylus 中非常强大的功能,它允许你定义可重用的样式块,并在需要的地方引入这些样式。混入类似于函数,可以接受参数,使得样式代码更加灵活和可维护。
Mixin
和函数都以相同的方式定义,但它们的应用方式不同。
一、简介
1、基本定义和使用
// 定义混入
basic-mixin() // 注意这里的括号不能省略
color red
font-size 14px
// 使用混入
.button
basic-mixin()
编译为:
.button {
color: #f00;
font-size: 14px;
}
2、传递参数
Mixin 支持传递参数,允许我们根据需要自定义样式。我们可以传递一个参数,也可以传递多个参数。
shadow(x, y, blur, color)
box-shadow x y blur color
.card
shadow(2px, 2px, 10px, rgba(0,0,0,.3))
编译为:
.card {
box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.3);
}
3、参数默认值
我们还可以为参数设置默认值,这样在不传递参数的情况下,会使用默认值。
// 带默认参数的混入
border-radius(radius = 5px)
-webkit-border-radius radius
border-radius radius
// 使用
.box
border-radius() // 使用默认值5px
.circle
border-radius(50%) // 覆盖默认值
编译为:
.box {
-webkit-border-radius: 5px;
border-radius: 5px;
}
.circle {
-webkit-border-radius: 50%;
border-radius: 50%;
}
二、特性介绍
1、参数列表 arguments
我们可以利用arguments
,他包含传递的表达式,允许传递多个值:
border-radius()
-webkit-border-radius arguments
-moz-border-radius arguments
border-radius arguments
form input[type=button]
border-radius 5px
编译为:
form input[type="button"] {
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
}
请注意,我们 Mixin 中的 border-radius
被视为属性,而不是递归函数调用。
2、剩余参数 ...
同时,我们可以使用 ...
可以接收任意数量的参数:
box-shadow(args...)
-webkit-box-shadow args
-moz-box-shadow args
box-shadow args
.card
box-shadow 1px 1px 5px #333, inset 0 0 3px #666
编译为:
.card {
-webkit-box-shadow: 1px 1px 5px #333, inset 0 0 3px #666;
-moz-box-shadow: 1px 1px 5px #333, inset 0 0 3px #666;
box-shadow: 1px 1px 5px #333, inset 0 0 3px #666;
}
3、插值语法
我们还可以利用 插值语法 {param}
:
border(side, args...)
if side
border-{side} args
else
border args
.border-thick
border('left' , 10px, 'darkred')
.border
border('' , 1px, 'darkred')
编译后:
.border-thick {
border-left: 10px "darkred";
}
.border {
border: 1px "darkred";
}
4、省略括号
Stylus 允许省略括号,这使得调用 Mixin 变得更加简洁和直观。
省略括号有个前提条件:需要给 Mixin 传递参数。
mixin-1() // 不涉及参数
border-radius 10px
mixin-2(n) // 包含参数
border-radius n
mixin-3() // arguments
border-radius arguments
mixin-4() // arguments
margin arguments
.class-0
mixin-1 // 此处将不会被编译
.class-1
mixin-1()
.class-2
mixin-1 10px // 不使用括号,就传个无用参数
.class-3
mixin-2(20px)
.class-4
mixin-2 20px
.class-5
mixin-3(30px)
.class-6
mixin-3 30px
.class-7
mixin-4(30px, 20px)
.class-8
mixin-4 30px 20px
编译后,我们发现.class-0
并没有被编译,因为它不符合可以省略括号的条件:
.class-1 {
border-radius: 10px;
}
.class-2 {
border-radius: 10px;
}
.class-3 {
border-radius: 20px;
}
.class-4 {
border-radius: 20px;
}
.class-5 {
border-radius: 30px;
}
.class-6 {
border-radius: 30px;
}
.class-7 {
margin: 30px 20px;
}
.class-8 {
margin: 30px 20px;
}
或者,我们假设有以下代码:
mixin-code()
backaround-color red
div
mixincode
span
color blue
你期望它会被编译成:
div {
background-color: red;
}
div span {
color: blue;
}
但是,实际上,它会被编译成:
div mixin-code,
div span {
color: #00f;
}
5、块级作用域
Mixin 内部的变量和函数定义在函数外部是不可见的。
mixin()
$x = 10px
color: red
div
mixin()
margin $x
编译后:
div {
color: #f00;
margin: $x;
}
三、高级用法
1、块混入
块引用相当于 vue 中的插槽(v-solt
)。你可以在调用 Mixin 的时候通过使用 +
前缀标记 Mixin,将块传递给 Mixin :
传递的块将在 Mixin 中作为 block
变量提供,然后可以与插值一起使用:
foo()
.bar
{block}
+foo()
width: 10px
编译为:
.bar {
width: 10px;
}
此功能在 ATM 上处于 早期开发状态(rough
状态),但将来会得到增强。
2、混入嵌套混入
Mixin 可以利用其他 Mixin
例如,下面我们在 comma-list()
中引用 inline-list
来创建内联 inline
的无序列表<li>
,并在末尾添加逗号分隔。
inline-list()
li
display inline
comma-list()
inline-list()
li
&:after
content ', '
&:last-child:after
content ''
ul
comma-list()
编译为:
ul li:after {
content: ", ";
}
ul li:last-child:after {
content: "";
}
ul li {
display: inline;
}
3、父引用
Mixin 可以利用父引用字符 &
,作用于父引用而不是进一步嵌套。
例如,假设我们要创建一个 stripe(even, odd)
Mixin 用于给表格添加斑马纹。我们为 even
和 odd
提供默认颜色值,并在该行上分配 background-color
属性。嵌套在 tr
中,我们使用 &
来引用 tr
,提供 even
颜色。
stripe(even = #fff, odd = #eee)
tr
background-color odd
&.even // 注意这里为class="even" 的 tr
&:nth-child(even)
background-color even
然后我们可以使用 Mixin :
table
stripe()
td
padding 4px 10px
table#users
stripe(#303030, #494848)
td
color white
或者,可以在没有父引用的情况下定义 stripe()
:
stripe(even = #fff, odd = #eee)
tr
background-color odd
tr.even
tr:nth-child(even)
background-color even
如果我们愿意,我们可以像调用属性一样调用 stripe()
:
stripe #fff #000
最终编译为:
table tr {
background-color: #eee;
}
table tr.even {
background-color: #fff;
}
table tr:nth-child(even) {
background-color: #fff;
}
table td {
padding: 4px 10px;
}
/* ----- */
table#users tr {
background-color: #494848;
}
table#users tr.even {
background-color: #303030;
}
table#users tr:nth-child(even) {
background-color: #303030;
}
table#users td {
color: #fff;
}
更新日志
e7112
-1于