本篇內容梳理自如下幾個來源:css
感謝大佬們的分享。html
什麼是 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 寫的 CSS 文件後綴名爲 .less
,但瀏覽器並不認識 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
第一種方式,雖然便捷,但會讓頁面的渲染多了一個轉換步驟,延長頁面渲染時長,因此,還能夠用第二種方式,直接在本地將 less 轉成 css 文件後,項目直接使用轉換後輸出的 css 文件。
假設你已經在電腦上安裝了 node.js 了,若是尚未,先去網上自行搜索下教程,不少,也很快。
首次使用須要先安裝 less,打開終端,執行下述命令:
npm install -g less
安裝完後,就可使用 lessc 命令,如:
lessc main.less main.css
這是最簡單的用法,將 main.less 文件編譯輸出 main.css;還有其餘高級的用法,好比順便壓縮 css 文件,輸出 .min.css 文件等等。
我是比較習慣使用第二種方式,也就是在本地就將 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 中使用註釋時,須要注意下,哪些是想保留,哪些是不想保留的。
也有的文章裏翻譯成混入,還有的文章直接保留單詞,不作翻譯,多是以爲中文翻譯不可以很好的表達意思吧。
先說有這麼種場景:有時候寫在某個選擇器中的屬性樣式,在其餘選擇器中也須要,因此一般是直接將那部分複製粘貼過來使用。
而 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; }
若是某份 less 文件是能夠複用的,那麼可使用 @import
命令將其所有引入使用。
@import "main";
最後在 test.css 裏會匯合 main.less 裏的代碼。
以上,只是介紹 less 的基礎語法,還有更多詳細、複雜的語法用途,須要時再翻閱文檔吧。
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 命令來處理轉換工做有兩種方式:
這種方式下,每次配置的文件變更時,會自動生成對應的 css 文件,轉換工做會自動實時進行。但若是不習慣這種方式,想要每次編寫完 scss 代碼後,手動來觸發轉換工做,那麼能夠選擇第二種方式:
在終端裏執行 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
語句和它前面的右閉大括號(}
)寫在同一行;}
)後添加空行,除非下一行仍是右閉大括號(}
),那麼就在最後一個右閉大括號(}
)後添加空行。另外,教程中也說了:
除非你的代碼中有偏複雜的邏輯,不然不必在平常開發的樣式表中使用條件語句。實際上,條件語句主要適用於庫和框架。
其餘區別,等用段時間,熟悉了再來說講。
Sass 有一點比 Less 有優點的就是,目前有不少穩定且熱門的基於 Sass 編寫的框架庫,好比:Compass、Bourbon 和 Susy 等。
這些框架庫就相似於 jQurey 和 JavaScript 關係,對 Sass 進行了一層封裝,讓編寫 Sass 代碼的人,能夠極爲簡便的開發,我還沒用過,就不過多介紹了。
你們好,我是 dasu,歡迎關注個人公衆號(dasuAndroidTv),公衆號中有個人聯繫方式,歡迎有事沒事來嘮嗑一下,若是你以爲本篇內容有幫助到你,能夠轉載但記得要關注,要標明原文哦,謝謝支持~