前端構建:Less入了個門

http://www.w3cplus.com/css/lessjavascript

1、前言                             
css

  說到前端構建怎能缺乏CSS預處理器呢!其實CSS的預處理器有不少啦,比較出名的有Scss、Sass、Stylus和Less。(最近還據說出現了Autoprefixer等CSS後處理器,可參考@一絲的PPT)html

  衆多CSS預處理器中Less的語法最接近原生CSS,所以相對來講更容易上手,假若有JS、C#等編程經驗的話,其實上述的幾種預處理器的學習成本也不會特別高。下面是咱們這陣子的學習筆記,以便往後查閱。前端

  最好的入門教程——官網地址:http://lesscss.org/java

  最佳實踐之一——Bootstrapnode

  因爲內容較多,特設目錄一坨:git

  2、搭建學習環境github

  3、內聯樣式和外聯樣式npm

  4、語法編程

    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. 選擇、循環做業控制

  5、運算符

  6、函數

   1. default函數

     2. escape函數

     3. 顏色處理函數

  7、經過Lessc將Less引入開發環境

  8、實戰一下

  9、與Grunt結合  

  10、總結

2、搭建學習環境                          

  搭建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>

 

3、內聯樣式和外聯樣式                      

  基於咱們如今使用的是瀏覽器端進行預編譯,所以Less可用於內聯樣式和外聯樣式當中。

內聯樣式以下:

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

外聯樣式引入以下:

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

 

4、語法                              

  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}{
     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. 採用&引用完整的父選擇器
  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){
  width: 100px;
  height: 100px;
}
/* 語法2:<selector>{ &:extend(<parentSelector>); } */
.deer{
  &:extend(.animal);
  width: 50px;
  height: 50px;
}
複製代碼

   最終輸出:

複製代碼
.animal,
.bear,
.deer {
  color: #fff;
}
/* 語法1:<selector>:extend(<parentSelector>){} */
.bear {
  width: 100px;
  height: 100px;
}
/* 語法2:<selector>{ &:extend(<parentSelector>); } */
.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%;
}
複製代碼

 

5、運算符                            

  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;
}
複製代碼

 

6、函數                              

  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%。

 

7、經過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"  

 

8、實戰一下                          

 先假定咱們開發環境的目錄結構以下(灰色表示文件由構建工具生成):

  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以下:

@echo off
cls
goto :%1

:bin
echo Building......
::remove subitems of bin
rd /S /Q bin
::copy html files
xcopy /y src\*.html bin\
::compile less to css
cmd /C lessc --include-path=lib/less --relative-urls --source-map --source-map-rootpath=../../src/less/main.less src/less/main.less bin/style/main.css
echo Building is over!
goto :over

:debug
echo Building......
::remove subitems of bin
rd /S /Q bin
::copy html files
xcopy /y src\*.html bin\
::compile less to css
cmd /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.css
echo Building is over!
goto :over

:dist
echo Deploying......
::remove subitems of dist
rd /S /Q dist
::copy lib
xcopy /y lib\less\img dist\lib\less\img\
::copy html files
xcopy /y src\*.html dist\app\
::compile less to css
cmd /C lessc --include-path=lib/less --clean-css="advanced" --relative-urls src/less/main.less dist/app/style/main.css
echo Deploying is over!

:over
View Code

    而後在CMD中輸入 build bin  、 build debug  或  build dist  便可構建工程了!

 sample@github

 

9、與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內容以下:

'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

   sample-grunt@github

 

10、總結                              

  到這裏我只能和你們說一聲,「辛苦了各位,終於看完了耶!」。但正如標題所說,此刻不管是對less的使用,仍是將其融入咱們的開發工做流,咱們均是入了個門而已。那應該如何進階呢?那就是

複製代碼
;; 定義進階過程
(defn becomeGeek [progress]
    (.log js/console "實踐->總結->參考最佳實踐")
    (if (> 100 progress) 
        (becomeGeek (+ 1 progress))
    ))

;; 努力吧騷年!
(becomeGeek 1)
複製代碼

   尊重原創,轉載請註明來自:http://www.cnblogs.com/fsjohnhuang/p/4187675.html ^_^肥仔John!

相關文章
相關標籤/搜索