Less介绍

26 Nov

我个人对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就先整理到这里。

Leave a Reply

Your email address will not be published. Required fields are marked *