Less介绍

作者: 张歆琳 | 来源:发表于2016-11-26 00:27 被阅读503次

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

    相关文章

      网友评论

        本文标题:Less介绍

        本文链接:https://www.haomeiwen.com/subject/uliwpttx.html