Stylus 是一個 Node.js 架構下的 CSS 前處理器,這裡介紹它的基本使用方式。

Stylus 是一種用來產生 CSS 的程式語言,其語法基本上是從傳統的 CSS 簡化而來,所以跟 CSS 的寫法類似,但是更精簡,另外也加入一些函數與運算的功能,讓使用上更彈性。


Stylus 有以下幾個特點:

  • 以 Node.js 為基礎,不需要其餘的軟體。(Sass 需要 Ruby)
  • 有提供 JavaScript API,可以讓使用者自定前處理流程。
  • 語法精簡,不需要括號、冒號或分號,只使用空白分隔。(如果使用這些符號也是可以正確編譯)
  • 有額外的 Nib 函式庫可以使用。

安裝 Stylus

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

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

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 除了讓你少寫一些基本的標點符號之外,它還有很多其他的功能,以下我們以各種範例來介紹。

巢狀結構

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;
}

父節點參照(Parent Reference)

跟 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;
}

Mixins

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

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;
}

Interpolation

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;
}

sprintf 運算子

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 的官方網站。

參考資料:BootStrapthe change logblog.fens.me