背景
??CSS自誕生以來,其基本語法和核心機制一直沒有本質(zhì)上的變化,它的發(fā)展幾乎是表現(xiàn)力層面上的提升。最開始 CSS 在網(wǎng)頁中的作用只是輔助式性的裝飾,輕便易學就是最大的需求。這也決定了 CSS 它只是一種敘述語言,而不是編程語言(編程語言具有邏輯,變量,條件語句)。但是隨著互聯(lián)網(wǎng)的發(fā)展,網(wǎng)站的復(fù)雜度已經(jīng)不可同日而語,原生 CSS 已經(jīng)讓開發(fā)者越加吃力。
??當一門語言的能力不足而用戶的環(huán)境又不支持其它選擇的時候,這門語言就會淪為“編譯目標”語言。開發(fā)者將選擇另一名更高級的語言來進行開發(fā),然后編譯到底層語言進行實際運行。
??于是,在前端領(lǐng)域,CSS 預(yù)處理器就應(yīng)用而生,而 CSS 這門古老的語言以另一種方式 “重新適應(yīng)” 了網(wǎng)頁開發(fā)的需求。它的基本思想是,用一種專門的編程語言,進行網(wǎng)頁樣式設(shè)計,然后再編譯成正常的CSS文件。根本目的,是提高寫網(wǎng)頁樣式的效率。目前主要的CSS預(yù)處理器有兩種:SASS與Less。
Sass與Scss是什么關(guān)系?
Sass的縮排語法,對于寫慣css前端的web開發(fā)者來說很不直觀,也不能將css代碼加入到Sass里面,因此sass語法進行了改良,Sass 3就變成了Scss(sassy css)。與原來的語法兼容,只是用{}取代了原來的縮進。
Less也是一種動態(tài)樣式語言. 對CSS賦予了動態(tài)語言的特性,如變量,繼承,運算, 函數(shù). Less 既可以在客戶端上運行 (支持IE 6+, Webkit, Firefox),也可在服務(wù)端運行 (借助 Node.js)。
如何使用Less?
??最基本的方式就是在頁面中引入less.js文件,就像一般使用jQuery庫一樣,具體步驟可以去Less官網(wǎng)查閱。另一種更加方便的方法就是安裝IDE插件,例如在使用Sublime的時候,安裝一個less插件,就可以直接在代碼中使用Less,編譯器自動給你轉(zhuǎn)為對應(yīng)的css代碼。
Less的功能特性
我們使用Less是為了增加網(wǎng)頁開發(fā)的效率,以下為Less中的功能特性:
-
文件切分
?當頁面越來越復(fù)雜的時候,需要加載的css文件也越來越大,我們有必要將大文件拆分開來,否則難以維護。傳統(tǒng)的css切分方案基本上是 CSS 原生的@import指令,或在 HTML 上加載多個 css 文件,這些方案通通不能滿足性能要求。
?CSS 預(yù)處理器擴展了@import指令的能力,通過編譯環(huán)節(jié)將切分后的文件重新合并為一個大文件。這一方面解決了大文件不便維護的問題,另一方面也解決了一堆小文件在加載時的性能問題。- 導(dǎo)入less文件可省略后綴
@import "main"; // 等價于 @import "main.less"- reference
Less 中 最強大的特性,使用 引入的 Less 文件,但不會編譯它。
/*Less*/ @import (reference) "bootstrap.less"; #wrap:extend(.navbar all){}翻譯官網(wǎng):
使用@import (reference)導(dǎo)入外部文件,但不會添加 把導(dǎo)入的文件 編譯到最終輸出中,只引用。- once(待補充)
- multiple(待補充)
-
模塊化
??把文件切分的思路再向前推進一步,就是 “模塊化”。一個大的 CSS 文件在合理切分之后,所產(chǎn)生的這些小文件的相互關(guān)系應(yīng)該是一個樹形結(jié)構(gòu)。樹形的根結(jié)節(jié)一般稱作 “入口文件”,樹形的其它節(jié)點一般稱作 “模塊文件”。入口文件通常會依賴多個模塊文件,各個模塊文件也可能會依賴其它更末端的模塊,從而構(gòu)成整個樹形。
??以下是一個簡單的示例:
模塊化樹形結(jié)構(gòu)
入口文件entry.styl在編譯時會引入所需的模塊,生成entry.css,然后被頁面引用。)
如果你用過其它擁有模塊機制的編程語言,應(yīng)該已經(jīng)深有體會,模塊化是一種非常好的代碼組織方式,是開發(fā)者設(shè)計代碼結(jié)構(gòu)的重要手段。模塊可以很清晰地實現(xiàn)代碼的分層、復(fù)用和依賴管理,讓 CSS 的開發(fā)過程也能享受到現(xiàn)代程序開發(fā)的便利。 選擇符嵌套
??選擇符嵌套是文件內(nèi)部的代碼組織方式,它可以讓一系列相關(guān)的規(guī)則呈現(xiàn)出層級關(guān)系。在以前,如果要達到這個目的,我們只能這樣寫:
.nav {margin: auto /* 水平居中 */; width: 1000px; color: #333;}
.nav li {float: left /* 水平排列 */; width: 100px;}
.nav li a {display: block; text-decoration: none;}
這種寫法需要我們手工維護縮進關(guān)系,當上級選擇符發(fā)生變化時,所有相關(guān)的下級選擇符都要修改;此外,把每條規(guī)則寫成一行也不易閱讀,為單條聲明寫注釋也很尷尬(只能插在聲明之間了)。
在 CSS 預(yù)處理語言中,嵌套語法可以很容易地表達出規(guī)則之間的層級關(guān)系,為單條聲明寫注釋也很清晰易讀:
.nav {
margin: auto; // 水平居中
width: 1000px;
color: #333;
li {
float: left; // 水平排列
width: 100px;
a {
display: block;
text-decoration: none;
}
}
}
- & 的妙用
& :代表的上一層選擇器的名字 - 媒體查詢(待補充)
-
變量
??在變更出現(xiàn)之前,CSS 中的所有屬性值都是 “幻數(shù)”。你不知道這個值是怎么來的、它的什么樣的意義。有了變量之后,我們就可以給這些 “幻數(shù)” 起個名字了,便于記憶、閱讀和理解。接下來我們會發(fā)現(xiàn),當某個特定的值在多處用到時,變量就是一種簡單而有效的抽象方式,可以把這種重復(fù)消滅掉。讓開發(fā)者更容易實現(xiàn)網(wǎng)站視覺風格的統(tǒng)一,也讓 “換膚” 這樣的需求變得更加輕松易行。- 值變量
/*Less*/ @color: #999; @bgColor: skyblue; // 不要添加引號 @width: 50%; #wrap { color: @color; width: @width; } /*生成后的css*/ #wrap { color: #999; width: 50%; }以
@開頭定義變量,并且使用時直接鍵入@名稱。在平時工作中,我們就可以把常用的變量保存到一個
文件中,這樣利于代碼的組織維護。- 選擇器變量(待補充)
- 屬性變量(待補充)
- url變量(待補充)
- 聲明變量
結(jié)構(gòu): @name: { 屬性: 值 ;};
使用:@name();/*Less*/ @background: {background: red;}; #main { @background(); }; @Rules: { width: 200px; hieght: 200px; border: 1px solid red; }; #con { @Rules(); } /*生成的css*/ #main { background: red; }; # con { width: 200px; height: 200px; border: 1px solid red; }- 變量運算
加減法時 以第一個數(shù)據(jù)的單位為基準
乘除法時 注意單位一定要統(tǒng)一/* Less */ @width:300px; @color:#222; #wrap{ width:@width-20; height:@width-20*5; margin:(@width-20)*5; color:@color*2; background-color:@color + #111; } /* 生成的 CSS */ #wrap{ width:280px; height:200px; margin:1400px; color:#444; background-color:#333; }- 變量作用域
就近原則
混合方法
方法猶如 聲明的集合,使用時 直接鍵入名稱即可。
/* Less */
.card { // 等價于 .card()
background: #f6f6f6;
-webkit-box-shadow: 0 1px 2px rgba(151, 151, 151, .58);
box-shadow: 0 1px 2px rgba(151, 151, 151, .58);
}
#wrap{
.card;//等價于.card();
}
/* 生成的 CSS */
#wrap{
background: #f6f6f6;
-webkit-box-shadow: 0 1px 2px rgba(151, 151, 151, .58);
box-shadow: 0 1px 2px rgba(151, 151, 151, .58);
}
其中 .card與.card()是等價的,為了表達更加清楚,我選擇使用.card()。
要點:
. 與 # 皆可作為 方法前綴。
方法后寫不寫 () 看個人習慣。
