博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
前端构建:Less入了个门
阅读量:6078 次
发布时间:2019-06-20

本文共 21626 字,大约阅读时间需要 72 分钟。

一、前言                             

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

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

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

  最佳实践之一——Bootstrap

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

 

   

   

       

   

   

 

   

  

  

   

    

    

   

   

  

  

  

  

   

 

   

     

     

 

 

   

二、搭建学习环境                          

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

 

三、内联样式和外联样式                      

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

内联样式如下:

外联样式引入如下:

 

四、语法                              

  1. 注释

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

  2. 变量(Variable)

     Less中的变量有以下规则:

  1. 以@作为变量的起始标识,变量名由字母、数字、_和-组成
  2. 没有先定义后使用的规定;
  3. 可用于、、、、、;
  4. 定义时 "@变量名: 变量值;" 的形式;引用时采用 "@变量名" 或 "@{变量名}" 的形式;

   Less源码:

@color: color;  @dialog: .dialog;  @suffix: fix;  // 空格将被忽略,若要保留空格则需要使用单引号或双引号  @hi: 'hello ';  @dear: there  ;        .dialog{    // 用于 rule属性部件,必须使用"@{变量名}" 的形式     background-@{color}: #888;     // 用于 rule属性,必须使用"@{变量名}" 的形式     @{color}: blue;  }  // 用于 选择器,必须使用"@{变量名}" 的形式  @{dialog}{     width: 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-width: 10px;  @dialog-border-width: 1px; // 3. 以最后定义的值为最终值;

    最终输出:

.dialog {  background-color: #888;  color: blue;}.dialog {  width: 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 {     width: 100px;   }   .aside {     width: 200px;   }  }

  最终输出:

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

  4. 父选择器引用(ParentSelector)

  1. 采用&引用完整的父选择器

  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样式规则。当前样式文件通过
extend
mixins的方式引用样式库的内容。
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:
:extend(
){} */.bear:extend(.animal){  width: 100px;  height: 100px;}/* 语法2:
{ &:extend(
); } */.deer{  &:extend(.animal);  width: 50px;  height: 50px;}

   最终输出:

.animal,.bear,.deer {  color: #fff;}/* 语法1:
:extend(
){} */.bear { width: 100px; height: 100px;}/* 语法2:
{ &:extend(
); } */.deer { width: 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-width: 1023px){     // 继承父media query块的选择器样式      .son2:extend(.parent1){}      .parent2{        width: 200px;      }   }}

    最终输出:

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

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

   Less源码:

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

  最终输出:

@media screen {  .parent,  .son {    height: 100px;  }}@media screen and (min-width: 1023px) {  .parent,  .son {    width: 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;@width:20px){  height: @age * 12px;  width: @width;}// 仅匹配到 .dog(@name){
.one-dog{  .dog('chihuahua');} // 匹配到.dog(@name;@age) 和 .dog(@name;@age;@width: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;  width: 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;  width: @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} {    width: (@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 {  width: 25%;}.column-2 {  width: 50%;}.column-3 {  width: 75%;}.column-4 {  width: 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)) {width: @value}.mixin(@value) when not(default())    {padding: (@value / 5)}div-1 {  .mixin(100px);}div-2 {  /* ... */  .mixin(100%);}// 最终输出:div-1 {  width: 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文件()

      首先通过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文件内容:

        

  样式库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如下:

@echo offclsgoto :%1:binecho Building......::remove subitems of binrd /S /Q bin::copy html filesxcopy /y src\*.html bin\::compile less to csscmd /C lessc --include-path=lib/less --relative-urls --source-map --source-map-rootpath=../../src/less/main.less src/less/main.less bin/style/main.cssecho Building is over!goto :over:debugecho Building......::remove subitems of binrd /S /Q bin::copy html filesxcopy /y src\*.html bin\::compile less to csscmd /C 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.cssecho Building is over!goto :over:distecho Deploying......::remove subitems of distrd /S /Q dist::copy libxcopy /y lib\less\img dist\lib\less\img\::copy html filesxcopy /y src\*.html dist\app\::compile less to csscmd /C lessc --include-path=lib/less --clean-css="advanced" --relative-urls src/less/main.less dist/app/style/main.cssecho Deploying is over!:over
View Code

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

 

 

九、与Grunt结合                          

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

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

 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内容如下:

'use strict'var lessBinDebugOpts = {        sourceMap: true,        sourceMapRootpath: '../../'    },    debug = {env: 'debug'}module.exports = function(grunt){    grunt.initConfig({        clean: {            options:{                force: true            },            bin: ['bin'],            dist: ['dist']        },        copy: {            bin: {                files: [                    {expand: true, cwd: 'src/', src: '*.html', dest: 'bin/'}                ]            },            dist: {                files:[                    {expand: true, cwd: 'lib/', src: '**', dest: 'dist/lib/'},                    {expand: true, cwd: 'src/', src: '*.html', dest: 'dist/app'}                ]            }            },        less: {            options:{                paths: 'lib/less',                relativeUrls: true            },            bin:{                options: (delete lessBinDebugOpts.modifyVars, lessBinDebugOpts),                files: {                    'bin/style/main.css': 'src/less/main.less'                }            },            debug:{                options: (lessBinDebugOpts.modifyVars = debug, lessBinDebugOpts),                files: {                    'bin/style/main.css': 'src/less/main.less'                }            },            dist:{                options:{                    plugins: [new (require('less-plugin-clean-css'))({advanced: true})]                },                files: {                    'dist/app/style/main.css': 'src/less/main.less'                }            }        }    })    grunt.loadNpmTasks('grunt-contrib-less')    grunt.loadNpmTasks('grunt-contrib-copy')    grunt.loadNpmTasks('grunt-contrib-clean')    var task = function(){        var name = this.name            , tasks = ['clean', 'copy', 'less']            , targets = tasks.map(function(v, i, m){                var target = name === 'debug' && v !== 'less' ? 'bin' : name                return v + ':' + target            })        grunt.task.run(targets)    }    grunt.registerTask('bin', task)    grunt.registerTask('debug', task)    grunt.registerTask('dist', task)}
View Code

   

 

十、总结                              

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

;; 定义进阶过程(defn becomeGeek [progress]    (.log js/console "实践->总结->参考最佳实践")    (if (> 100 progress)         (becomeGeek (+ 1 progress))    ));; 努力吧骚年!(becomeGeek 1)

   尊重原创,转载请注明来自: ^_^肥仔John!

 

如果您觉得本文的内容有趣就扫一下吧!捐赠互勉!

分类:
+加关注
14
0
上一篇:
下一篇:
posted @ 2015-01-07 15:18 阅读( 38255) 评论( 8)
  
2015-01-07 17:31
不错,以前接触过less,现在看来也是学到很多
  
2015-01-08 09:06
没有什么吸引力啊,能不能整点干货呢?
css写法快不只有这种方式嘛
http://pic.cnblogs.com/face/424274/20130126034040.png
  
2015-09-19 16:10
css中的@import指令并不是说只能放在.css文件第一行,而是说一定要在所有的样式表之前使用,多个引用写多行;
这个地方的“第一行”容易让很多不了解css@import指令的人误解
  
2016-03-07 20:46
请问下,less.watch机制可以在我更改了less中的代码后,浏览器无需刷新页面,就能显示最新的结果,这是如何实现的?
http://pic.cnblogs.com/face/696637/20141219193815.png
  
2016-06-20 15:08
看extend 6.2
// 匹配失败
// 形式1,不支持以变量作入参
.son1:extend(@{p1}){}
// 形式2,不支持以变量作为选择器的规则集合
.son1:extend(.parent2){}
// 匹配成功
.son2:extend(.parent1){}
.son1:extend(.parent2){}和 .son2:extend(.parent1){}不是一回事吗?我是小白,看到这里我蒙逼了,不懂为啥第一个匹配失败,第二个就匹配成功了
http://pic.cnblogs.com/face/853802/20170425114819.png
  
2016-06-20 15:11
@
我又仔细看了一遍,好像是懂了
http://pic.cnblogs.com/face/853802/20170425114819.png
  
2017-03-03 19:42
非常好,正是我需要的,谢谢大佬,收藏了
http://pic.cnblogs.com/face/1108721/20170221073311.png
  
3750466 2017/8/4 10:56:51
2017-08-04 10:56
bootstrap特效对照手册:
最新IT新闻:
·
·
·
·
·
»
最新知识库文章:
·
·
·
·
·
»

公告

作品:
本文转自
博客园博客,原文链接: ,如需转载请自行联系原作者
 
 
你可能感兴趣的文章
要想成为高级Java程序员需要具备哪些知识呢?
查看>>
带着问题去学习--Nginx配置解析(一)
查看>>
onix-文件系统
查看>>
java.io.Serializable浅析
查看>>
我的友情链接
查看>>
多线程之线程池任务管理通用模板
查看>>
CSS3让长单词与URL地址自动换行——word-wrap属性
查看>>
CodeForces 580B Kefa and Company
查看>>
开发规范浅谈
查看>>
Spark Streaming揭秘 Day29 深入理解Spark2.x中的Structured Streaming
查看>>
鼠标增强软件StrokeIt使用方法
查看>>
本地连接linux虚拟机的方法
查看>>
某公司面试java试题之【二】,看看吧,说不定就是你将要做的题
查看>>
BABOK - 企业分析(Enterprise Analysis)概要
查看>>
Linux 配置vnc,开启linux远程桌面
查看>>
NLog文章系列——如何优化日志性能
查看>>
Hadoop安装测试简单记录
查看>>
CentOS6.4关闭触控板
查看>>
ThreadPoolExecutor线程池运行机制分析-线程复用原理
查看>>
React Native 极光推送填坑(ios)
查看>>