中文
混合(Mixins)
混入和函数定义方法一致,但是应用却大相径庭。
例如,下面有定义的border-radius(n)
方法,其却作为一个 mixin(如,作为状态调用,而非表达式)调用。
当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
Block mixins
You can pass blocks to mixins by calling mixin with +
prefix:
+foo()
width: 10px
+foo()
width: 10px
The passed block would be available inside the mixin as block
variable, that then could be used with interpolation:
foo()
.bar
{block}
+foo()
width: 10px
=> .bar {
width: 10px;
}
foo()
.bar
{block}
+foo()
width: 10px
=> .bar {
width: 10px;
}
This feature is in its rough state ATM, but would be enhanced in the future.
混合中的混合
自然,混合可以利用其它混合,建立在它们自己的属性和选择器上。
例如,下面我们创建内联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;
}