Less 的基本使用入门
给 CSS 加点料 ~
LESS(Leaner Style Sheets 的缩写) 为 CSS 赋予了动态语言的特性,如变量,继承,运算,函数等,它是一门向后兼容的 CSS 扩展语言。
当前最新版本:Less 3.0
官方文档:http://lesscss.org
快速入门:http://www.bootcss.com/p/lesscss
源码地址:https://github.com/less/less.js
1. 浏览器使用
1.1. 编译成 *.css 👍
node.js
1
2➜ npm install -g less
➜ lessc styles.less styles.csskoala
这是一个简单易用的 GUI 工具,可以对 less 进行实时编译、压缩等,详见:http://koala-app.com/index-zh.html
更多工具,请访问官网:http://lesscss.org/tools/#guis-for-less
webapck(后续待补充…)
1.2. 借助 less.js
1 | <!-- 首先引入 less 文件,注意这里的 rel 类型 --> |
注意:
- *.less 文件一定要在引入 less.js 之前引入。
- 请在 web 服务环境下使用,直接双击打开可能报错。
2. 语法规则
2.1. 变量(Variables)
1 | // 定义变量 |
还支持这样:
1 | @size: 14px; |
2.2. 混合(Mixins)
我们可以预先定义一个通用的属性集(mixin,如下面的 .bordered),然后在另一个需要用到的属性集(如下面的 #menu)里面去调用(或称作引入、合并),这种方式叫混合。
基本使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21.bordered { // 如果不想这个 mixin 被编译输出,可以写成 .bordered() { ... }
border-top: dotted 1px black;
border-bottom: solid 2px black;
}
#link {
display: inline-block;
.bordered; // .bordered(); 完成同样的功能,括号不是必须的。
}
输出:
.bordered {
border-top: dotted 1px black;
border-bottom: solid 2px black;
}
#link {
display: inline-block;
border-top: dotted 1px black;
border-bottom: solid 2px black;
}带参数的混合
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30.border-radius (@radius) { // 不设置参数默认值,调用时必须传参,否则编译报错
border-radius: @radius;
-moz-border-radius: @radius;
-webkit-border-radius: @radius;
}
.border-radius2 (@radius: 5px) { // 设置参数默认值
border-radius: @radius;
-moz-border-radius: @radius;
-webkit-border-radius: @radius;
}
#header {
.border-radius(4px); // 传参 4px
//.border-radius; // 编译报错
}
#footer {
.border-radius2; // 编译正常,不传参时,可以省略 ()
}
输出:
#header {
border-radius: 4px;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
}
#footer {
border-radius: 5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
}@arguments 变量
@arguments 包含了所有传递进来的参数,如下示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17.box-shadow (@x: 0, @y: 0, @blur: 1px, @color: #000) {
box-shadow: @arguments;
-moz-box-shadow: @arguments;
-webkit-box-shadow: @arguments;
}
.div1 {
.box-shadow(2px, 5px);
}
输出:
.div1 {
box-shadow: 2px 5px 1px #000000;
-moz-box-shadow: 2px 5px 1px #000000;
-webkit-box-shadow: 2px 5px 1px #000000;
}匹配模式
只有被匹配的混合才会被使用。
变量可以匹配任意的传入值,而变量以外的固定值就仅仅匹配与其相等的传入值。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21.mixin (dark, @color) { // 调用时,第一个参数必须传 dark 才会匹配
color: darken(@color, 10%);
}
.mixin (light, @color) { // 调用时,第一个参数必须传 light 才会匹配
color: lighten(@color, 10%);
}
.mixin (@_, @color) { // 不管第一个参数传什么,都会匹配
display: block;
}
@switch: light;
.class {
.mixin(@switch, #888);
}
输出:
.class {
color: #a2a2a2;
display: block;
}也可以匹配多个参数,即根据调用时传参的多少,匹配对应的混合规则(如下)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15.mixin2 (@a) { // 调用时传1个参数
color: @a;
}
.mixin2 (@a, @b) { // 调用时传2个参数
color: @b;
}
.class2 {
.mixin2(#888, #eee);
}
输出:
.class2 {
color: #eeeeee;
}导引(Guards )
使用关键字 when 根据表达式进行匹配混合(mixin)。
为了尽可能地保留 CSS 的可声明性,Less 通过导引(Guards )而非 if/else 语句来实现条件判断,因为前者已在 @media query 特性中被定义。
如下示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24// when 关键字用以定义一个导引(Guards)序列(此例只有一个导引)
.mixin (@a) when (lightness(@a) >= 50%) { // 颜色的亮度大于等于 50% 时匹配
background-color: black;
}
.mixin (@a) when (lightness(@a) < 50%) { // 颜色的亮度小于 50% 时匹配
background-color: white;
}
.mixin (@a) { // 不管传什么,始终匹配
color: @a;
}
.class3 { .mixin(#ddd) }
.class4 { .mixin(#555) }
输出:
.class3 {
background-color: black;
color: #dddddd;
}
.class4 {
background-color: white;
color: #555555;
}导引中可用的比较运算符 **>、>=、=、=<、<**。
1
2
3
4
5
6
7
8
9// 关键字 true 只表示布尔真
// 下面两种方式是等价的
.truth (@a) when (@a) { ... }
.truth (@a) when (@a = true) { ... }
// 除关键字 true 以外的其它值都被视作布尔假
.class {
.truth(40); // 这里的传参 40 被视作布尔假,不会匹配上面定义的混合(mixin)
}导引序列可以使用基于 CSS media queries 的逻辑操作符
1
2
3
4
5
6
7
8// 用关键字 and 合并导引序列,表示条件的并且关系
.mixin (@a) when (isnumber(@a)) and (@a > 0) { ... }
// 用逗号 , 合并导引序列,表示条件的或者(or)关系
.mixin (@a) when (@a > 10), (@a < -10) { ... }
// 用关键字 not 取反
.mixin (@b) when not (@b > 0) { ... }最后,如果想基于值的类型进行匹配,我们就可以使用 is* 函式
1
2.mixin (@a, @b: 0) when (isnumber(@b)) { ... }
.mixin (@a, @b: black) when (iscolor(@b)) { ... }可用的 is* 函数
- iscolor
- isnumber
- isstring
- iskeyword
- isurl
- ispixel 判断一个值的单位是否是 px
- ispercentage 判断一个值的单位是否是 百分比
- isem 判断一个值的单位是否是 em
- isunit(value, unit) 判断一个值是否是指定的单位类型
- isruleset
2.3. 嵌套(Nesting)
LESS 可以让我们以嵌套的方式编写层叠样式
1 | #header { |
@规则(At-rules)例如 @media 或 @supports,同样是可以被嵌套的,编译后,@规则被放在顶级,同一个规则集下的其它元素相对顺序保持不变,如下示例:
1 | .component { |
2.4. 运算(Operations)
任何数字、颜色或者变量都可以采用运算符 加( + )、减( - )、乘( * )、 除( / ) 进行运算。
在加、减或比较数字之前,如果数字包含单位,则先转换成相同的单位(比如 10mm 转成 1cm),并且以最左侧的单位为基准。如果单位是不可转换的(比如 px → cm)或转换是没有意义的,则会被忽略。
1 | @conversion-1: 5cm + 10mm; // 结果:6cm(10mm 先转成 1cm 然后再计算) |
乘法 和 除法 运算不会转换数字,因为在大多数情况下,这是没有意义的:长度乘以长度会产生一个区域,而css不支持指定区域。所以,LESS 将会对数字进行原样操作(忽略单位),并将最左侧指定的单位带到结果里。
1 | @base: 2cm * 3mm; // 结果:6cm |
2.5. 函数(Functions)
LESS 提供了一系列针对颜色、字符串和数学运算的函数,详见官方文档。
下面是一些示例:
1 | hue(@color); // 获取颜色的色调 |
2.6. 命名空间
有时候,为了更好组织 CSS 或者单纯是为了更好的封装,将一些变量或者混合(mixins)模块打包起来, 你可以像下面这样在 #bundle 中定义一些属性集:
1 | #bundle { |
使用 > 引用某属性集下面的规则:
1 | #header a { |
2.7. 作用域(Scope)
LESS 中的作用域跟其他编程语言非常类似,首先会从本地查找变量或者混合(mixins)模块,如果没找到的话会去父级作用域中查找,直到找到为止。
1 | @var: red; |
2.8. 注释(Comments)
1 | // 这种是 less 加入的注释,不会被编译 |
2.9. 引入(Importing) *.less 文件
1 | @import "library"; // library.less 后缀名可带可不带 |
2.10. 变量嵌入字符串
变量可以用类似 ruby 和 php 的方式嵌入到字符串中,结构:@{name}
1 | @base-url: "http://assets.fnord.com"; |
2.11. 使用 ~ 禁止编译
有时候我们需要输出一些不正确的 CSS 语法或者使用一些 LESS 不认识的专有语法,这时可以使用符合 **~**,如下:
1 | .class { |
2.12. 使用 JavaScript 表达式
通过反引号的方式可以再 LESS 中使用 JavaScript 表达式。
1 | @var: `"hello".toUpperCase() + '!'`; // 结果:HELLO! |