less必知必会(1)

less-essential less 必知必会

第一节主要说 comment/variable/mixin

comment

less 支持 3 种注释形式

  1. single line comment // commented by magicdawn
  2. block comment /* commented by magicdawn */
  3. special comment /*! Copyright 2015 Magicdawn !*/

这三种对应着不同的 min 级别

  • lessc a.less a.css 会移除 // 开头的 single line comment
  • lessc -x 表示压缩,已经 deprecated,提示用 less-plugin-clean-css 插件 , 会移除 blockcomment,speial comment 也就是这个用途,可以保存一些 copyright license 信息.

variable

即变量. syntax : @variable-name: value;
e.g

1
@color: red;

变量名

变量名可以用连字符(hyphen),即 - 连接,像@variable-name,而 camelCase 形式,貌似没有哪种语言不支持吧.

变量冲突

即变量在相同的作用域冲突,规则是 :

最后定义的获胜
The last declaration wins

e.g

1
2
3
4
5
@color: red;
body {
background-color: @color;
}
@color: yellow;

得到结果是

1
2
3
body {
background-color: yellow;
}

@color 重复定义,后面的 yellow 取胜,致使 body 的 background-color 为 yellow

  1. 也就是说 less 中的变量其实更像是其他编程语言中的 const*,在整个 less 编译期间,一个变量只有一个值,而且是最后定义的值.

  2. 根据第一条结论,lazyLoad 不就有了么

    1
    2
    3
    4
    body {
    background-color: @color;
    }
    @color: red;

    这个@color 后写也没有关系.

  3. 使用 variable 初始化 另一个 variable

    1
    2
    3
    @var2 : 1;
    @var1 : @var2;
    @var2 : 3;

    result : @var1: 3

  4. escape value , syntax ~"xxx @{interpolation}"
    例如

    1
    2
    @w: 20px;
    width: calc(100% - @w);

    想输出 width: calc(100% - 20px); 是不可行的.

    这里的 calc,不应该被 less 当作 function or mixin. 所以可以使用 引号引起来,加上~,再展开.

    使用

    1
    2
    @w: 20px;
    width: ~"calc(100% - @{ w }";

    => 即可得到期望值 width: calc(100% - 20px)

mixin

mixin E 文意思为: 混合

在 js 中常见的,mixin function 实现的是 lodash.extend , 即把一个 obj 上的 prop copy 给另一个 obj.
在 less 中,可以吧 mixin 理解为 一个 function 之类的

1
2
3
body {
.some-mixin();
}

调用这个 some-mixin,就会把这个 mixin 里的 css 规则添加到 body 里.

语法

1
2
3
.some-mixin() {
...;
}

在 less 中,.some-class 也可以作为 mixin,不带参数的.some-mixin() 可以省略括号,即 .some-mixin;

so:

  • 当你见着一个 .abcd-efg(); , 它是一个 mixin
  • 当你见着一个 .abcd-efg; , 可能是一个 类选择器 or 可以省略参数的 mixin;

参数

1
2
3
.some-mixin(@para: 10px,@para2: 20px) {
...;
}

@para1,@para2 定义参数, 后面也可以接上默认值.

  • 参数之间以 , or ; 分隔, less 更 prefer ; 分隔,因为某些 css 属性是用,分隔的,因此会有歧义.

    1
    2
    3
    4
    5
    6
    7
    8
    @some-mixin (@para1,@para2) {
    prop1: @para1;
    prop2: @para2;
    }

    body {
    .some-mixin(1, 2, 3;4);
    }

    =>

    1
    2
    3
    4
    body {
    prop1: 1, 2, 3;
    prop2: 4;
    }

    当 less 在参数列表中发现一个;时,就以;为分隔符,因此 @(1,2,3,4;) 匹配一个参数.

特殊参数

@arguments

好理解,就是 js 里面一个 function 传进来的 arguments

@rest

1
2
3
4
5
6
7
.vendor(@prop,@values...) {
@{prop}: @values;
-webkit-@{prop}: @values;
-ms-@{prop}: @values;
-moz-@{prop}: @values;
-o-@{prop}: @values;
}

这个 .vendor mixin 里面的 @values 参数就是 rest 参数,代表传进来的参数 slice 掉已经定义的.

返回值

mixin 是没有返回值的.但是 可以有下面的效果.我赶脚比较 weird,就不多说了.

1
2
3
4
5
6
7
8
9
10
11
12
13
.returnmixin() {
@par1: 5;
@par2: 10;
}
.mixin() {
@par2: 5; // protected for overwriting
property1: @par1; // copied from returnmixin's scope
property2: @par2;
.returnmixin();
}
element {
.mixin();
}

=>

1
2
3
4
element {
property1: 5;
property2: 5;
}

这么玩,出错了怎么找??????

参数匹配

1
2
3
4
5
6
7
8
9
10
11
12
.mixin() {
color: white;
}
.mixin(@para1) {
color: red;
}
.mixin(@para1,@para2) {
color: green;
}
.mixin(@para1,@para2,@para3) {
color: blue;
}

可以根据参数的不同选择实现,类似于 函数重载.

  1. 当两个 mixin 都符合时,这两个 mixin 都会应用.
  2. 当找不到匹配时,报错.

有一种叫 argument switch

1
2
3
4
5
6
.color(light) {
color: white;
}
.color(dark) {
color: black;
}

可以看到,light 和 dark 都是没有@符号的,他们不是变量,相当于加了个 switch case

1
2
3
4
5
6
7
8
switch(xxx){
case light:
xxxx;
case dark:
xxxx;
default;
break;
}

于是 这个 mixin 传值只能传 .color(light) or .color(dark)

条件判断

1
2
3
4
5
6
7
8
9
10
11
12
mixin(@a) when (@<1){
color: white;
}
mixin(@a) when (@>=1){
color: black;
}
.class {
mixin(0);
}
.class2 {
mixin(1);
}

As you see.

于是就有了 利用 when+递归 做的 loop

1
2
3
4
5
6
7
8
.gen-class(@i) when (@i > 0) {
.class-@{i} {
color: red;
}
.gen-class(@i - 1);
}

.gen-class(10);

=>

1
2
3
4
5
6
7
8
9
10
.class-10 {
color: red;
}
.class-9 {
color: red;
}

... .class-1 {
color: red;
}