混合
混合和函数以相同的方式定义,但它们以不同的方式应用。
例如,我们定义了下面一个 border-radius(n)
函数,它作为一个混合被调用(即,作为一个语句被调用,而不是作为表达式的一部分)。
当 border-radius()
在选择器内被调用时,这些属性将被展开并复制到选择器中。
border-radius(n)
-webkit-border-radius n
-moz-border-radius n
border-radius n
form input[type=button]
border-radius(5px)
border-radius(n)
-webkit-border-radius n
-moz-border-radius n
border-radius n
form input[type=button]
border-radius(5px)
编译为
form input[type=button] {
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
}
form input[type=button] {
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
}
当使用混合时,你可以完全省略括号,提供奇妙的透明供应商属性支持!
border-radius(n)
-webkit-border-radius n
-moz-border-radius n
border-radius n
form input[type=button]
border-radius 5px
border-radius(n)
-webkit-border-radius n
-moz-border-radius n
border-radius n
form input[type=button]
border-radius 5px
请注意,混合中的 border-radius
被视为一个属性,而不是一个递归函数调用。
为了进一步了解这一点,我们可以利用自动 arguments
局部变量,它包含传递的表达式,允许传递多个值
border-radius()
-webkit-border-radius arguments
-moz-border-radius arguments
border-radius arguments
border-radius()
-webkit-border-radius arguments
-moz-border-radius arguments
border-radius arguments
现在我们可以传递像 border-radius 1px 2px / 3px 4px
这样的值!
我们还可以使用 插值 {param}
border(side, args...)
if side
border-{side} args
else
border args
.border-thick
border('left' , 10px, 'darkred')
.border
border('' , 1px, 'darkred')
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';
}
.border-thick {
border-left: 10px 'darkred';
}
.border {
border: 1px 'darkred';
}
此功能的另一个妙用是添加对供应商特定功能的透明支持——例如 IE 的 opacity
支持
support-for-ie ?= true
opacity(n)
opacity n
if support-for-ie
filter unquote('progid:DXImageTransform.Microsoft.Alpha(Opacity=' + round(n * 100) + ')')
#logo
&:hover
opacity 0.5
support-for-ie ?= true
opacity(n)
opacity n
if support-for-ie
filter unquote('progid:DXImageTransform.Microsoft.Alpha(Opacity=' + round(n * 100) + ')')
#logo
&:hover
opacity 0.5
渲染
#logo:hover {
opacity: 0.5;
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=50);
}
#logo:hover {
opacity: 0.5;
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=50);
}
父引用
混合可以利用父引用字符 &
,对父级操作,而不是进一步嵌套。
例如,假设我们想为条纹表格行创建一个 stripe(even, odd)
混合。我们为 even
和 odd
提供默认颜色值,并在行上分配 background-color
属性。在 tr
中嵌套,我们使用 &
引用 tr
,提供 even
颜色。
stripe(even = #fff, odd = #eee)
tr
background-color odd
&.even
&:nth-child(even)
background-color even
stripe(even = #fff, odd = #eee)
tr
background-color odd
&.even
&:nth-child(even)
background-color even
然后,我们可以按如下所示使用混合
table
stripe()
td
padding 4px 10px
table#users
stripe(#303030, #494848)
td
color white
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(even = #fff, odd = #eee)
tr
background-color odd
tr.even
tr:nth-child(even)
background-color even
如果需要,我们可以像调用属性一样调用 stripe()
stripe #fff #000
stripe #fff #000
块混合
你可以通过使用 +
前缀调用混合来将块传递给混合
+foo()
width: 10px
+foo()
width: 10px
传递的块在混合中可用作 block
变量,然后可以使用插值。
foo()
.bar
{block}
+foo()
width: 10px
=> .bar {
width: 10px;
}
foo()
.bar
{block}
+foo()
width: 10px
=> .bar {
width: 10px;
}
此功能目前处于粗略状态,但将在未来得到增强。
在混合中混合混合
混合当然可以利用其他混合,构建自己的选择器和属性。
例如,下面我们创建 comma-list()
以内联(通过 inline-list()
)和逗号分隔无序列表。
inline-list()
li
display inline
comma-list()
inline-list()
li
&:after
content ', '
&:last-child:after
content ''
ul
comma-list()
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;
}
ul li:after {
content: ", ";
}
ul li:last-child:after {
content: "";
}
ul li {
display: inline;
}