混合(Mixins)
overview
混合是一种将一组属性从一个规则集包含(或混入)到另一个规则集的方法,能够混合类选择器和**id
选择器**。
假定有一个类选择器:
.bordered {
border-top: dotted 1px black;
border-bottom: solid 2px black;
}
如果希望它能在其他规则集下使用呢?可以直接调用:
#menu a {
color: #111;
.bordered();
}
.post a {
color: red;
.bordered();
}
这样.bordered
类选择器中包含的属性就同时出现在id
选择器#menu a
和类选择器.post a
中。
注意:mixin
调用中的圆括号是可选的,但将在未来的版本中被要求使用。
阻止输出
如果你想创建一个mixin
,但是你不希望这个mixin
出现在你的CSS
输出中,那就在mixin
定义后面加圆括号。
.my-mixin {
color: black;
}
.my-other-mixin() {
background: white;
}
.class {
.my-mixin();
.my-other-mixin();
}
//对应输出为
//没有输出.my-other-mixin选择器
.my-mixin {
color: black;
}
.class {
color: black;
background: white;
}
命名空间
给mixin
命名空间可以减少与其他库mixin
或用户mixin
的冲突,它也是一种组织mixin
组的方法。
#my-library {
.my-mixin() {
color: black;
}
}
// which can be used like this
.class {
#my-library.my-mixin();
}
以下三种写法等价,空格和>
是可选的:
#my-library > .my-mixin()
#my-library .my-mixin()
#my-library.my-mixin()
Guarded Namespaces
如果一个命名空间有一个Guard
,那么只有当Guard
条件返回true
时,才会使用它定义的mixins
。
#namespace when (@mode = huge) {
.mixin() { /* */ }
}
#namespace {
.mixin() when (@mode = huge) { /* */ }
}
!important
在mixin
调用后使用!important
关键字将它继承的所有属性标记为!important
:
.foo (@bg: #f5f5f5, @color: #900) {
background: @bg;
color: @color;
}
.unimportant {
.foo();
}
.important {
.foo() !important;
}
//编译为
.unimportant {
background: #f5f5f5;
color: #900;
}
.important {
background: #f5f5f5 !important;
color: #900 !important;
}
参数
接收参数
Mixins也可以接收参数,这些参数是混合时传递给选择器块的变量。
.border-radius(@radius) {
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
border-radius: @radius;
}
//传入参数值
#header {
.border-radius(4px);
}
.button {
.border-radius(6px);
}
接收参数时也可以有缺省值:
.border-radius(@radius: 5px) {
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
border-radius: @radius;
}
接收多个参数
参数可以用分号或逗号分隔,建议使用分号。符号逗号有双重含义:它既可以解释为mixin
参数分隔符,也可以解释为CSS
列表分隔符。如果编译器在mixin
调用或声明中至少看到一个分号,它就假定参数用分号分隔,并且所有的逗号都属于CSS
列表。
//两个参数,每个参数包含一个列表
.name(1, 2, 3; something, else)
//三个参数,每个包含一个数字
.name(1, 2, 3)
//一个参数,包含一个列表
.name(1, 2, 3;)
//默认值
.name(@param1: red, blue;)
@arguments
@arguments
在mixin
中有特殊的含义,它包含了当mixin
被调用时传递的所有参数。
.box-shadow(@x: 0; @y: 0; @blur: 1px; @color: #000) {
-webkit-box-shadow: @arguments;
-moz-box-shadow: @arguments;
box-shadow: @arguments;
}
.big-block {
.box-shadow(2px; 5px);
}
//编译成
.big-block {
-webkit-box-shadow: 2px 5px 1px #000;
-moz-box-shadow: 2px 5px 1px #000;
box-shadow: 2px 5px 1px #000;
}
参数拓展
你可以用…
让mixin参数数量可变:
.mixin(...) { // matches 0-N arguments
.mixin() { // matches exactly 0 arguments
.mixin(@a: 1) { // matches 0-1 arguments
.mixin(@a: 1; ...) { // matches 0-N arguments
.mixin(@a; ...) { // matches 1-N arguments
模式匹配
根据传递给mixin
的参数来更改它的行为:
.mixin(@s; @color) { ... }
.class {
.mixin(@switch; #888);
}
根据@switch
的值不同,.mixin
的行为不同:
//定义@switch值不同时的行为
.mixin(dark; @color) {
color: darken(@color, 10%);
}
.mixin(light; @color) {
color: lighten(@color, 10%);
}
.mixin(@_; @color) {
display: block;
}
//传入@switch的值
@switch: light;
//此时的.class
.class {
color: #a2a2a2;
display: block;
}
as Function
.average(@x, @y) {
@result: ((@x + @y) / 2);
}
div {
// call a mixin and look up its "@result" value
padding: .average(16px, 50px)[@result];
}
//编译
div {
padding: 33px;
}
递归
在Less
中,mixin
可以调用自己,用来创建各种迭代/循环结构。
.loop(@counter) when (@counter > 0) {
.loop((@counter - 1)); // next iteration
width: (10px * @counter); // code for each iteration
}
div {
.loop(5); // launch the loop
}
//编译
div {
width: 10px;
width: 20px;
width: 30px;
width: 40px;
width: 50px;
}
生成网格类:
.generate-columns(4);
.generate-columns(@n, @i: 1) when (@i =< @n) {
.column-@{i} {
width: (@i * 100% / @n);
}
.generate-columns(@n, (@i + 1));
}
//编译
.column-1 {
width: 25%;
}
.column-2 {
width: 50%;
}
.column-3 {
width: 75%;
}
.column-4 {
width: 100%;
}
Guard
Guard可以理解为条件操作符,类似于函数式编程。
比较符号
在Guard
中可用的比较操作符的完整列表是:>,>=,=,=<,<
。关键字true
是唯一的真值,使得这两个mixin
等价:
.truth(@a) when (@a) { ... }
.truth(@a) when (@a = true) { ... }
可以相互比较参数,或者比较非参数:
@media: mobile;
.mixin(@a) when (@media = mobile) { ... }
.mixin(@a) when (@media = desktop) { ... }
.max(@a; @b) when (@a > @b) { width: @a }
.max(@a; @b) when (@a < @b) { width: @b }
逻辑操作符
-
and
操作符(与).mixin(@a) when (isnumber(@a)) and (@a > 0) { ... }
-
,
操作符(或).mixin(@a) when (@a > 10), (@a < -10) { ... }
-
not
操作符(否定).mixin(@b) when not (@b > 0) { ... }
类型检查函数
可以使用is函数匹配值类型:
.mixin(@a; @b: 0) when (isnumber(@b)) { ... }
.mixin(@a; @b: black) when (iscolor(@b)) { ... }
常见基本类型检查函数:
iscolor
isnumber
isstring
iskeyword
isurl
检查是否为特定单位:
ispixel
ispercentage
isem
isunit