我个人对CSS预处理器比较偏爱Stylus和Sass,但公司项目现在上Less,所以抽空整理了Less的相关知识汇总到本篇。
- 安装与执行
- 变量
- Mixin
- 匹配模式
- 嵌套规则
- 注释
- Import
安装与执行
个人比较偏好node环境,安装非常简单:
npm install less –global
安装后本地随便新建一个sample.less文件,执行:
lessc sample.less > sample.css
就能将其翻译成标准的sample.css源文件了。执行时可以带上参数,通过lessc -h
查看支持的命令参数。参数还真不少,例如-x
可以编译出压缩过的css文件。如果希望获得更好的压缩效果,还可以通过--clean-css
选项启用Clean CSS进行压缩。更多的参数可以点击这里。
如果你不喜欢命令行环境,可以用图形界面工具,例如Koala,该神器除了可以便捷地编译Less文件,还支持Sass。
变量
个人感觉写源生CSS最大的痛苦就是没有变量和函数,封装性很差,这点其实不利于团队协作开发。而各种CSS预处理工具首要解决的就是变量和函数。
先看变量,变量声明和使用很简单,前面加上@即可。例如:
@label-width: 100px;
.label {
width: @label-width;
}
//编译出来的结果
.label {
width: 100px;
}
有了变量,维护起css代码就方便多了。以后只要改一下变量值,使用到该变量的地方都会跟着一起被改掉。
变量还可以执行数学运算:
@label-width: 100px;
.label-dpubleWidth {
width: @label-width * 2;
}
//编译出来的结果
.label-dpubleWidth {
width: 200px;
}
Mixin
Mixin也不是个什么新的概念,例如Sass里也用Mixin封装css代码,即能重用代码,而且维护简单,Less也不例外。可以理解为function,例如常规写法:
@label-width: 100px;
.label {
width: @label-width;
}
.label-border {
border: 1px solid #000;
}
//编译出来的结果
.label {
width: 100px;
}
.label-border {
border: 1px solid #000;
}
//有两个css类,因此需要在HTML标签里引用这两个css类
<p class="label label-border">less label</p>
Mixin写法:
.label {
width: @label-width;
.label-border; //在Less的css里直接引用其他css类
}
.label-border {
border: 1px solid #000;
}
//编译出来的结果
.label {
width: 100px;
border: 1px solid #000; //用Mixin将其他css类的内容直接拷贝进来了
}
// HTML标签里只需要引用一个css类即可
<p class="label">less label</p>
有了Mixin真正实现了css的代码复用。只要定义好共通的css式样,团队协作时,直接在css内部引用共同的式样即可,不必再自己重写一遍。而且维护简单,维护了共通的css式样后,引用的地方自动会跟着变。
上面这种没有参数的Mixin只是简单地无脑拷贝css代码。还能为Mixin添加参数,用函数级别来封装css。例如上面的label-border的粗细和颜色都可以通过参数传入:
.label {
width: @label-width;
.label-border(2px, #ccc);
}
.label-border(@width, @color) {
border: @width solid @color;
}
//编译出来的结果
.label {
width: 100px;
border: 2px solid #cccccc;
}
Less的参数不像JS定义的比较松散,Less的参数没有undefined的概念,如果Mixin定义了参数,调用时不能省略,否则会编译报错。但程序员懒惯了,因此Less支持为参数指定默认值:
.label {
width: @label-width;
.label-border();
}
.label-border(@width:1px, @color:#000) {
border: @width solid @color;
}
//编译出来的结果
.label {
width: 100px;
border: 1px solid #000000;
}
用Mixin来支持css兼容性再好不过啦,例如:
.label {
width: @label-width;
.border-radius()
}
.border-radius(@radius:4px) {
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
border-radius: @radius;
}
//编译出来的结果
.label {
width: 100px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
}
恼人的兼容性写法被Mixin完美地解决了。
JS里函数有arguments对象,Less里也有,有时可以稍微简化一下代码,但感觉没啥大用处:
.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 #000000;
-moz-box-shadow: 2px 5px 1px #000000;
box-shadow: 2px 5px 1px #000000;
}
Mixin后面加上关键字!important会在所有属性后面都加上!important,除了开发需要外,也能方便调试:
.foo (@bg: #f5f5f5, @color: #900) {
background: @bg;
color: @color;
}
.foo-important {
.foo(2) !important;
}
//编译出来的结果
.foo-important {
background: 2 !important;
color: #990000 !important;
}
模式匹配
Pattern-matching有点类似于if语句,可以预先定义多个同名样式,根据条件来匹配相关样式。例如:
.color(dark, @color) {
color: darken(@color, 10%);
}
.color(light, @color) {
color: lighten(@color, 10%);
}
.color(@_, @color) {
display: inline-block;
}
定义一组color样式。第一组黑色系,第二组亮色系。(darken和lighten是Less内置API。Less内置了不少常用的CSS相关的API,可以参考这里)第三组的第一个参数@_
有特殊意义,表示不论匹配到哪组,都要引用该组样式。最终我们可以根据需求觉得加载哪组color:
.label-color {
.color(light, #888); //第一个变量为light将匹配上面第一组color
}
//编译出来的结果
.label-color {
color: #a2a2a2; //最终生成亮色系的颜色
display: inline-block; //第三组color的样式,因为有参数@_,所以肯定会被加载
}
另外如果你.color(abc, #888);第一个参数一组都没匹配到,最终生成的css是第三组带@_的样式。
嵌套规则
Less支持css嵌套规则。例如ul-li-a-span的结构写源生css代码:
.ul {...}
.ui li {...}
.ui li a {...}
.ui li a span {...}
这样写虽然维护起来比较累,但估计大家都习惯了。Less能嵌套起来,方便阅读和维护:
.ul {
width: 100px;
margin: 30px auto;
.li {
background-color: #f00;
.a {
float: left;
.span {
float: right;
}
}
}
}
//编译出来的结果
.ul {
width: 100px;
margin: 30px auto;
}
.ul .li {
background-color: #f00;
}
.ul .li .a {
float: left;
}
.ul .li .a .span {
float: right;
}
上面的嵌套就像父子函数嵌套一样,会根据层级编译出相应的css源码,写起来更加方便。例如伪类可以这样写:
//css源码的写法
.li .a {…}
.li .a:hover {…}
//Less的写法
.li {
...
.a {
...
&:hover { //用&符号表示上层选择器,即.a
color: #ff0;
}
}
}
用Less的写法编译出来的结果和css源码的写法是一样的。
注释
原生css里只支持/**/来注释,Less里用//也可以添加注释。区别是,在Less里/**/的注释是会作为注释被编译进css文件的,而//的注释会被直接忽略,不会被编译进css文件。
/*这行会被编译进css*/
//这行不会被编译进css
//编译出来的结果
/*这行会被编译进css*/
Import
可以用@Import导入其他Less或CSS文件,如果导入的是Less可以省略后缀名,很简单:
@import "library";
@import "typo.css";
总结
Less的特性当然还不止这些,例如还有Extend,还定义了很多内置函数,例如color等。但我经验尚浅,看上去觉得没什么卵用…
预处理器应该方便我们写和维护CSS,如果写的特别高端,写的人爽了,维护的人惨了。实际经验是,上面这些知识点足够应付项目里的工作了,所以Less就先整理到这里。