?
LESS 是一個流行的樣式表語言,它提供了 CSS3 也未曾實現的多種功能,讓您編寫 CSS 更加方便,更加直觀。LESS 已經被廣泛使用在多種框架中 ( 例如:BootStrap)。本文將介紹 LESS 產生的背景、優勢、演化與 CSS 之間的轉化,及其典型的應用場景,并將其與其他樣式表語言進行比較。相信前端開發工程師會喜歡 LESS,靈活運用 LESS 以提高開發效率。
?
LESS 背景介紹
LESS 提供了多種方式能平滑的將寫好的代碼轉化成標準 CSS 代碼,在很多流行的框架和工具盒中已經能經常看到 LESS 的身影了(例如 Twitter 提供的 bootstrap 庫就使用了 LESS)。那么,LESS 是從何而來呢?它和 SASS 等樣式表語言又有何區別呢?
?
圖 1.LESS 的官網介紹
根 據維基百科上的介紹,其實 LESS 是 Alexis Sellier 受 SASS 的影響創建的開源項目。當時 SASS 采用了縮進作為分隔符來區分代碼塊,而不是 CSS 中廣為使用的括號。為了讓 CSS 現有用戶使用起來更為方便,Alexis 開發了 LESS 并提供了類似的功能。在一開始,LESS 的解釋器也同樣是由 Ruby 編寫,后來才轉而采用了 JavaScript. LESS 代碼既可以運行在客戶端,也可以運行在服務器端。在客戶端只要把 LESS 代碼和相應的 JavaScript 解釋器在同一頁面引用即可;而在服務器端,LESS 可以運行在 Node.js 上,也可以運行在 Rhino 這樣的 JavaScript 引擎上。
?
說一點題外話,其實現在的 SASS 已經有了兩套語法規則:一個依舊是用縮進作為分隔符來區分代碼塊的;另一套規則和 CSS 一樣采用了大括弧作為風格符。后一種語法規則又名 SCSS,在 SASS 3 之后的版本都支持這種語法規則。SCSS 和 LESS 已經越來越像了,它倆之間更詳細的對比可以參考 此鏈接 。
?
LESS 高級特性
我 們知道 LESS 擁有四大特性:變量、混入、嵌套、函數。這些特性在其他文章中已經有所介紹,這里就不復述了。其實,LESS 還擁有一些很有趣的特性有助于我們的開發,例如模式匹配、條件表達式、命名空間和作用域,以及 JavaScript 賦值等等。讓我們來逐一看看這些特性吧。
?
模式匹配:
相信大家對 LESS 四大特性中的混入 (mixin) 依然印象深刻吧,您用它能夠定義一堆屬性,然后輕松的在多個樣式集中重用。甚至在定義混入時加入參數使得這些屬性根據調用的參數不同而生成不同的屬性。那 么,讓我們更進一步,來了解一下 LESS 對混入的更高級支持:模式匹配和條件表達式。
首先,讓我們來回顧一下普通的帶參數的混入方式:
?
清單 1. 帶參數(及參數缺省值)的混入
?
.border-radius (@radius: 3px) {
border-radius: @radius;
-moz-border-radius: @radius;
-webkit-border-radius: @radius;
}
.button {
.border-radius(6px);
}
.button2 {
.border-radius();
}
?
?
清單 2. 混入生成的 CSS 代碼
?
.button {
border-radius: 6px;
-moz-border-radius: 6px;
-webkit-border-radius: 6px;
}
.button2 {
border-radius: 3px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
}
?
?
從上面這個例子可以看出,在混入我們可以定義參數,同時也可以為這個參數指定一個缺省值。這樣我們在調用這個混入時如果指定了參數
.border-radius(6px)
,LESS 就會用
6px
來替換,如果不指定參數來調用
.border-radius()
,LESS 就會用缺省的
3px
來替換。現在,我們更近一步,不僅僅通過參數值來更改最終結果,而是通過傳入不同的參數個數來匹配不同的混入。
?
清單 3. 利用不同的參數個數來匹配不同的混入
?
.mixin (@a) {
color: @a;
width: 10px;
}
.mixin (@a, @b) {
color: fade(@a, @b);
}
.header{
.mixin(red);
}
.footer{
.mixin(blue, 50%);
}
?
?
清單 4. 不同參數個數調用后生成的 CSS 代碼
?
.header {
color: #ff0000;
width: 10px;
}
.footer {
color: rgba(0, 0, 255, 0.5);
}
?
?
這個例子有些像 Java 語言中的方法調用有些類似,LESS 可以根據調用參數的個數來選擇正確的混入來帶入。現在,我們了解到通過傳入參數的值,以及傳入不同的參數個數能夠選擇不同的混入及改變它的最終代碼。這兩 個例子的模式匹配都是非常容易理解的,讓我們換個思路,上面的例子中參數都是由變量構成的,其實在 LESS 中定義參數是可以用常量的!模式匹配時匹配的方式也會發生相應的變化,讓我們看個實例。
?
清單 5. 用常量參數來控制混入的模式匹配
?
.mixin (dark, @color) {
color: darken(@color, 10%);
}
.mixin (light, @color) {
color: lighten(@color, 10%);
}
.mixin (@zzz, @color) {
display: block;
weight: @zzz;
}
.header{
.mixin(dark, red);
}
.footer{
.mixin(light, blue);
}
.body{
.mixin(none, blue);
}
?
?
清單 6. 常量參數生成的 CSS 代碼
?
.header {
color: #cc0000;
display: block;
weight: dark;
}
.footer {
color: #3333ff;
display: block;
weight: light;
}
.body {
display: block;
weight: none;
}
?
?
通過這個例子我們可以看出,當我們定義的是變量參數時,因為 LESS 中對變量并沒有類型的概念,所以它只會根據參數的個數來選擇相應的混入來替換。而定義常量參數就不同了,這時候不僅參數的個數要對應的上,而且常量參數的 值和調用時的值也要一樣才會匹配的上。值得注意的是我們在 body 中的調用,它調用時指定的第一個參數 none 并不能匹配上前兩個混入,而第三個混入
.mixin (@zzz, @color)
就不同了,由于它的兩個參數都是變量,所以它接受任何值,因此它對三個調用都能匹配成功,因此我們在最終的 CSS 代碼中看到每次調用的結果中都包含了第三個混入的屬性。
?
最后,我們把清單 1 中的代碼做略微改動,增加一個無參的混入和一個常量參數的混入,您猜猜看最終的匹配結果會發生什么變化么?
?
清單 7. 無參和常量參數的模式匹配
?
.border-radius (@radius: 3px) {
border-radius: @radius;
-moz-border-radius: @radius;
-webkit-border-radius: @radius;
}
.border-radius (7px) {
border-radius: 7px;
-moz-border-radius: 7px;
}
.border-radius () {
border-radius: 4px;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
}
.button {
.border-radius(6px);
}
.button2 {
.border-radius(7px);
}
.button3{
.border-radius();
}
?
?
下面的結果可能會出乎您的意料,無參的混入是能夠匹配任何調用,而常量參數非常嚴格,必須保證參數的值
(7px)
和調用的值
(7px)
一致才會匹配。
?
清單 8. 加入了無參混入后生成的 CSS 代碼
?
.button {
border-radius: 6px;
-moz-border-radius: 6px;
-webkit-border-radius: 6px;
border-radius: 4px;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
}
.button2 {
border-radius: 7px;
-moz-border-radius: 7px;
-webkit-border-radius: 7px;
border-radius: 7px;
-moz-border-radius: 7px;
border-radius: 4px;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
}
.button3 {
border-radius: 3px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
border-radius: 4px;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
}
?
?
條件表達式
有了模式匹配之后是方便了很多,我們能根據不同的需求來匹配不同的混入,但更進一步的就是利用條件表達式來更加準確,更加嚴格的來限制混入的匹配,實現的方式就是利用了
when
這個關鍵詞。
?
清單 9. 利用條件表達式來控制模式匹配
?
.mixin (@a) when (@a >= 10) {
background-color: black;
}
.mixin (@a) when (@a < 10) {
background-color: white;
}
.class1 { .mixin(12) }
.class2 { .mixin(6) }
?
?
清單 10. 條件表達式生成的 CSS 代碼
?
.class1 {
background-color: black;
}
.class2 {
background-color: white;
}
?
?
利用 When 以及 <, >, =, <=, >= 是十分簡單和方便的。LESS 并沒有停留在這里,而且提供了很多類型檢查函數來輔助條件表達式,例如
iscolor
、
isnumber
、
isstring
、
iskeyword
、
isurl
等等。
?
清單 11. 條件表達式中支持的類型檢查函數
?
.mixin (@a) when (iscolor(@a)) {
background-color: black;
}
.mixin (@a) when (isnumber(@a)) {
background-color: white;
}
.class1 { .mixin(red) }
.class2 { .mixin(6) }
?
?
清單 12. 類型檢查匹配后生成的 CSS 代碼
?
.class1 {
background-color: black;
}
.class2 {
background-color: white;
}
?
?
另外,LESS 的條件表達式同樣支持 AND 和 OR 以及 NOT 來組合條件表達式,這樣可以組織成更為強大的條件表達式。需要特別指出的一點是,OR 在 LESS 中并不是用 or 關鍵字,而是用 , 來表示 or 的邏輯關系。
?
清單 13. AND,OR,NOT 條件表達式
?
.smaller (@a, @b) when (@a > @b) {
background-color: black;
}
.math (@a) when (@a > 10) and (@a < 20) {
background-color: red;
}
.math (@a) when (@a < 10),(@a > 20) {
background-color: blue;
}
.math (@a) when not (@a = 10) {
background-color: yellow;
}
.math (@a) when (@a = 10) {
background-color: green;
}
.testSmall {.smaller(30, 10) }
.testMath1 {.math(15)}
.testMath2 {.math(7)}
.testMath3 {.math(10)}
?
?
清單 14. AND,OR,NOT 條件表達式生成的 CSS 代碼
?
.testSmall {
background-color: black;
}
.testMath1 {
background-color: red;
background-color: yellow;
}
.testMath2 {
background-color: blue;
background-color: yellow;
}
.testMath3 {
background-color: green;
}
?
?
命名空間和作用域
LESS 所帶來的變量,混入這些特性其實很大程度上避免了傳統 CSS 中的大量代碼重復。變量能夠避免一個屬性多次重復,混入能夠避免屬性集的重復。而且使用起來更加靈活,維護起來也方便了許多,只要修改一處定義而無需修改 多處引用的地方。現在,讓我們更進一步,當我定義好了變量和混入之后,怎么能更好的控制和運用它們呢,怎么避免和其他地方定義的變量及混入沖突?一個顯而 易見的想法就是像其他語言一樣引入命名空間和作用域了。首先我們來看一個 LESS 的作用域的例子。
?
清單 15. 變量的作用域
?
@var: red;
#page {
@var: white;
#header {
color: @var;
}
}
#footer {
color: @var;
}
?
?
在這個例子里,可以看到 header 中的
@var
會首先在當前作用域尋找,然后再逐層往父作用域中尋找,一直到頂層的全局作用域中為止。所以 header 的
@var
在父作用域中找到之后就停止了尋找,最終的值為 white。而 footer 中的
@var
在當前作用域沒找到定義之后就尋找到了全局作用域,最終的結果就是全局作用域中的定義值 red。
?
清單 16. 變量作用域例子生成的 CSS 代碼
?
#page #header {
color: #ffffff; // white
}
#footer {
color: #ff0000; // red
}
?
?
了解了作用域之后讓我們再來看一下命名空間,我們可以用命名空間把變量和混入封裝起來,避免和其他地方的定義沖突,引用起來也十分方便,只要在前面加上相應的命名空間就可以了。
?
清單 17. 命名空間的例子
@var-color: white;
#bundle {
@var-color: black;
.button () {
display: block;
border: 1px solid black;
background-color: @var-color;
}
.tab() { color: red }
.citation() { color: black}
.oops {weight: 10px}
}
#header {
color: @var-color;
#bundle > .button;
#bundle > .oops;
}
?
這里可以看出,我們利用嵌套規則在
#bundle
中建立了一個命名空間,在里面封裝的變量以及屬性集合都不會暴露到外部空間中,例如
.tab(), .citation()
都沒有暴露在最終的 CSS 代碼中。而值得注意的一點是 .oops 卻被暴露在了最終的 CSS 代碼中,這種結果可能并不是我們想要的。其實同樣的例子我們可以在混入的例子中也可以發現,即無參的混入
.tab()
是和普通的屬性集
.oops
不同的。無參的混入是不會暴露在最終的 CSS 代碼中,而普通的屬性集則會現在出來。我們在定義命名空間和混入時要小心處理這樣的差別,避免帶來潛在的問題。
?
清單 18. 命名空間例子生成的 CSS 代碼
#bundle .oops {
weight: 10px;
}
#header {
color: #ffffff;
display: block;
border: 1px solid black;
background-color: #000000;
weight: 10px;
}
?
JavaScript 賦值 (JavaScript Evaluation)
如 果能在 CSS 中使用一些 JavaScript 方法無疑是十分令人興奮的,而 LESS 真正逐步加入這項功能,目前已經能使用字符串及數字的常用函數了,想要在 LESS 中運用 JavaScript 賦值只需要用反引號(`)來包含所要進行的操作即可。讓我們看看實例吧。
?
清單 19. JavaScript 賦值的例子
.eval {
js: `1 + 1`;
js: `(1 + 1 == 2 ? true : false)`;
js: `"hello".toUpperCase() + '!'`;
title: `process.title`;
}
.scope {
@foo: 42;
var: `this.foo.toJS()`;
}
.escape-interpol {
@world: "world";
width: ~`"hello" + " " + @{world}`;
}
.arrays {
@ary: 1, 2, 3;
@ary2: 1 2 3;
ary: `@{ary}.join(', ')`;
ary: `@{ary2}.join(', ')`;
}
?
我們可以看到,在 eval 中我們可以用 JavaScript 做數字運算,布爾表達式;對字符串做大小寫轉化,串聯字符串等操作。甚至最后能夠獲取到 JavaScript 的運行環境(
process.title
)。同樣可以看到 LESS 的作用域和變量也同樣在 JavaScript 賦值中使用。而最后的例子中,我們看到 JavaScript 賦值同樣運用于數組操作當中。其實 LESS 的 JavaScript 賦值還有支持其他一些方式,不過目前尚未公布出來。
?
清單 20. JavaScript 賦值生成的 CSS 代碼
.eval {
js: 2;
js: true;
js: "HELLO!";
title: "/Users/Admin/Downloads/LESS/Less.app/Contents/Resources/engines/bin/node";
}
.scope {
var: 42;
}
.escape-interpol {
width: hello world;
}
.arrays {
ary: "1, 2, 3";
ary: "1, 2, 3";
}
?
LESS 開發的實用工具 – LESS.app
在 LESS 開發中,我們可以用 LESS 提供的 JavaScript 腳本來在運行時解析,將 LESS 文件實時翻譯成對應的 CSS 語法。如下面這個例子:
?
清單 21. helloworld.html
<link rel="stylesheet/less" type="text/css" href="helloworld.less">
<script src="less.js" type="text/javascript"></script>
<div class="helloworld">Hello World!</div>
?
從上 面的示例可以看出,在 helloworld.less 引入之后我們還添加了一個 JavaScript 文件,這個文件就是 LESS 的解釋器,可以在 LESS 的官方網站上下載此文件。需要注意的是,要注意 LESS 文件和 LESS 解釋器的引入順序,確保所有的 LESS 文件都在 LESS 解釋器之前。
?
看到這里也許有人會說,實時解析的話方便倒是方便,可以性能上不就有損耗了么?比起普通 CSS 來說多了一道解釋的手續。也許還有的人對寫好的 LESS 文件不太放心,希望能看到解析之后的 CSS 文件來檢查下是否是自己希望的內容。這兩個問題其實都是能夠解決的,LESS 提供了服務端的方案,使用 npm 安裝 LESS 之后就能夠將您所有的 LESS 文件批量轉化成 CSS 文件,然后您拿到 CSS 文件就可以隨心所欲了,檢查生成的內容是否有誤,也可以直接在 HTML 中引用,再也不用添加 LESS 的 JavaScript 文件來解析它了。關于這部分的詳細安裝信息,可以直接參考 LESS 官網上的介紹,這里就不復述了。
?
不過,對于 Mac 用戶來說還有一個更方便的工具可以使用,它就是 less.app. 這是一個第三方提供的工具,使用起來十分方便,我們可以在下圖所示的界面上添加 LESS 文件所在的目錄,此工具就會在右側列出目錄中包含的所有 LESS 文件。最酷的是,從此您就不用再操心惦記著要把 LESS 文件編譯成 CSS 文件了,這個工具會在您每次修改完保存 LESS 文件時自己執行編譯,自動生成 CSS 文件。這樣,您就可以隨時查看 LESS 代碼的最終效果,檢查目標 CSS 是否符合您的需要了,實在是太方便了!
?
圖 2. 導入 LESS 文件夾的界面,左側可添加存放在多個不同路徑的文件夾。
?
圖 3. 編譯結果界面,在此可手動批量編譯所有 LESS 文件。
更值為稱道的是,LESS.app 還是個免費軟件,接受捐贈:)
?
總結
通過上面的簡單介紹,希望大家了解到了 LESS 的主要功能,相信 LESS 會讓前端攻城師的工作更為輕松,更加靈活。更多的細節可以參考 LESS 官方網站。
?
參考資料
學習
- “ LESS CSS 框架簡介 ”(developerWorks,2012 年 7 月):LESS 是動態的樣式表語言,通過簡潔明了的語法定義,使編寫 CSS 的工作變得非常簡單。本文將通過實例,為大家介紹這一框架。
- LESS 官方網站 : 包括官方參考文檔庫,示例代碼等相關資料。
- 維基百科上的 LESS 條目 包括了 LESS 的歷史,功能介紹,與其他樣式語言的對比等資料。
- LESS.app 官方網站 LESS.app 的官方網站,提供了 LESS.app 的下載,視頻介紹,相關問題回答等資料。
- twitter 提供的 bootstrap 由 Twitter 共享出的 CSS 工具包,使開發者能夠輕松的創建出漂亮的界面。其中很多地方都使用了 LESS。
- SASS 官方網站 包含了 SASS 和 SCSS 的下載,幫助文檔,以及在線教程等資料。
- developerWorks Web development 專區 :通過專門關于 Web 技術的文章和教程,擴展您在網站開發方面的技能。
- developerWorks Ajax 資源中心 :這是有關 Ajax 編程模型信息的一站式中心,包括很多文檔、教程、論壇、blog、wiki 和新聞。任何 Ajax 的新信息都能在這里找到。
- developerWorks Web 2.0 資源中心 ,這是有關 Web 2.0 相關信息的一站式中心,包括大量 Web 2.0 技術文章、教程、下載和相關技術資源。您還可以通過 Web 2.0 新手入門 欄目,迅速了解 Web 2.0 的相關概念。
- 查看 HTML5 專題 ,了解更多和 HTML5 相關的知識和動向。
討論
- 加入 developerWorks 中文社區 。查看開發人員推動的博客、論壇、組和維基,并與其他 developerWorks 用戶交流。
?
原文: http://www.ibm.com/developerworks/cn/web/1207_shenyi_lesscss/
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

