Stylus 是一個 Node.js 架構下的 CSS 前處理器,這裡介紹它的基本使用方式。
Stylus 是一種用來產生 CSS 的程式語言,其語法基本上是從傳統的 CSS 簡化而來,所以跟 CSS 的寫法類似,但是更精簡,另外也加入一些函數與運算的功能,讓使用上更彈性。
Stylus 是建立在 Node.js 之上的工具,所以首先要先安裝好 Node.js,然後再用 npm
安裝 Stylus:
npm install stylus
這樣會將 Stylus 安裝在目前的目錄中,如果要安裝在系統的目錄,就要再加上 -g
參數:
npm install stylus -g
稍後使用時,請自己注意安裝的路徑,如果安裝的位置是在系統設定好的 PATH
路徑上,那麼直接執行 stylus
就可以使用了:
stylus -h
如果安裝在本地的目錄,可能就要加上相對的路徑,例如:
./node_modules/stylus/bin/stylus -h
Stylus 的語法就是把原本的 CSS 簡化而成的,例如原本的 CSS 程式碼是這樣:
body { font: 12px Helvetica, Arial, sans-serif; } a.button { -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; }
首先把大括號省略,變成這樣:
body font: 12px Helvetica, Arial, sans-serif; a.button -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px;
接著再省略分號:
body font: 12px Helvetica, Arial, sans-serif a.button -webkit-border-radius: 5px -moz-border-radius: 5px border-radius: 5px
最後連同冒號也省略:
body font 12px Helvetica, Arial, sans-serif a.button -webkit-border-radius 5px -moz-border-radius 5px border-radius 5px
使用 mixins 讓程式更乾淨:
border-radius() -webkit-border-radius arguments -moz-border-radius arguments border-radius arguments body font 12px Helvetica, Arial, sans-serif a.button border-radius(5px)
以上這些都是可以在 Stylus 中使用的語法,也就是說如果你不想省略某些符號(例如保留冒號等),Stylus 也是可以正常編譯的。
在撰寫 Stylus 時唯一要注意的就是空白,Stylus 是靠著縮排來判斷整個程式碼的結構的,這個跟 Python 有點類似。
Stylus 的原始檔都是以 .styl
作為副檔名,假設你已經建立了一個 Stylus 的原始檔 main.styl
,則可直接使用 stylus
指令進行編譯:
stylus main.styl
編譯完會得到一個 main.css
檔,這個檔案就是編譯的結果。
如果想要產生一個最小化 CSS 檔,可以加上 -c
或 --compress
參數:
stylus -c main.styl
若要指定輸出的目錄,可以使用 -o
或 --out
參數:
stylus -o output main.styl
這樣就會將輸出的 CSS 檔放置在 output
目錄中。
使用 -U
或 --inline
參數可以將 CSS 中的圖片以 Data URI 的方式,內崁至 CSS 檔中:
stylus -U main.styl
stylus
還有許多參數,可以使用
stylus -h
來查看。
當然 Stylus 除了讓你少寫一些基本的標點符號之外,它還有很多其他的功能,以下我們以各種範例來介紹。
Stylus 的巢狀結構語法可以讓程式碼更簡潔:
body { font: 14px/1.5 Helvetica, arial, sans-serif; #logo { border-radius: 5px; } }
編譯結果為:
body { font: 14px/1.5 Helvetica, arial, sans-serif; } body #logo { border-radius: 5px; }
跟 SASS 一樣可以參照父節點:
ul li a display: block color: blue padding: 5px html.ie & padding: 6px &:hover color: red
編譯結果為:
ul li a { display: block; color: #00f; padding: 5px; } html.ie ul li a { padding: 6px; } ul li a:hover { color: #f00; }
Stylus 的 mixins 可以讓你定義函數,重複使用程式碼:
border-radius(val) -webkit-border-radius: val -moz-border-radius: val border-radius: val button { border-radius(5px); }
編譯結果為:
button { -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; }
Transparent mixins 是 Stylus 特有的功能,它可以讓你傳入任意個數的參數:
border-radius() -webkit-border-radius: arguments -moz-border-radius: arguments border-radius: arguments button { border-radius: 5px 10px; }
編譯結果為:
button { -webkit-border-radius: 5px 10px; -moz-border-radius: 5px 10px; border-radius: 5px 10px; }
Stylus 的變數跟一般程式語言差不多,你可以自己選擇變數名稱要不要用 $
字元開頭:
#prompt position: absolute top: 150px left: 50% width: w = 200px margin-left: -(w / 2)
編譯結果為:
#prompt { position: absolute; top: 150px; left: 50%; width: 200px; margin-left: -100px; }
Stylus 的區域屬性讀取功能,可以讓你取得特定的屬性值:
#prompt position: absolute top: 150px left: 50% width: 200px margin-left: -(@width / 2)
編譯結果為:
#prompt { position: absolute; top: 150px; left: 50%; width: 200px; margin-left: -100px; }
這是 Stylus 的 for
迴圈寫法:
table for row in 1 2 3 4 5 tr:nth-child({row}) height: 10px * row
編譯結果為:
table tr:nth-child(1) { height: 10px; } table tr:nth-child(2) { height: 20px; } table tr:nth-child(3) { height: 30px; } table tr:nth-child(4) { height: 40px; } table tr:nth-child(5) { height: 50px; }
Stylus 的 interpolation 功能可以讓你將變數安插在 CSS 屬性名稱中,組成各種屬性名稱:
vendors = webkit moz o ms official border-radius() for vendor in vendors if vendor == official border-radius: arguments else -{vendor}-border-radius: arguments #content border-radius: 5px
編譯結果為:
#content { -webkit-border-radius: 5px; -moz-border-radius: 5px; -o-border-radius: 5px; -ms-border-radius: 5px; border-radius: 5px; }
這是 Stylus 支援的各種運算子:
body foo: 5px + 10 foo: 2 ** 8 foo: 5px * 2 foo: !!'' foo: foo and bar and baz foo: foo or bar or baz foo: 1..5 foo: 1...5 foo: 'foo' is a 'string' foo: (1 2 3) == (1 2 3) foo: (1 2 3) == (1 2) foo: ((one 1) (two 2)) == ((one 1) (two 2)) foo: ((one 1) (two 2)) == ((one 1) (two)) foo: ((one 1) (two 2))[0] foo: 3 in (1 2 3 4)
編譯結果為:
body { foo: 15px; foo: 256; foo: 10px; foo: false; foo: baz; foo: foo; foo: 1 2 3 4 5; foo: 1 2 3 4; foo: true; foo: true; foo: false; foo: true; foo: false; foo: one 1; foo: true; }
Stylus 會在適當的時機自動進行變數的型別轉換:
body foo: foo + bar foo: 'foo ' + bar foo: 'foo ' + 'bar' foo: 'foo ' + 5px foo: 2s - 500ms foo: 5000ms == 5s foo: 50deg
編譯結果為:
body { foo: foobar; foo: 'foo bar'; foo: 'foo bar'; foo: 'foo 5px'; foo: 1.5s; foo: true; foo: 50deg; }
Stylus 的 %
運算子,其作用相當於一般語言的 sprintf
函數:
body foo: '%s / %s' % (5px 10px) foo: 'MS:WeirdStuff(opacity=%s)' % 1 foo: unquote('MS:WeirdStuff(opacity=1)')
編譯結果為:
body { foo: 5px / 10px; foo: MS:WeirdStuff(opacity=1); foo: MS:WeirdStuff(opacity=1); }
Stylus 也可以直接對顏色進行運算:
body foo: white - 50% foo: black + 50% foo: #eee - #f00 foo: #eee - rgba(black,.5) foo: #cc0000 + 30deg
編譯結果為:
body { foo: #808080; foo: #808080; foo: #0ee; foo: rgba(238,238,238,0.5); foo: #c60; }
Stylus 可以自行定義函數,函數定義的語法跟 mixins 相同,但在使用上則有差異:
sum(nums...) n = 0 n += num for num in nums body foo: sum(1, 2, 3)
編譯結果為:
body { foo: 6; }
具名參數可以讓程式碼看起來更清楚:
fade-out(color, amount = 50%) amount /= 100 color - rgba(0,0,0,amount) body foo: fade-out(#eee) foo: fade-out(#eee, 20%) foo: fade-out(#eee, amount: 50%) foo: fade-out(color: #eee, amount: 50%) foo: fade-out(amount: 50%, #eee) foo: fade-out(amount: 50%, color: #eee)
編譯結果為:
body { foo: rgba(238,238,238,0.995); foo: rgba(238,238,238,0.998); foo: rgba(238,238,238,0.995); foo: rgba(238,238,238,0.995); foo: rgba(238,238,238,0.995); foo: rgba(238,238,238,0.995); }
以上是一些常見的使用範例,至於更詳細的語法,請直接參考 Stylus 的官方網站。