前端入門23-CSS預處理器(Less&Sass)

聲明

本篇內容梳理自如下幾個來源:css

感謝大佬們的分享。html

正文-CSS預處理(less&Sass)

CSS預處理

什麼是 CSS 預處理?爲何要有 CSS 預處理?node

這裏就講講這兩個問題,寫過 CSS 應該就會比較清楚,雖然我纔剛入門,但在寫一些練手時就已經有點感受了:寫 CSS 後,很難維護,維護基本要靠註釋來,並且因爲 HTML 文檔中標籤的嵌套層次複雜,致使寫 CSS 的選擇器時也很費勁,尤爲是在後期爲某部分標籤新增樣式時,總會不知道到底應該在 CSS 文件中哪裏寫這個選擇器,這個選擇器是否會與前面衝突。git

最有感受的一點是,CSS 代碼基本無法複用,一個頁面一份 CSS,每次都須要重寫,只是不少時候,能夠直接去舊的裏面複製粘貼。github

有這麼些問題是由於 CSS 自己並非一門編程語言,它只是一個標記語言,靜態語言,不具有編程語言的特性,因此寫容易,但維護會比較難。web

這個時候,CSS 預處理器就出現了,其實應該是說 Sass 和 Less 這類語言出現了。npm

Sass 和 Less 這類語言,其實能夠理解成 CSS 的超集,也就是它們是基於 CSS 本來的語法格式基礎上,增長了編程語言的特性,如變量的使用、邏輯語句的支持、函數等。讓 CSS 代碼更容易維護和複用。編程

但瀏覽器最終確定是只認識 CSS 文件的,它並沒有法處理 CSS 中的那些變量、邏輯語句,因此須要有一個編譯的過程,將 Sass 或 Less 寫的代碼轉換成標準的 CSS 代碼,這個過程就稱爲 CSS 預處理。json

因此,CSS 預處理器其實只是一個過程的稱呼,主要工做就是將源代碼編譯並輸出標準的 CSS 文件,而這個源代碼能夠用 Sass 寫,也能夠用 Less,固然還有其餘不少種語言。數組

那麼,到底哪種語言好,我還沒能力來討論,反正存在即有理,每種語言總它的優缺點、總有它的適用場景。

下面,主要就來介紹下其中的兩種語言:Less 和 Sass。

我以爲,掌握 CSS 預處理的關鍵,其實也就兩點,一是掌握語言的語法、二是清楚怎麼編譯成標準的 CSS 文件;語法基本都不會很難,編譯通常須要配置一些環境,由於我使用的開發工具是 WebStrom,因此會介紹下 WebStrom 上的配置。

Less

使用

Less 寫的 CSS 文件後綴名爲 .less,但瀏覽器並不認識 less 文件,因此最後須要轉換成 css 文件,有兩種方式:

  • 藉助 less.js,程序運行期間,瀏覽器會自動藉助 less.js 來解析 less 文件內的代碼,轉成 css 標準語法

這種方式,不須要配置任何其餘環境,只須要下載 less.js,並在項目中使用便可,但有幾點須要注意:

<head>
    <!--link標籤須要設置 rel=stylesheet/less, less.js的加載須要放在全部 link 標籤後面-->
    <link rel="stylesheet/less" type="text/css" href="css/src/main.less"/>
    <link rel="stylesheet/less" type="text/css" href="css/src/test.less"/>
    <script src="js/lib/less.js"></script>
</head>

HTML 文檔經過 link 標籤引入 less 文件時,須要將 link 標籤的 rel 屬性設置爲 stylesheet/less,不然無效;

並且,用 <script> 標籤加載 less.js 的代碼須要放在最後,即全部用 link 標籤引入 less 文件的後面,由於 less.js 文件加載成功後就會去將 less 轉成 css 標準樣式,在 <script> 標籤後面才用 link 標籤引入的那些 less 文件就沒法被轉換了。

less.js 下載地址:https://github.com/less/less.js/releases

  • 藉助 node.js 環境,安裝完 less 後,執行 lessc 命令

第一種方式,雖然便捷,但會讓頁面的渲染多了一個轉換步驟,延長頁面渲染時長,因此,還能夠用第二種方式,直接在本地將 less 轉成 css 文件後,項目直接使用轉換後輸出的 css 文件。

假設你已經在電腦上安裝了 node.js 了,若是尚未,先去網上自行搜索下教程,不少,也很快。

首次使用須要先安裝 less,打開終端,執行下述命令:

npm install -g less

安裝完後,就可使用 lessc 命令,如:

lessc main.less main.css

這是最簡單的用法,將 main.less 文件編譯輸出 main.css;還有其餘高級的用法,好比順便壓縮 css 文件,輸出 .min.css 文件等等。

WebStorm配置

我是比較習慣使用第二種方式,也就是在本地就將 less 文件轉成 css 文件,項目裏是直接使用轉換後輸出的 css 文件了,並且我用的開發工具是 WebStrom,因此能夠藉助它,省去了每次本身輸命令的操做:

第一步:在項目根目錄下執行 npm init -y 初始化項目,初始化完項目後,根目錄會生成 package.json 文件;

第二步:打開 package.json,在裏面的 scripts 字段,根據你的項目結構,輸入腳本命令;

第三步:點擊 scripts 旁邊的三角形按鈕,就能夠自動執行腳本命令,完成轉換工做;

第四步:(可選)若是嫌每次都須要本身手動點擊按鈕麻煩,能夠將這項工做添加進 File Watcher 功能中,每次文件改動就會自動執行腳本命令,完成轉換,具體參考上一篇,或者自行搜索,很簡單。

這是例子的項目結構:

src 目錄中存放 less 文件,dist 目錄中存放轉換後輸出的 css 文件,因此,個人 package.json 裏的腳本命令以下:

具體的腳本命令可根據實際需求,實際項目結構,自行決定。

語法

好了,清楚了 less 文件的兩種使用方式後,就能夠來學習語法了,這樣在學習語法過程當中,就能夠隨時進行轉換,查看 less 書寫的代碼,最終轉換的 css 代碼是什麼樣的,這樣比較着學習比較容易掌握。

  • 變量

經過 @變量名: 來定義變量,經過 @變量名 使用變量,其實本質上是常量了,如:

@width: 10px;  /*定義變量*/
@height: @width + 10px; /*使用變量,和邏輯語句*/

#header {
  width: @width;  /*使用變量*/
  height: @height;
}

轉換成 CSS 文件:

/*定義變量*/
/*使用變量,和邏輯語句*/
#header {
  width: 10px;
  /*使用變量*/
  height: 20px;
}
  • 註釋

上個例子中,轉換後的註釋也還保留着,這是由於 less 和 css 都支持 /* */ 的註釋方式,因此這種會保留,但若是是 //,這種只有在 less 中支持,css 不支持,那麼這種註釋就不會保留,驗證下:

/*這是註釋1*/
//這是註釋2

轉換成 css 文件:

/*這是註釋1*/

因此,在 less 中使用註釋時,須要注意下,哪些是想保留,哪些是不想保留的。

  • Mixins(混合)

也有的文章裏翻譯成混入,還有的文章直接保留單詞,不作翻譯,多是以爲中文翻譯不可以很好的表達意思吧。

先說有這麼種場景:有時候寫在某個選擇器中的屬性樣式,在其餘選擇器中也須要,因此一般是直接將那部分複製粘貼過來使用。

而 less 的 Mixins 容許你在某個選擇器內,直接使用其餘選擇器內的屬性樣式,因此中文翻譯纔有混合,或混入之說,其實也就是將其餘的屬性樣式混合到當前選擇器中。

看個例子就明白了:

.class1 {   //類選擇器 class1 的屬性樣式
  width: 10px;
  height: 20px;
}

.class2(@color: #fff) {  //定義了一個模板樣式,相似於函數的做用
  background-color: @color;
}

#id1() {  //定義了一個模板樣式,相似於函數做用
  border: 1px solid #ff22ff;
}

.mian { 
  .class1; //直接使用其餘選擇器定義的屬性樣式
  .class2(#f2f); //使用模板樣式,傳入參數
  #id1; //使用模板樣式,不傳參時,括號可省略
}

轉換後的 CSS 文件:

.class1 {
  width: 10px;
  height: 20px;
}
.mian {
  width: 10px;
  height: 20px;
  background-color: #f2f;
  border: 1px solid #ff22ff;
}

能夠注意對比源代碼和轉換後的代碼,本來就定義好的基本選擇器,如 .class1,可直接在其餘選擇器內經過 .calss1 將它內部的屬性樣式都複製過來。

也能夠在基本選擇器後面加上 () 括號,這樣一來,這個就會被當作模板處理,做用相似於函數,可接收參數,使用時就相似於調用函數那麼使用,若是不傳參,調用時也能夠將括號省略。既然是做爲函數使用,那麼它們存在的意義就只是被調用,因此轉換後的 CSS 中並不會存在這個函數。

另外,有的文章中,對 Mixins 的解釋是說,在 class 中使用 class,但上面的例子中也測試了,class 中也是可使用其餘 id 選擇器的屬性樣式的,因此應該不只限於 class 類選擇器,但不能用於組合選擇器中。

  • 命名空間

我對於命名空間的理解:屬於 less 本身的命名空間,也就是這些代碼並不會在轉換後的 CSS 文件中出現,由於它只屬於 less。

因此,其實也就是上述例子中,相似函數存在的那些模板選擇器,當在書寫選擇器時,在其後面增長 () 括號,則表示這個選擇器只屬於 less 的命名空間,轉成 CSS 後並不會出現。k

  • 嵌套

在寫 CSS 時,組合選擇器常常寫得很複雜,由於 HTML 裏的標籤嵌套層次自己就很複雜,並且組合選擇器寫完也不是可以很明顯的表示出它的目的,因此 less 容許依據 HTML 中的嵌套層次來書寫,不用去記那麼多組合選擇器的規則,如:

body {
  font-size: 16px;
  .content {
    .banner {
      ul {
        img {
          width: 700px;
          height: 300px;
          &:hover {
            width: 800px;
            height: 300px;
          }
        }
      }
    }
  }
}

轉換成 CSS 文件:

body {
  font-size: 16px;
}
body .content .banner ul img {
  width: 700px;
  height: 300px;
}
body .content .banner ul img:hover {
  width: 800px;
  height: 300px;
}

也就是,子孫後代的組合選擇器規則能夠不用去記,直接根據 HTML 文檔中標籤的嵌套層次來書寫便可,這樣便於後期維護,若是要對某個標籤新增某些樣式,也知道該去哪裏找。

有一點須要注意的是,相似 a:hover 這種僞類選擇器,須要加一個 & 符號。

  • 運算

less 容許在代碼中進行一些簡單的加、減、乘、除基本運算,結合變量的使用,可進行一些字體、顏色等的動態運算效果。

@border: 1px;
@color: #fff;
#header {
  color: @color * 0.5;
  border-width: @border @border*2 @border*3 @border*4;
}

轉換成 CSS 後:

#header {
  color: #808080;
  border-width: 1px 2px 3px 4px;
}

一般,變量和運算都是用於對顏色、大小等進行計算。

  • 內置函數

less 內置了一些基礎函數,可用於轉換顏色、處理字符串、算術運算等,這裏列舉一些函數:

color("#aaa");  //輸出 #aaa, 將字符串的顏色值轉換爲顏色值
image-size("file.png");  //輸出 => 10px 10px,獲取圖片文件的寬高信息
//image-with("file.png"); image-height("file.png"); 獲取圖片文件寬高
convert(9s, "ms");  //輸出 => 9000ms,單位換算,例如對 m,cm,mmin,pt,pc的換算
@size: if((true), 1px, 0px);  //if函數,第一個參數爲條件,知足則返回第二個參數,不知足返回第三個參數
if(not (true), 1px, 0px);     //非語句, not
if((true) and (true), 1px, 0px); //邏輯與語句, and 
if((false) or (true), 1px, 0px); //邏輯或語句, or 

//處理數組
@list: "banana", "tomato", "potato", "peach";
length(@list);  // 輸出 => 4
extract(@list, 3);  //輸出 => potato,注意第一個不是從 0 開始計算

//類型判斷
isnumber(#ff0);  // false
isstring("234"); // true
iscolor(#ff0);   // true
isXXX

...

內置函數不少,用途也不少,覆蓋了基本算術運算、邏輯語句、顏色計算、字符串處理等等,須要用時再查手冊吧。

  • 做用域

做用域很好理解,就是相似 JavaScript 中的變量做用域,由於在 less 中都是經過 @變量名: 來定義變量的,後定義的會覆蓋掉前定義的,但當在不一樣嵌套層次中定義同一變量時,就存在局部變量和外部變量之分,內部變量並不會覆蓋掉外部變量。

並且,less 的變量定義也有相似 JavaScript 中的提早特性,如:

@var: red;

#aaa {
  color: @var;  // yellow,由於後面定義的 @var:yellow 將 @var:red 覆蓋掉了
}

#page {
  #header {
    color: @var; // white,內部變量不影響外部變量
  }
  @var: white;
}

@var: yellow;

#ppp {
  color: @var;  //yellow
}

看看轉換成 CSS 後:

#aaa {
  color: yellow;
}
#page #header {
  color: white;
}
#ppp {
  color: yellow;
}
  • import(導入)

若是某份 less 文件是能夠複用的,那麼可使用 @import 命令將其所有引入使用。

@import "main";

最後在 test.css 裏會匯合 main.less 裏的代碼。

以上,只是介紹 less 的基礎語法,還有更多詳細、複雜的語法用途,須要時再翻閱文檔吧。

Sass(Scss)

Sass 相比於 Less 功能會更強大,但也更復雜。

Sass 和 Scss 本質是一家,Sass 早期版本的文件後綴名是 .sass,從 Sass 3 以後,由於修改了一些特性語法,Sass 更增強大且易使用,從這個版本以後的文件後綴名改爲了 .scss,因此 Scss 其實 Sass 的新版本的稱呼,但二者本質上沒太大區別。

Scss 是基於 Sass 的語法基礎上,修改了一部分的語法。好比早期的 Sass 是經過換行和縮進如:

#sidebar
  width: 30%
  background-color: #faa

這種語法格式跟 CSS 不一致,讓使用者會很不習慣,Scss 以後就換成用分號和括號了:

#sidebar {
  width: 30%;
  background-color: #faa;
}

使用

Sass 不像 Less 同樣能夠直接藉助 less.js 來進行轉換,它是基於 Ruby 運行環境,因此電腦上須要先安裝 Ruby,而後纔能有辦法將 Sass 文件轉成 CSS。

Ruby 下載地址:https://rubyinstaller.org/downloads/

由於是 exe 文件,下載完直接按提示安裝就能夠了,安裝後打開終端,執行 gem 命名安裝 Sass:

gem install sass

安裝完 Sass 後,就能夠經過 scss 命令來進行轉換工做了,如:

scss main.scss main.css

上述命令中,scss 換成 sass 也能夠,但注意,scss 或 sass 命令是基於 Ruby 環境下運行的命令,由於電腦上已經安裝過 Ruby 了,也經過 Ruby 安裝了 Sass,因此才能夠在終端裏直接執行 scss 命令。

而相似於 Less 中說到的,WebStrom 能夠藉助 package.json 裏的 scripts 來手動運行腳本命令,這有個前提,就這些腳本命令是運行在 node.js 環境上的,因此若是你直接將上述 scss 命令配置到 package.json 的 script 裏,你會發現,是運行不了的。

要解決這個問題,讓 WebStrom 可以運行 sass 命令來處理轉換工做有兩種方式:

  • 直接去 WebStrom 配置 File Watcher,program 選擇 Ruby 目錄中的 sass.bat 或 scss.bat

這種方式下,每次配置的文件變更時,會自動生成對應的 css 文件,轉換工做會自動實時進行。但若是不習慣這種方式,想要每次編寫完 scss 代碼後,手動來觸發轉換工做,那麼能夠選擇第二種方式:

  • 經過 npm 命令安裝 sass

在終端裏執行 npm install -g sass,這樣就能夠相似配置 less 那樣的步驟來使用 sass 命令了,在 package.json 裏配置相關命令,而後手動點擊腳本的運行便可。

但 npm 安裝的 sass 跟在 Ruby 下安裝的 sass 是否有和區別,我不清楚,用段時間,若是有啥問題再來講說。

並且,對於選擇使用 Sass,剛接觸可能會有些困惑,是應該使用哪一個後綴名的文件,命令是該用 sass 仍是 scss 來進行轉換,我也有這個困惑,但感受好像並無什麼區別,先試着用段時間,之後熟悉了再來說講。

最後,Sass 雖然有 .sass.scss 兩種後綴名的文件,但建議使用 .scss,由於前者的語法跟 CSS 很不同,使用起來會有些不習慣,固然若是你有 Ruby 基礎的話,可能會比較喜歡這種。我我的會選擇後者。

語法

語法方面,大部分相似於 Less,但就細節方面可能有些不同,還有,支持更多更強大的功能吧。

上面介紹的 Less 的基礎語法、基礎功能,Sass 也基本所有支持,也差不了多少,因此下面就不一個個來介紹了,詳細的到開頭聲明部分給的中文網連接中去查閱便可。

下面就主要列一些不一樣的地方:

  • 變量

Sass 中的變量用 $變量名: 定義,用 $變量名 使用,其他跟 Less 差不了多少。

  • 做用域

Less 中的變量分局部做用域和全局做用域,但在 Sass 中,不一樣版本,做用域範圍並不同,摘抄一段原文中描述:

Sass 中變量的做用域在過去幾年已經發生了一些改變。直到最近,規則集和其餘範圍內聲明變量的做用域才默認爲本地。若是已經存在同名的全局變量,則局部變量覆蓋全局變量。從 Sass 3.4 版本開始,Sass 已經能夠正確處理做用域的概念,並經過建立一個新的局部變量來代替。

  • 條件語句

Less 中並不支持條件語句,固然,能夠經過內置函數 if 以及 and,or,not 這些來模擬條件語句。

在 Sass 中是支持條件語句的,但也不是像其餘編程語言直接 if 這樣經過保留字來編寫,須要加個 @ 符合,如:

@if $support-legacy {
  // …
} @else {
  // …
}

教程中給了幾條準則要求:

  • 除非必要,否則不須要括號;
  • 務必在 @if 以前添加空行;
  • 務必在左開大括號({)後換行;
  • @else 語句和它前面的右閉大括號(})寫在同一行;
  • 務必在右閉大括號(})後添加空行,除非下一行仍是右閉大括號(}),那麼就在最後一個右閉大括號(})後添加空行。

另外,教程中也說了:

除非你的代碼中有偏複雜的邏輯,不然不必在平常開發的樣式表中使用條件語句。實際上,條件語句主要適用於庫和框架。

其餘區別,等用段時間,熟悉了再來說講。

框架-Compass

Sass 有一點比 Less 有優點的就是,目前有不少穩定且熱門的基於 Sass 編寫的框架庫,好比:CompassBourbon 和 Susy 等。

這些框架庫就相似於 jQurey 和 JavaScript 關係,對 Sass 進行了一層封裝,讓編寫 Sass 代碼的人,能夠極爲簡便的開發,我還沒用過,就不過多介紹了。


你們好,我是 dasu,歡迎關注個人公衆號(dasuAndroidTv),公衆號中有個人聯繫方式,歡迎有事沒事來嘮嗑一下,若是你以爲本篇內容有幫助到你,能夠轉載但記得要關注,要標明原文哦,謝謝支持~
dasuAndroidTv2.png

相關文章
相關標籤/搜索