less语言特性(二) —— 混合

在 LESS 中我们可以定义一些通用的属性集为一个 class,然后在另一个 class 中去调用这些属性,下面有这样一个 class:

1

2

3

4

.bordered {

    border-top: dotted 1px black;

    border-bottom: solid 2px black;

}

那如果我们现在需要在其他 class 中引入那些通用的属性集,那么我们只需要在任何 class 中像下面这样调用就可以了:

1

2

3

4

5

6

7

8

9

.border_radius {

    border-radius: 10px;

    -moz-border-radius: 10px;

    -webkit-border-radius: 10px;

}

#progress{

    display: block;

    .border_radius

}

任何 CSS class, id 属性集都可以以同样的方式引入。

注意:变量也会被混合,也就是说变量会被带到当前的作用域。这个特性还有争议,也许在未来会有变化。

对于常常操纵css3的我们,真事我们的救星,我们知道,如果一个网站中全部的圆角都用css3实现,那么用这种混合的方式真事帮我们省了不少事儿,可是灵活性上似乎差了点,例如圆角的尺寸等。别急,less还提供了其他的方法解决了这个问题。

~带参数混合

在 LESS 中,你还可以像函数一样定义一个带参数的属性集合:

1

2

3

4

5

.border_radius (@radius) {

    border-radius: @radius;

    -moz-border-radius: @radius;

    -webkit-border-radius: @radius;

}

然后在其他 class 中像这样调用它:

1

2

3

4

5

6

#header {

    .border_radius(4px);

}

.button {

    .border_radius(6px);

}

这种方式是否解决了上边的那个问题;但是问题又出来了,这样的话我每回调用的时候都要写上参数,在圆角大部分都相同的情况下,调用时我都要写上同样的参数,似乎可以再简洁一点,而less的处理方式似乎也提供了这种方式,让我们更灵活的操纵代码,看如下代码:

我们还可以像这样给参数设置默认值:

1

2

3

4

5

.border_radius (@radius: 5px) {

    border-radius: @radius;

    -moz-border-radius: @radius;

    -webkit-border-radius: @radius;

}

所以现在如果我们像这样调用它的话:

1

2

3

#header {

    .border_radius;

}

radius 的值就会是 5px。

LESS混合方式也提供一种可以定义不带参数属性集合,如果你想隐藏这个属性集合,不让它暴露到 CSS 中去,但是你还想在其他的属性集合中引用,你会发现这个方法非常的好用:

1

2

3

4

5

6

7

8

9

.wrap(){

    text-wrap: wrap;

    white-space: pre-wrap;

    white-space: -moz-pre-wrap;

    word-wrap: break-word;

}

.pre {

    .wrap;

}

编译过的CSS:

1

2

3

4

5

6

.pre {

    text-wrap: wrap;

    white-space: pre-wrap;

    white-space: -moz-pre-wrap;

    word-wrap: break-word;

}

以上为混合模式传一个参数,及不定义参数的详解,混合模式还提供了多参数混合模式,是我们操纵css的时候能灵活。

~多参数混合

多个参数可以使用分号或者逗号分隔,推荐使用分号分隔,因为逗号有两重含义:它既可以表示混合的参数,也可以表示一个参数中一组值的分隔符。

使用分号作为参数分隔符意味着可以将逗号分隔的一组值作为一个变量处理。换句话说,如果编译器在混合的定义或者是调用中找到至少一个分号,就会假设参数是使用分号分隔的,所有的逗号都属于参数中的一组值的分隔符。

2个参数,每个参数都含有通过逗号分隔的一组值的情况:.name(1, 2, 3; something, else)。

3个参数,每个参数只含一个数字的情况:.name(1, 2, 3)。

使用一个象征性的分号可以创建一个只含一个参数,但参数包含一组值的混合:.name(1, 2, 3;)。

逗号分隔的一组值参数的默认值:.name(@param1: red, blue;)。

使用同样的名字和同样数量的参数定义多个混合是合法的。在被调用时,LESS会应用到所有可以应用的混合上。比如你调用混合时只传了一个参数.mixin(green),那么所有只强制要求一个参数的混合都会被调用:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

.mixin(@color) {

    color: @color;

}

.mixin(@color; @padding:2) {

    color: @color;

    padding: @padding;

}

.mixin(@color; @padding;30px; @margin: 2px) {

    color: @color;

    padding: @padding;

    margin: @margin @margin @margin @margin;

}

.header-nav li a{

    .mixin(#008000);

}

编译成的css:

1

2

3

4

.header-nav li a{

    color: #008000;

    padding: 2;

}

首先,看上个片段的代码你会发现,为什么第三个.mixin的margin没有解析出来?

其次padding为什么失效?

先说第一个问题,显然,在调用第三个.mixin方法的时候padding没有值,也没有传值,没传值的结果字面上显示的是此处第三个方法不被调用。

第二个问题,因为padding的值没有单位,所以被浏览器解析出来但是失效 。

针对第一个问题我们稍作修改验证一下,如果第一种真的是因为我说的那个缘故,那么我们给他穿个参数看能否被调用:

1

2

3

.header-nav li a{

    .mixin(#008000;20p);

}

浏览器中被编译的css结果:

1

2

3

color: #008000;

padding: 20px;

margin: 2px 2px 2px 2px;

显然当第二位有参数的时候,第三个.mixin方法被调用了。

那如果第二个参数不传单位,看会被编译成什么结果:

1

2

3

.header-nav li a{

    .mixin(#008000;20;);

}

被编译的css结果

1

2

3

color: #008000;

padding: 20;

margin: 2px 2px 2px 2px;

显然,以上的说法成立。

 ~@arguments 变量

@arguments在Mixins中是一个很特别的参数,当Mixins引用这个参数时,他将表示所有的变量,当你不想处理个别的参数时,这个将很有用,我们来看一个阴影的实例:

1

2

3

4

5

6

.box_shadow (@x: 0, @y: 0, @blur: 1px, @color: #000) {

    box-shadow: @arguments;

    -moz-box-shadow: @arguments;

    -webkit-box-shadow: @arguments;

}

.box_shadow(2px, 5px);

编译的css结果:

1

2

3

box-shadow: 2px 5px 1px #000;

-moz-box-shadow: 2px 5px 1px #000;

-webkit-box-shadow: 2px 5px 1px #000;

 ~高级参数用法与 @rest 变量

很多时候,我们的参数并不固定,尤其在css3的开发中这种问题尤为明显;混合模式中也为我们提供了在 mixin 中不限制参数的数量的方式,可以在变量名后添加 ...,表示这里可以使用 N 个参数。

1

2

3

4

5

.mixin (...) {        // 接受 0-N 个参数

.mixin () {           // 不接受任何参数

.mixin (@a: 1) {      // 接受 0-1 个参数

.mixin (@a: 1, ...) { // 接受 0-N 个参数

.mixin (@a, ...) {    // 接受 1-N 个参数

此外:

1

2

3

4

.mixin (@a, @rest...) {

    // @rest 表示 @a 之后的参数

    // @arguments 表示所有参数

}

怎么样。不错吧,这样开发起来是不是灵活性更高了呢!

开发时需注意的一点,有时候我们可能会使用hack !Important,调用时在混合后面加上!important关键字表示将混合带来的所有属性标记为!Important;

如:

1

2

3

4

5

6

7

8

9

10

.mixin (@a: 0) {

    border: @a;

    boxer: @a;

}

.unimportant {

    .mixin(1);

}

.important {

    .mixin(2) !important;

}

编译后:

1

2

3

4

5

6

7

8

.unimportant {

    border: 1;

    boxer: 1;

}

.important {

    border: 2 !important;

    boxer: 2 !important;

}

~混合模式还有两块内容,模式匹配与Guard表达式这里先暂不作介绍了。

下期为大家介绍LESS另一个特性,嵌套规则。

posted @ 2014-01-09 20:20  汪强胜  Views(478)  Comments(0Edit  收藏  举报