• less入门


    、前言                             

      说到前端构建怎能缺少CSS预处理器呢!其实CSS的预处理器有很多啦,比较出名的有Scss、Sass、Stylus和Less。(最近还听说出现了Autoprefixer等CSS后处理器,可参考@一丝的PPT)

      众多CSS预处理器中Less的语法最接近原生CSS,因此相对来说更容易上手,假如有JS、C#等编程经验的话,其实上述的几种预处理器的学习成本也不会特别高。下面是我们这阵子的学习笔记,以便日后查阅。

      最好的入门教程——官网地址:http://lesscss.org/

      最佳实践之一——Bootstrap

      由于内容较多,特设目录一坨:

    •   二、搭建学习环境
    •   三、内联样式和外联样式
    •   四、语法
    •     1. 注释
    •     2. 变量(Variable)
    •         列表类型
    •     3. 嵌套(Nested)
    •     4. 父选择器引用(ParentSelector)
    •   5. 导入指令(Import)
    •     6. 继承(Extend)
    •    6.1. 父选择器必须严格匹配,除了属性选择器中属性值引号不必匹配外,或添加all关键字外。
    •    6.2. 父选择器不支持变量形式
    •    6.3. media query影响继承的作用域
    •     6.3.1. media query内的extend操作,仅能继承当前块的其他选择器样式。
    •     6.3.2. 非media query内的extend操作,将会继承所有media query中匹配的选择器样式。
    •    6.4. 增强的mixin定义mixin时仅能使用类选择器和ID选择器,而extend操作可对应所有的选择器,因此当没有动态入参而又需要类选择器和ID选择器以外的选择器时,可使用extend来实现mixin的功能。
    •     7. 混合(Mixin)
    •   7.1. 类选择器、ID选择器自动被定义为mixin,而且具有命名空间;
    •   7.2. 显示定义不带参数和带参数的样式库(mixin库),不会输出到最终输出中,仅供调用;
    •   7.3. mixin的中内置两个特殊的对象@arguments和@reset。@argumentsk代表mixin的所有入参,而@reset代表mixin的...入参数组。
    •   7.4. mixin的重载可定义多个同名mixin,调用时只要参数数量匹配则会执行相应的mixin。
    •     8. 选择、循环作业控制
    •   五、运算符
    •   六、函数
    •    1. default函数
    •      2. escape函数
    •      3. 颜色处理函数
    •   七、通过Lessc将Less引入开发环境
    •   八、实战一下
    •   九、与Grunt结合  
    •   十、总结

    二、搭建学习环境                          

      搭建Less的学习环境非常简单,只需在</body>标签前通过<script type="text/javascript" src="less.js"></script>引入处理器即可实现浏览器端中将less预编译为css样式。更有效的方式是通过如下 代码监测less样式,自动编译为css样式,从而减少我们修改less代码后需按F5后才看到实际效果的繁琐步骤。

    <script>less = { env: 'development'};</script>
    <script src="less.js"></script>
    <script>less.watch();</script>

    三、内联样式和外联样式                      

      基于我们现在使用的是浏览器端进行预编译,因此Less可用于内联样式和外联样式当中。

    内联样式如下:

    <style type="text/less">
      // less 代码
    </style>

    外联样式引入如下:

    <link rel="stylesheet/less" type="text/css" href="文件.less"/>

    四、语法                              

      1. 注释

    // 单行注释,不会作为最终输出
    /* 
        多行注释,以原生CSS的/*注释....*/形式作为最终输出
     */

      2. 变量(Variable)

         Less中的变量有以下规则:

    1. 以@作为变量的起始标识,变量名由字母、数字、_和-组成
    2. 没有先定义后使用的规定;
    3. 以最后定义的值为最终值;
    4. 可用于rule值、rule属性、rule属性部件、选择器、选择器部件、字符串拼接;
    5. 定义时 "@变量名: 变量值;" 的形式;引用时采用 "@变量名" 或 "@{变量名}" 的形式;
    6. 存在作用域,局部作用域优先级高于全局作用域。

       Less源码:

     
      @color: color;
      @dialog: .dialog;
      @suffix: fix;
      // 空格将被忽略,若要保留空格则需要使用单引号或双引号
      @hi: 'hello ';
      @dear: there  ;
          
      .dialog{
        // 用于 rule属性部件,必须使用"@{变量名}" 的形式
         background-@{color}: #888;
         // 用于 rule属性,必须使用"@{变量名}" 的形式
         @{color}: blue;
      }
      // 用于 选择器,必须使用"@{变量名}" 的形式
      @{dialog}{
          200px;
      }
      @{dialog}::after{
         content: ': @{hi}@{dear}!';    // 用于 字符串拼接,必须使用"@{变量名}" 的形式
      }
      @h: 1000px;
      // 用于 选择器部件,必须使用"@{变量名}" 的形式
      .ie-@{suffix}{
        @h: 30px; // 存在作用域,局部作用域优先级高于全局作用域。
         height: @h; // 用于 属性值,两种形式均可使用
         line-height: 30px;
      }
          
      // 1. 以@作为变量的起始标识,变量名由字母、数字、_和-组成
      // 2. 没有先定义后使用的规定;
      @dialog-border-color: #666;
      @dialog-border- 10px;
      @dialog-border- 1px; // 3. 以最后定义的值为最终值;
     

        最终输出:

     
    .dialog {
      background-color: #888;
      color: blue;
    }
    .dialog {
       200px;
    }
    .dialog::after {
      content: ': hello there!';
    }
    .ie-fix {
      height: 30px;
      line-height: 30px;
    }
     

        列表类型

        less变量除了支持#FFF,12px,12,test等单值类型外,还支持列表类型,通过内置函数extract通过索引获取列表元素,通过内置函数length获取列表的元素个数

    @colors: #FFF, #0F0, #F0F;
    .skin{
      color: extract(@colors, 0);
      height: 12px * length(@colors);
    }

       最终输出:

    .skin{
      color: #FFF;
      height: 36px;
    }

      3. 嵌套(Nested)

      Less源码:

     
    .main{
      padding: 10px;
       > div {
          100px;
       }
       .aside {
          200px;
       }
      }
        

      最终输出:

    .main {
      padding: 10px;
    }
    .main > div {
       100px;
    }
    .main .aside {
       200px;
    }

      4. 父选择器引用(ParentSelector)

    1. 采用&引用完整的父选择器
    2. 可通过追加和预追加的方式加工&,从而生成新的选择器
    3. 通过&::after等方式添加伪元素、伪类样式规则集合
    4. 同一个选择器可使用多个&
    5. 通过在选择器后添加 "空格&"的方式,可将当前选择器排列到最前面
    6. &指向组选择器时,会生成新的组选择器

      Less源码:

     
     /* 
      * 采用&引用完整的父选择器
      * 可通过追加和预追加的方式加工&,从而生成新的选择器
      * 通过&::after等方式添加伪元素样式规则集合
      * 同一个选择器可使用多个&
      * 通过在选择器后添加 "空格&"的方式,可将当前选择器排列到最前面
      */
    @bg: #aaa;
    #ps1 .btn{
      background-color: @bg;
       border-radius: 5px;
       &:hover{
         background-color: lighten(@bg, 30%);
          cursor: pointer;
       }
       &-msg, &-eof{
         color: blue;
       }
       .no-borderradius &{
         background-image: url('img/btn-bg.png');
       }
    }
    /*
     * &指向组选择器时,会生成新的组选择器
     */
    #dummy1, .dummy1{
      &:hover{
         color: red;
        }
       & + &{
         font-size: 12px;
       }
    }
     

          最终输出:

     
    /* 
     * 采用&引用完整的父选择器
     * 可通过追加和预追加的方式加工&,从而生成新的选择器
     * 通过&::after等方式添加伪元素样式规则集合
     * 同一个选择器可使用多个&
     * 通过在选择器后添加 "空格&"的方式,可将当前选择器排列到最前面
     */
    #ps1 .btn {
      background-color: #aaaaaa;
      border-radius: 5px;
    }
    #ps1 .btn:hover {
      background-color: #f6f6f6;
      cursor: pointer;
    }
    #ps1 .btn-msg,
    #ps1 .btn-eof {
      color: blue;
    }
    .no-borderradius #ps1 .btn {
      background-image: url('img/btn-bg.png');
    }
    /*
     * &指向组选择器时,会生成新的组选择器
     */
    #dummy1:hover,
    .dummy1:hover {
      color: red;
    }
    #dummy1 + #dummy1,
    #dummy1 + .dummy1,
    .dummy1 + #dummy1,
    .dummy1 + .dummy1 {
      font-size: 12px;
    }
     

    5. 导入指令(Import)

      less样式文件可通过 @import '文件路径'; 引入外部的less文件。

      注意:

    1. 不带扩展名或带非.less的扩展名均被视为less文件;
    2. @import可出现在任何位置,而不像css的@import那样只能放在文件第一行。

      另外@import还提供了6个可选配置项(分别为reference,inline,less,css,once,multiple),用来改变引入文件的特性。语法为:  @import (reference) '文件路径'; 。下面为各配置项的具体说明:

    1. @import (reference) "文件路径"; 
      将引入的文件作为样式库使用,因此文件中样式不会被直接编译为css样式规则。当前样式文件通过extendmixins的方式引用样式库的内容。
    2. @import (inline) "文件路径"; 
      用于引入与less不兼容的css文件,通过inline配置告知编译器不对引入的文件进行编译处理,直接输出到最终输出。注意:引入的文件和当前文件会被编译为一个样式样式
    3. @import (less) "文件路径"; 
      默认使用该配置项,表示引入的文件为less文件。
    4. @import (css) "文件路径"; 
      表示当前操作为CSS中的@import操作。当前文件会输出一个样式文件,而被引入的文件自身为一个独立的样式文件
    5. @import (once) "文件路径"; 
      默认使用该配置项,表示对同一个资源仅引入一次。
    6. @import (multiple) "文件路径"; 
      表示对同一资源可引入多次。

      6. 继承(Extend)

      有两种语法形式, <selector>:extend(<parentSelector>){} 和 <selector>{ &:extend(<parentSelector>); } 

       Less源码:

    .animal{
      color: #fff;
    }
    /* 语法1:<selector>:extend(<parentSelector>){} */
    .bear:extend(.animal){
       100px;
      height: 100px;
    }
    /* 语法2:<selector>{ &:extend(<parentSelector>); } */
    .deer{
      &:extend(.animal);
       50px;
      height: 50px;
    }

       最终输出:

    .animal,
    .bear,
    .deer {
      color: #fff;
    }
    /* 语法1:<selector>:extend(<parentSelector>){} */
    .bear {
       100px;
      height: 100px;
    }
    /* 语法2:<selector>{ &:extend(<parentSelector>); } */
    .deer {
       50px;
      height: 50px;
    }

    注意事项:

      6.1. 父选择器必须严格匹配,除了属性选择器中属性值引号不必匹配外,或添加all关键字外。
      Less源码:
    *.parent{
      height: 100px;
       .hair{
         color: #f27;
       }
       [name=eyes]{
         color: #768;
       }
    }
    // 匹配失败
    .son:extend(.parent){}
    .son:extend(.hair){}
              
    // 匹配成功
    .son:extend(*.parent [name='eyes']){}
    .son:extend(*.parent [name="eyes"]){}
    // all关键字会匹配所有包含parentSelector内容的选择器,并以selector替换parentSelector来生成新的选择器
    // 下面的内容会生成 *.son,*.son .hair,*.son [name=eyes]三个新的选择器
    .son:extend(.parent all){}

      最终输出:

    *.parent,
    *.son {
      height: 100px;
    }
    *.parent .hair,
    *.son .hair {
      color: #f27;
    }
    *.parent [name=eyes],
    .son,
    .son,
    *.son [name=eyes] {
      color: #768;
    }

     6.2. 父选择器不支持变量形式

     Less源码:

    @p1: .parent1;
    @p2: .parent2;
    .parent1{
      height: 100px;
    }
    @{p2}{
      height: 200px;
    }
    // 匹配失败
    // 形式1,不支持以变量作入参
    .son1:extend(@{p1}){}
    // 形式2,不支持以变量作为选择器的规则集合
    .son1:extend(.parent2){}
              
    // 匹配成功
    .son2:extend(.parent1){}
    @s3: son3;
    .@{s3}:extend(.parent1){}     

      最终输出:

    .parent1,
    .son2,
    .son3 {
      height: 100px;
    }
    .parent2 {
      height: 200px;
    }

    6.3. media query影响继承的作用域

      6.3.1. media query内的extend操作,仅能继承当前块的其他选择器样式。

          注意:不能extend当前media query块内部的子media query块中的选择器样式;但可以extend父media query块的选择器样式。

        Less源码:

    .parent1{
      height: 200px;
    }
    @media screen{
      .parent1{
        height: 100px;
      }    
       // 无法继承子media query块的选择器样式
       .son1:extend(.parent2){}
       @media (min- 1023px){
         // 继承父media query块的选择器样式
          .son2:extend(.parent1){}
          .parent2{
             200px;
          }
       }
    }   

        最终输出:

    .parent1 {
      height: 200px;
    }
    @media screen {
      .parent1 {
        height: 100px;
      }
    }
    @media screen and (min- 1023px) {
      .parent2 {
         200px;
      }
    }

      6.3.2. 非media query内的extend操作,将会继承所有media query中匹配的选择器样式。

       Less源码:

    @media screen{
      .parent{
         height: 100px;
       }
       @media (min- 1023px){
         .parent{
              200px;
           }
       }
    }
    .son:extend(.parent){}

      最终输出:

    @media screen {
      .parent,
      .son {
        height: 100px;
      }
    }
    @media screen and (min- 1023px) {
      .parent,
      .son {
         200px;
      }
    }

     6.4. 增强的mixin定义mixin时仅能使用类选择器和ID选择器,而extend操作可对应所有的选择器,因此当没有动态入参而又需要类选择器和ID选择器以外的选择器时,可使用extend来实现mixin的功能。

    7. 混合(Mixin)

      Mixin相当于macro,会将样式规则内联到调用的位置中。而Less中的mixin有以下的注意点:

      7.1. 类选择器、ID选择器自动被定义为mixin,而且具有命名空间;
      Less源码:
    .animal{
      .human{
         #fsjohnhuang{
            .hair{
                color: #000;
              }
           }    
        }    
    }    
    .front-end-monkey{
      // 或者.animal.human#fsjohnhuang.hair();
      // 或者.animal>.human>#fsjohnhuang>.hair;
       // 或者.animal>.human>#fsjohnhuang>.hair();
       // 即可调用mixin
       .animal.human#fsjohnhuang.hair;
    }

      最终输出:

    .animal .human #fsjohnhuang .hair {
      color: #000;
    }
    .front-end-monkey {
      color: #000;
    }

      7.2. 显示定义不带参数和带参数的样式库(mixin库),不会输出到最终输出中,仅供调用;

      Less源码:

    // 定义不带参数的mixin
    .animal(){
      color: #000;
    }
    // 定义带参数的mixin
    // 注意:由于,和;均可用于作为参数分隔符,但由于如background、border等样式属性支持属性值组,而,则作为属性值组元素分隔符,因此推荐使用;作为参数分隔符
    .dog(@type; @age){
      height: @type * @age * 12px;
    }
    // 定义带参数默认值的mixin
    .cat(@type; @age:1){
      height: @type * @age * 5px;
    }
              
    // 调用才会出现在最终输出
    .chihuahua{
      .dog(1;2);
    } 

      最终输出:

    .chihuahua {
      height: 24px;
    }

      7.3. mixin内置两个特殊的对象 @arguments 和 @reset 。@arguments代表mixin的所有入参,而@reset代表mixin的...入参数组。

      Less源码:

    .dog(@type;@age;@rest...){
      height: @type * @age * 12px;
      border: @rest;
    }
    .cat(@solid;@w;@color){
      border: @arguments;
    }
              
    .chihuahua{
      .dog(1;2;solid;1px;red);    
    }
    .mimi{
      .cat(solid;2px;blue);    
    }

      最终输出:

    .chihuahua {
      height: 24px;
      border: solid 1px red;
    }
    .mimi {
      border: solid 2px blue;
    }

      7.4. mixin的重载可定义多个同名mixin,调用时只要参数数量匹配则会执行相应的mixin。

      Less源码:

    .dog(@name){
      &::after{
        content: @name;
       }
    }
    .dog(@name;@age){
      height: @age * 4px;
    }
    .dog(@name;@age;@20px){
      height: @age * 12px;
       @width;
    }
    // 仅匹配到 .dog(@name){
    .one-dog{
      .dog('chihuahua');
    }    
    // 匹配到.dog(@name;@age) 和 .dog(@name;@age;@20px)
     .two-three-dog{
       .dog('two-three-dog', 2);
    }
              
    // 参数的模式匹配
    // 当第一参数值为mimi时调用该mixin
    .cat(mimi, @age){
      height: @age * 22px;    
    }
    // 当第一参数值为mini时调用该mixin
    .cat(mini, @age){
      height: @age * 12px;    
    }
    // 不管第一参数值为啥均调用该mixin
    .cat(@any, @age){
      color: #f3c;
    }
    .mycat{
      .cat(mini, 1);
    }

      最终输出:

    .one-dog::after {
      content: 'chihuahua';
    }
    .two-three-dog {
      height: 8px;
      height: 24px;
       20px;
    }
    .mycat {
      height: 12px;
      color: #f3c;
    }

     8. 选择、循环作业控制

         Less中通过混合(Mixin)后的when关键字来提供选择的作业控制,通过递归来实现循环的作业控制。

      Less源码:

    // 条件匹配
    // true值匹配,仅实参为true时才匹配成功
    .truth(@a) when (@a){
      &::after{
      content: @a;
      }
    }
    // 匹配成功
    .truth1{
      .truth(true);
    }
    // 匹配失败
    .truth2{
      .truth(#fff);
    }
              
    /* 类型判断函数
     * iscolor
     * isnumber
     * isstring
     * iskeyword
     * isurl
     */
    .bear(@color) when (iscolor(@color)){
      color: @color;
    }
    /* 单位判断函数
     * ispixel
     * ispercentage
     * isem
     * isunit
     */
    .bear(@height) when (ispixel(@height)){
      height: @height;
    }
    // =,>,>=,<=,< 关系运算符
    .rich(@h) when (@h > 1000){
      height: @h;    
    }
    // and、not、or(使用,号表示) 逻辑运算符
    .huge(@h, @w) when (@h > 180) and (@w > 180){
      height: @h;
       @w;
    }
    // 使用& when()实现if语句
    @debug: true;
    & when (@debug){
      div{
        border: solid 1px red;
        }
    }
              
    // 通过递归实现循环
    .generate-columns(4);
    .generate-columns(@n, @i: 1) when (@i =< @n) {
      .column-@{i} {
         (@i * 100% / @n);
      }
       .generate-columns(@n, (@i + 1));
    }

      最终输出:

     
    .truth1::after {
      content: true;
    }
    /* 类型判断函数
     * iscolor
     * isnumber
     * isstring
     * iskeyword
     * isurl
     */
    /* 单位判断函数
     * ispixel
     * ispercentage
     * isem
     * isunit
     */
    div {
      border: solid 1px red;
    }
    .column-1 {
       25%;
    }
    .column-2 {
       50%;
    }
    .column-3 {
       75%;
    }
    .column-4 {
       100%;
    }

    五、运算符                            

      Less还支持+、-、*、/运算符。但对单位不一致的运算数进行运算要注意以下两点:

      1. 运算数与运算符间必须用空格分隔;

      2. 以第一个运算数的单位作为运算结果的单位;

        Less源码:

     
    // 运算数与运算符间没有空格
    @fail: 1px +2em;
    .fail{
      height: @fail;
    }
    
    @success1: 1px + 2em;
    .success1{
      height: @success1;
    }
    
    @success2: 2px + 1em;
    .success2{
      height: @success2;
    }

        最终输出:

    .fail{
      height: 1px 2em;
    }
    
    .success1{
      height: 3px;
    }
    
    .success2{
      height: 3em;
    }
     

    六、函数                              

      Less为我们提供了一个功能强大的内置函数库,其中绝大部分为颜色处理函数。下面着重介绍Misc Function中的default函数、String Function中的escape函数和颜色处理函数。

      1. default函数

         示例:

     
    // for teenager
    .person(@age) when (@age <= 19) and (@age >=13){
      height: @age * 10px;
    }
    // for child
    .person(@age) when (@age <13){
      height: @age * 6px;
    }
    // for adult
    .person(@age) when (default()){
      height: 180px;
    }
    
    .son{
      .person(10);
    }
    .daughter{
      person(17);
    }
    .father{
     .person(27);
    }

        最终输出:

    .son{
      height: 60px;
    }
    .daughter{
      height: 170px;
    }
    .father{
      height: 180px;
    }
     

        虽然上述示例逻辑上不合理。但可以看出default函数用于条件控制当中,充当else或switch语句中default的角色。

        通过官网提供的综合示例我们可以更好理解它的用法:

     
    // Less源码
    .x {
      .m(red)                                    {case-1: darkred}
      .m(blue)                                   {case-2: darkblue}
      .m(@x) when (iscolor(@x)) and (default())  {default-color: @x}
      .m('foo')                                  {case-1: I am 'foo'}
      .m('bar')                                  {case-2: I am 'bar'}
      .m(@x) when (isstring(@x)) and (default()) {default-string: and I am the default}
    
      &-blue  {.m(blue)}
      &-green {.m(green)}
      &-foo   {.m('foo')}
      &-baz   {.m('baz')}
    }
    
    // 最终输出
    .x-blue {
      case-2: #00008b;
    }
    .x-green {
      default-color: #008000;
    }
    .x-foo {
      case-1: I am 'foo';
    }
    .x-baz {
      default-string: and I am the default;
    }
     

       注意:

         1. default函数必须在条件控制语句当中使用;

         2. default函数可实现比else更复杂的功能,如下:

     
    // Less源码
    .mixin(@value) when (ispixel(@value)) { @value}
    .mixin(@value) when not(default())    {padding: (@value / 5)}
    
    div-1 {
      .mixin(100px);
    }
    
    div-2 {
      /* ... */
      .mixin(100%);
    }
    
    // 最终输出:
    div-1 {
       100px;
      padding: 20px;
    }
    div-2 {
      /* ... */
    }

      2. escape函数

        顾名思义就是对字符串中的特定字符进行编码,该函数将对<space>#^(){}|:><;][ 和 =字符进行编码。

      3. 颜色处理函数

        颜色处理函数又分为四大类:颜色定义函数(Color Definition)、颜色通道值获取函数(Color Channel)、颜色通道值修改函数(Color Operation Function)、混色函数(Color Blending)。

        这里仅仅介绍常用的lighten和darken函数。

         lighten(color, amount) ,color为颜色,amount为增加的亮度值,取值范围为0-100%。

         darken(color, amount) ,color为颜色,amount为减少的亮度值,取值范围为0-100%。

    七、通过Lessc将Less引入开发环境                 

       到这里我想大家已经对Less有一定程度的了解,并希望在将其加入你的开发工具包中。但通过less.js将Less解析器引入到浏览器肯定是不适合开发的,而cli工具lessc更适合开发环境中使用。在使用之前我们先要通过npm来安装less。

    npm install -g less

      然后我们就可以通过 lessc [option option=parameter ...] <source> [destination] 的命令格式来调用lessc了!

      lessc的option选项较多,我将主要的选项分为lessc命令信息相关sourcemap相关@import指令相关插件相关四类。

      1. lessc命令信息相关

         lessc -h ,获取lessc命令的帮助信息;

         lessc -v ,获取lessc命令的版本号。

      2. sourcemap相关

         由于在浏览器直接查看和操作的是CSS样式规则,而我们开发时使用的Less代码,这会导致难以找到CSS样式规则所对应的Less代码从而增大调试难度。而sourcemap就是为了解决这一痛点而提出的技术解决方案,其原理就是通过一个map文件来保存两个文件中代码的对应关系,然后支持sourcemap的浏览器的devTools中就会根据这些对应关系来定位相应的Less代码。(Chrome和FF均支持sourcemap,IE11及以下均不支持)

         若对sourcemap不太了解的可以参考《前端构建:Source Maps详解》

          --source-map ,生成与生成的css同名的sourcemap文件(例如生成的css文件为main.css,那么sourcemap文件就是main.css.map),且与css文件位于同一目录下;

          --source-map=<sourcemap文件路径> ,自定义sourcemap文件的路径;

           --source-map-rootpath=<sourcemap文件中sources属性值的路径前缀> ,假如main.less文件位于src/less下,而生成的css和sourcemap文件位于bin/style下,那么就需要修改sourcemap文件中用于指向less文件路径的sources属性值,浏览器才能通过sourcemap文件查找到less文件。上述例子的命令为:

                         lessc --source-map --source-map-rootpath=../../src/less/main.less src/less/main.less bin/style/main.css 

           --source-map-map-inline ,以data URI Scheme的形式将sourcemap文件内容内嵌到css文件中。

           --source-map-url=<css文件中指向sourcemap文件的url> ,默认情况下css文件的最后一行会插入如 /*# sourceMappingURL=main.css.map */ 的内容来指向sourcemap文件,而该选项则可修改sourceMappingURL的值。

      3. @import指令相关

           --include-path=<path>[;<path>]* ,通过@import指令引入外部less或css等文件时存在引入的文件路径到底是以哪个目录作为参考的问题,我们可以通过该选项来指定参考目录,当存在多个参考目录时,使用;号分隔。

           --relative-urls 或 -ru ,用于保持样式库中的图片等资源的相对路径。示例:

    # main.less
    @import "files/backgrounds.less";
    # files/backgrounds.less
    .icon-1 {
      background-image: url('images/lamp-post.png');
    }

          不使用该选项时:

    .icon-1 {
      background-image: url('images/lamp-post.png');
    }

          使用该选项时:

    .icon-1 {
      background-image: url('files/images/lamp-post.png');
    }

      4. 插件相关

          lessc以插件的形式来增强其功能,下面仅介绍clean-css插件,其他插件请参考http://lesscss.org/usage/#plugins-list-of-less-plugins

          clean-css插件用于压缩css文件(less-plugin-clean-css@github)

          首先通过npm安装插件 npm install -g less-plugin-clean-css ,然后通过--clean-css选项来启动CSS压缩功能。

            如: lessc file.less --clean-css="--s1 --advanced --compatibility=ie8"  

    八、实战一下                          

     先假定我们开发环境的目录结构如下(灰色表示文件由构建工具生成):

      sample

        |-- build.bat     构建工具

        |-- lib              第三方依赖库

        |     |-- less     

        |            |-- base.less 

        |            |-- img

        |                  |-- nav.png

        |-- src              源码

        |     |-- less

        |     |      |-- main.less

        |     |-- index.html

        |-- bin              编译后的文件

        |     |-- style

        |             |-- main.css

        |             |-- main.css.map

        |     |-- index.html

        |-- dist              发布文件

        |-- lib

        |  |-- less

        |          |-- img

        |                |-- nav.png

        |-- app

          |-- style

          |   |--main.css

          |-- index.html

      index.html文件内容:

    <html>
    <head>
        <title></title>
        <link rel="stylesheet" type="text/css" href="style/main.css"/>    
    </head>
    <body>
        <div class="nav">
        </div>
    </body>
    </html>

      样式库base.less文件内容:

    .base-nav{
        height: 50px;
        background-image: url(img/nav.png);
    }
    .base-debug{
        border: solid 5px red;
    }

       main.less文件内容:

    @import (reference) "base.less";
    @env:release; //编译模式:release或debug
    
    /* 导航栏 */
    .nav:extend(.base-nav){
        // 编译模式为debug时采用该样式
        & when (@env=debug){
            .base-debug();
        }
    }

       我们一般将工程代码级别的产出分为源码可执行代码 可发布代码 三种,而可执行代码和可发布代码的构建需求是不同的,因此构建方式也有所区别,也就是lessc使用的选项也会不同。下面将针对不同的产出物来介绍lessc的使用。

       1. 可执行代码

         我将可执行代码部分再细分为release和debug两种编译模式,可以看到通过变量@env来实现不同模式下采用不同的样式规则。默认采用release模式编译源码。

    lessc --include-path=lib/less --relative-urls --source-map --source-map-rootpath=../../src/less/main.less src/less/main.less bin/style/main.css

         在执行lessc命令时通过选项--modify-var="env=debug"即可以debug模式编译源码。

    lessc --include-path=lib/less --relative-urls --source-map --source-map-rootpath=../../src/less/ --modify-var="env=debug" src/less/main.less bin/style/main.css

         可以看到上述编译过程中均会生成sourcemap文件以便调试使用。

       2. 可发布代码

         对于发布的内容我们会对其进行压缩处理

    lessc --include-path=lib/less --clean-css="advanced" --relative-urls src/less/main.less dist/app/style/main.css

         由于sourcemap文件仅在开发阶段有用,因此生成发布代码时就不要生成了。

       完整的构建文件build.bat如下:

    View Code

        然后在CMD中输入 build bin  、 build debug  或  build dist  即可构建工程了!

     sample@github

    九、与Grunt结合                          

      我们沿用第八节的工程目录结构来演示。

      首先我们要将npm的package.json添加到工程中,然后安装grunt及其插件(grunt-contrib-less,less-plugin-clean-css,grunt-contrib-clean,grunt-contrib-copy),现在我们的工程结构应该是这样的。

     sample-grunt

        |-- package.json

        |-- Gruntfile.js

        |-- node_modules   

        |-- lib              第三方依赖库

        |     |-- less     

        |            |-- base.less 

        |            |-- img

        |                  |-- nav.png

        |-- src              源码

        |     |-- less

        |     |      |-- main.less

        |     |-- index.html

        |-- bin              编译后的文件

        |     |-- style

        |             |-- main.css

        |             |-- main.css.map

        |     |-- index.html

        |-- dist              发布文件

        |-- lib

        |  |-- less

        |          |-- img

        |                |-- nav.png

        |-- app

          |-- style

          |   |--main.css

          |-- index.html

       其中用于将Less编译为CSS的插件为grunt-contrib-less, 下面我们对应第八章的内容来介绍该插件的选项。

       sourcemap相关:

       {Boolean} sourceMap,对应lessc中属性值为true/false的--source-map选项;

       {String} sourceMapFilename,对应lessc中属性值为String的--source-map选项;

       {String} sourceMapRootPath,对应lessc的--source-map-rootpath选项;

       {String} sourceMapURL,对应lessc的--source-map-url选项;

       {Boolean} outputSourceFiles,,对应lessc的--source-map-map-inline选项;

       @import指令相关:

     {Array|String} paths,对应lessc的--include-path选项;

       {Boolean} relativeUrls,对应lessc的--relative-urls选项;

       插件相关:

      {Array} plugins,数组元素为插件实例。

       Gruntfile.js内容如下:

    View Code

       sample-grunt@github

    十、总结                              

      到这里我只能和大家说一声,“辛苦了各位,终于看完了耶!”。但正如标题所说,此刻无论是对less的使用,还是将其融入我们的开发工作流,我们均是入了个门而已。那应该如何进阶呢?那就是

    ;; 定义进阶过程
    (defn becomeGeek [progress]
        (.log js/console "实践->总结->参考最佳实践")
        (if (> 100 progress) 
            (becomeGeek (+ 1 progress))
        ))
    
    ;; 努力吧骚年!
    (becomeGeek 1)
  • 相关阅读:
    element-ui 后台问题
    element-ui 使用:rules对表单字段进行验证
    扫码枪 移动端监听
    前端好用工具介绍——wulihub
    移动端 扫描枪输入不弹出键盘
    移动端 input输入实时监听查询数据渲染
    新老系统统一认证解决方案
    转 高性能IO模型浅析
    数据库备份方案
    软件开发阶段数据库升级维护策略
  • 原文地址:https://www.cnblogs.com/aure/p/4682621.html
Copyright © 2020-2023  润新知