CSS預處理工具Stylus


CSS(層疊樣式表,Cascading Style Sheet)是前端開發中最基本也是最必須的三個(HTML,CSS,JavaScript)技能之一。然而在傳統的前端開發中,CSS的開發過於靜態化,存在着一些制約開發效率的問題,例如,語法不夠強大,無法嵌套書寫,導致模塊化開發中多次重複書寫相同的選擇器;沒有變量和合理的樣式複用機制,使得邏輯上相關的屬性值必須以字面量的形式重複輸出,導致代碼冗餘、難以維護,等等。

1、背景

爲了解決上述問題,提高CSS開發效率,近十年來,陸續有多種CSS預處理器被提出。那麼,什麼是CSS預處理器呢?CSS預處理器定義了一種專門針對web頁面樣式設計的編程語言,其基本思想是,用一種專門的編程語言,爲CSS增加一些編程的特性,並將CSS文件作爲目標生成文件。CSS預處理器爲CSS增加了一些編程的特性,例如可以使用變量、簡單的邏輯程序、函數等等,且無需考慮瀏覽器的兼容性問題,讓CSS的編寫更加簡潔、適應性更強、可讀性更佳。CSS 預處理器提供了CSS 缺失的樣式層複用機制,減少了冗餘代碼,提高了樣式代碼的可維護性。目前,CSS預處理器技術已經比較成熟,而且涌現出多種不同的CSS預處理器語言,例如:Sass(SCSS)、LESS、Stylus、 Turbine、Swithch CSS、CSS Cacheer、DT CSS等。

在衆多的CSS預處理器語言中, Sass、LESS和Stylus被使用的最多,也最優秀。這三款CSS預處理器語言具有一些相同的特性,例如:變量、混入、嵌套、函數等,根據以往使用者的經驗,對三者的簡單總結如下:

  1. LESS

LESS,2009年出現,使用CSS的語法,讓大部分開發者和設計師更容易上手,其缺點是比起Sass和Stylus,編程功能不夠強大。

  1. Sass

Sass,2007年誕生,是最早的CSS預處理器,發展成熟,但依賴於ruby環境,所以裝Sass之前要先安裝和學習ruby,增加開發、維護人員的學習成本。

  1. Stylus

Stylus,2010年產生,來自Node.js社區,功能上更爲強壯,和js聯繫更加緊密,可以創建健壯的、動態的、富有表現力的CSS。

綜合考慮三者的功能、學習成本,以及企業環境,如果要使用CSS預處理器,Stylus似乎是最合適的。

2、Stylus介紹及特點

Stylus 是一個基於Node.js的CSS的預處理框架,誕生於2010年,比較年輕,可以說是一種新型語言,其本質上做的事情與 Sass/LESS 等類似, 可以以近似腳本的方式去寫CSS代碼,創建健壯的、動態的、富有表現力的CSS,默認使用 .styl 的作爲文件擴展名,支持多樣性的CSS語法。Stylus比LESS更強大,而且基於nodejs比Sass更符合我們的思路。

Stylus的特點如下

  • 基於js

Node.js是一個Javascript運行環境(runtime),是對Google V8引擎進行了封裝,V8引擎執行Javascript的速度非常快,性能非常好。對於不瞭解Node.js的開發人員,不會增加太多學習成本。Stylus基於Node.js,換而言之,就是藉助JavaScript讓CSS更富有表現力,更動態,更健壯!而且還有專門的JavaScript API。

  • 支持Ruby之類框架

雖然Stylus基於Node.js,但是依然支持Ruby之類框架,還有FireBug插件FireStylus, sublimetext插件,便於開發、調試。

  • 功能強大,使用靈活,支持多樣性的CSS語法

Stylus的功能比LESS強大,不遜於Sass。在用法上,支持傳統的CSS,而且相對於傳統的用法,更加簡潔、靈活,像省掉花括號、冒號,分號,甚至使用混合的CSS編程,Stylus都可以接受。

3、使用Stylus的優缺點

【優點】

  • 解決樣式覆寫的問題,尤其是mixin式複用

使用純CSS,我們可以抽象出一些常用的佈局CSS屬性組合,通過CSS的類組合來達成常見的mixin式複用,然而這種方案存在一些問題,例如,當頁面重構時,需要頻繁修改class name,這個問題在後端人員掌握着視圖層的時候格外突出,前後端耗費很多溝通成本;在約束上下文的時候非常無力,比如“只有在ul下面的img.db允許是display:block”的規則,寫成“ul img.db { display: block; }”就完全跑偏了,它違背了創建這個.db類時的本意,造成了代碼的可讀性和可維護性下降。如果你要改動規則,需要同時修改HTML和CSS,也可能造成新的樣式問題。

而通過Stylus可以建立一種新的代碼風格,只允許CSS Class代表UI模塊的抽象,這樣一來,改動樣式時不至於通知後端改模板,然後在CSS Class內部實現mixin。而這正是CSS的短板,CSS體系內的用法只有複製粘貼。

  • 可緩解多瀏覽器兼容造成的冗餘

進入CSS3的時代,舊式CSS hack如filter,新式兼容前綴如-webkit-等,都是冗餘,修改的時候也需要修改多處,不容易維護。在Stylus裏面,寫個函數就能解決,多次複用也不需要看到如此之多的hack。

  • 提高效率,節約成本.

用Stylus開發CSS可以提高效率,它類似於一種CSS的方言,可以用更精簡的語法表達更多的意思。比如,Stylus中可以使用變量,比如和 UED 同學訂好各種樣式的規範,做好變量後開發中直接使用,避免頁面中的各種雜亂樣式。當樣式需求有變動時,也可以重新給變量賦值,一下改掉相關樣式,不用再一點一點的改。

  • 使CSS開發更加靈活

Stylus可以使用變量、條件、循環,兼容傳統的CSS樣式,等等,可以讓CSS的開發和修改更加靈活。

【缺點】

  • 開發過程增加步驟

CSS的好處在於簡便、隨時隨地被使用和調試,使用Stylus,增加了預編譯CSS的步驟,讓我們開發工作流中多了一個環節,調試也多了個步驟。

  • 增加學習成本。

雖然Stylus簡單易學,可以兼容傳統CSS,但是當開發和維護團隊都從CSS過渡到Stylus時,還是需要一點學習成本的,而且初學者使用起來,不一定能明顯提高效率。

二、  使用Stylus的方便之處

1、基本語法

Stylus的文件擴展名是“.styl”,語法規則使用縮進控制來代替花括號,使用逗號或換行爲多個選擇器同時定義屬性,同時Stylus也接受不帶大括號、分號、冒號的語法,也接受標準的CSS語法,使用起來非常靈活,如下所示:

stylus1

2、變量

變量允許我們單獨定義一系列通用的樣式,然後在需要的時候去調用它。Stylus中支持變量,可以減少代碼冗餘,提高靈活度。

Stylus樣式中,聲明變量沒有任何限定,可以使用“$”符號開始,結尾的分號可有可無,但變量名和變量值之間的等號是必須的。變量命名需要注意的是,如果使用“@”符號開頭來聲明變量,Stylus會進行編譯,但其對應的值並不會賦值給變量。換句話說,在 Stylus中不要使用“@”符號開頭聲明變量。

Stylus的變量和其他程序語言一樣,可以實現值的複用,同樣,它也存在生命週期,也就是Scope(變量範圍,開發人員習慣稱之爲作用域),簡單點講就是局部變量和全局變量的概念,查找變量的順序是先在局部定義中找,如果找不到,則查找上級定義,直至全局,也就是一種向上冒泡查找的過程。Stylus中我們可以指定表達式爲變量,變量甚至可以組成一個表達式列表。

3、運算

Stylus具有運算的特性,簡單的講,就是對數值型的Value(如:數字、顏色、變量等)進行加減乘除等運算。Stylus的運算是三款預處理器(LESS、Sass、Stylus)語言中最強大的一款,它擁有其他程序語言一樣的運算功能。這樣的特性在CSS樣式中是想都不敢想的,但在Stylus中,對樣式做一些運算一點問題都沒有。

4、邏輯控制

說到編程,對於編程基本控制流,大家並不會感到陌生,除了循環就是條件了。條件提供了語言的可控性,否則就是純粹的靜態語言。在 Stylus 中,提供了 if、else if、else、unless、for…in 來實現類似功能,語法簡潔靈活,如下示例:

stylus2

Stylus除了這種簡單的條件語句應用之外,還支持後綴條件語句。這就意味着可以把if和unless(unless條件,其基本上與if相反,本質上是“(!(expr))”)當作操作符,當右邊表達式爲真時,執行左邊的操作對象。

在Stylus中,循環是通過for/in表達式來進行的,這對一些類似樣式的書寫,是非常方便的。

5、嵌套

Stylus中的嵌套指的是在一個選擇器中嵌套另一個選擇器來實現繼承,從而減少代碼量,使代碼看起來更加清晰,並且增加了代碼的可讀性。比如說,我們在CSS中,多個元素有一個相同的父元素,那麼寫樣式會變得很乏味,我們需要一遍一遍的在每個元素前寫這個父元素,除非給特定的元素添加類名“class”或者ID。相反,使用Stylus的嵌套特性,我們可以在父元素的大括號內寫這些元素。同時可以使用“&”符號來引用父選擇器。如下所示:

stylus3

6、混合(混入、混寫,Mixins)

混合(mixins)應該說是CSS預處理器最精髓的功能之一了。它提供了 CSS 缺失的最關鍵的東西:樣式層面的抽象。它是CSS預處理器中語言中最強大的特性,簡單點來說,Mixins可以將一部分樣式抽出,作爲單獨定義的模塊,被很多選擇器重複使用。

在的CSS書寫中,經常會遇到某段CSS樣式需要被用於多個元素中,這樣就需要重複的寫多次。而在CSS預處理器語言中,我們可以爲這些公用的CSS樣式 定義一個Mixin,然後在需要使用這些樣式的地方,直接調用定義好的Mixin。這是一個非常有用的特性,Mixin被當作一個公認的選擇器,還可以在Mixin中定義變量或者默認參數。也就是說,混合可以將一個已定義好的classA輕鬆引入到classB中,從而簡單的實現classB繼承classA中的所有屬性。Minxin還可以單參數,可以帶參數地調用minxin,就像使用函數一樣。

Stylus中的混合可以不使用任何符號,就是直接聲明Mixins名,然後在定義參數、參數默認值等。如下所示:

stylus4

上面的Stylus代碼定義了border-radius(n)方法,作爲一個mixin(作爲狀態調用,而非表達式)調用,當border-radius()在選擇器中被調用時,其屬性會被擴展並複製在該選擇器中,例如“form input[type=button]”“form input[type=text]”,而且參數是參數的圓括號,可以省去。

7、函數

Stylus自帶了諸如色彩處理、類型判斷、數值計算等內置函數,目前版本的數量在 80 個左右。

除了內置函數,stulys提供了強大的內置的語言函數定義,其定義與混入(mixins)一致,卻可以返回值,如下:

stylus5

Stylus調用函數爲直接指定參數名的方式傳入參數,這樣做的好處是,如果參數列表比較長,Stylus 可以直接爲列表後面的參數賦值,而不需要一路將之前的參數填上null或默認值。Stylus 將這個特性稱爲【Named parameters】,在 Stylus 中,這些都是隱含的,最後一個表達式的值會作爲返回值,可以返回多個返回值。

【函數與mixin的區別】

那麼,這種寫法和 mixin 有什麼區別呢?當把函數作爲 mixin 調用時,如果其中有 prop: value 這樣格式的內容,就會被當做樣式規則輸出,mixin沒有返回值。Stylus 中大量的內容都是根據調用時的 context 去隱式推斷該使用什麼邏輯進行輸出,而非 Less 和 Sass 那樣使用關鍵字去顯式地進行區分。

8、繼承

在傳統的CSS中,在多個元素應用相同的樣式時,通常在CSS中都是這樣寫:stylus6

這種寫法,可以實現部分代碼重用, 但是,當我們需要給某些元素單獨添加另外的樣式時,就需要把相應選擇器單獨出來寫樣式,如此一來,我們維護樣式就相當麻煩。爲了應對該問題,Stylus提供了繼承機制,可以從一個選擇器繼承另一個選擇器下的所有樣式。

Stylus中,在繼承另時需要使用“@extend”開始,後面緊跟被繼承的選擇器,如下代碼:

 

stylus7

講到這裏,也許大家會覺得,那跟上面講到的混入有點類似啊,混入也可以實現代碼的重用,那我用混入,不用繼承,還不是一樣?混入很好用,可也有問題:如果多個地方都混入同樣的代碼,會造成輸出代碼的多次重複,這個時候繼承就派上用場了。

9、導入

在CSS中,使用@import來導入樣式,這種做法會增加http的請求。而Stylus中的導入(@import)規則和CSS的有所不同,當導入.styl文件時,它只是在語義上導入不同的文件,最終結果是生成一個CSS文件。但是,如果是通過“@import”導入“file.css”樣式文件,那麼效果跟普通CSS導入樣式文件一樣。

@import工作原理爲:遍歷目錄隊列,並檢查任意目錄中是否有該文件(類似node的require.paths)。該隊列默認爲單一路徑,從filename選項的dirname衍生而來。 因此,如果你的文件名是/tmp/testing/stylus/main.styl,導入將顯現爲/tmp/testing/stylus/。@import也支持索引形式。這意味着當你@import blueprint, 則會理解成blueprint.styl或blueprint/index.styl. 對於庫而言,這很有用,既可以展示所有特徵與功能,同時又能導入特徵子集。

Stylus中導入文件需要注意的是:導入文件中定義了變量、混合等信息也將會被引入到主樣式文件中,因此需要避免它們的相互衝突。

10、補充

【插值】

Stylus Stylus支持通過使用“{ }”字符包圍表達式來插入值,其會變成標識符的一部分。例如,-webkit-{‘border’ + ‘-radius’}等同於-webkit-border-radius。插值也可以在選擇器上起作用。例如,我們可以指定表格前3行的高度,如下:

stylus8

【關鍵字參數】

Stylus支持關鍵字參數,允許你根據相關參數名引用參數,但是,我們可以在列表中的任何地方放置關鍵字參數,其餘不鍵入參數將適用於尚未得到滿足的參數。

【CSS字面量】

不管什麼原因,如果遇到Stylus搞不定的特殊需求,你可以使用@css使其作爲CSS字面量解決之。

【字符轉碼】

Stylus可以字符轉碼。這可以讓字符變成標識符,或是渲染成字面量。

【錯誤報告】

Stylus內置夢幻般的錯誤報告,針對語法、解析以及計算錯誤,完整的堆棧跟蹤,行號和文件名。

三、  實例與總結

上面介紹了Stylus的特點、用法,我們來對Stylus進行一個實例的應用。

1、Stylus應用實例

下面的CSS代碼,是一個樣式文件pageshame.css,因爲文件較大,我們截取它比較有代表性的一段代碼,如下:

stylus9

從這段CSS代碼中,我們可以看到有大量的重複代碼,例如, “.drillDataBackgroud_1”與“.drillDataBackgroud”下的類“.close”的樣式代碼完全一樣,卻要被書寫兩次;選擇器因無法使用嵌套,導致選擇器在子選擇器前被一次又一次重寫,例如“.popoverBody”;大量類似的樣式,因無法使用變量和循環,也是需要一遍一遍書寫大量重複的代碼,例如“.popoverBody .popGongjilian > table > tbody > tr > td”;同一個選擇器的樣式,被分散在不同處,沒有模塊化開發的概念,等等。這些都是傳統CSS代碼無法避免的,因爲它就是一個靜態開發的過程。那如果使用Stylus來寫,會是什麼效果呢?我們來看下該CSS代碼對應的Stylus代碼:

stylus10

在上述的Stylus代碼中,我們通過使用變量、混合(mixin)、選擇器的嵌套、循環,使得代碼精簡不少。例如,定義混合close(),那麼在“.drillDataBackgroud_1”與“.drillDataBackgroud”下的類“.close”就不用重複書寫,只用在相關處調用close()就行;在“.popoverBody”的樣式書寫中,我們使用了選擇器的嵌套,使代碼更精簡、緊湊,模塊化開發比較明顯;在“.popoverBody .popGongjilian > table > tbody > tr > td”的樣式書寫中,我們通過變量和for循環,使原本謝了7次的代碼一次搞定。那麼,我們再來看exp.styl文件編譯生成的CSS代碼exp.css,如下:

stylus11

可以看到,由exp.styl編譯生成的exp.css代碼,跟pageshame.css中的原始的CSS代碼,效果是一模一樣的。

2、總結

通過對Stylus的特點、優缺點、使用方法的介紹,再結合具體的應用實例,可以看到在CSS編程中,使用Stylus的確可以精簡CSS代碼、提高代碼複用率,使用變量、循環,又可以大大提高代碼靈活度,方便在樣式需求變更時,做出統一的修改,等等。而且,Stylus簡單易學,不會消耗過大的學習成本,更重要的是,Stylus兼容CSS的代碼,即使在後期維護中,有人不懂Stylus,但是需要修改其中的CSS代碼,也可以在Stylus文件中直接書寫CSS代碼,完全不會給不懂Stylus的同伴挖坑。因此,在以後的前端開發者,在書寫CSS代碼時,可以嘗試使用Stylus,當熟練了Stylus,相信可以明顯提高工作效率;而且在樣式需求發生變更時,可以很快統一修改。

如果您需要了解更多內容,可以
加入QQ羣:486207500、570982169
直接詢問:010-68438880-8669



文章分類: 安全分享 
文章關鍵詞: CSS預處理器CSS預處理工具StylusFireStylus sublimetextNode.js CSSStylus工具Stylus應用實例Stylus的優缺點Stylus的特點 用法 
轉載請註明:“轉自綠盟科技博客”: 原文鏈接.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章