stylus入門學習筆記

學習到 vue, 有人推薦使用 stylus 這個 css 預處理器。而之前也只是停留在聽說過 stylus,並沒有實際操作過。現在正好抽空來學習一下唄;如果會 less,sass之類的 css 預編譯器,學 stylus 也是 so easy!
學習來源:張鑫旭個人博客,這是個 css 界大牛哦

話不多說,先來段代碼比較一下吧。

body
    color: white
    textarea, input
        border: 1px solid #333
    p
    li
    ul
        margin: 0
    .contain
        &:hover
            opacity: 0.8

等同於

body {
    color: white;
}
body textarea,
body input {
    border: 1px solid #333;
}
body p,
body li,
body ul {
    margin: 0;
}
body .contain:hover {
    opacity: 0.8;
}

目前看來,stylus 就是將 sass 的花括號去掉,分號不要而已。按照之前的 sass、less 的語法寫,就差不了太多。所以不做多解釋,繼續下面。

有 stylus 無法處理的屬性值,可以使用 unquote()

filter
unquote('progid: DXImageTransform.Microsoft.BasicImage(rotation=1)')

轉化成

filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1)

#聲明變量

直接使用 ‘=’ 來聲明, 變量中可以帶 $

font-size = 14px
$color = #ddd
body {
    font-size: font-size
    background-color: $color
}

等同於

body {
    font-size: 14px;
    background-color: #ddd;
}

#插值

Stylus支持通過使用{}字符包圍表達式來插入值,其會變成標識符的一部分。例如,-webkit-{‘border’ + ‘-radius’}等同於-webkit-border-radius.

vendor(prop, args)
  -webkit-{prop} args
  -moz-{prop} args
  {prop} args

border-radius()
  vendor('border-radius', arguments)

box-shadow()
  vendor('box-shadow', arguments)

button
  border-radius 1px 2px / 3px 4px

轉換成

button {
  -webkit-border-radius: 1px 2px / 3px 4px;
  -moz-border-radius: 1px 2px / 3px 4px;
  border-radius: 1px 2px / 3px 4px;  
}

插值也可以在選擇器上起作用。eg:

table
  for row in 1 2 3 
    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;
}

利用這個屬性,我們可以封裝很多的方法了。將瀏覽器兼容前綴寫法封裝成一個函數。

add-attr-prefix(attr, args) {
    -webkit-{attr}: args
    -moz-{attr}: args
    -o-{attr}: args
    -ms-{attr}: args
    {attr}: args
}

// 封裝一下 box-shadow 函數
box-shadow()
    add-attr-prefix('box-shadow', arguments)
body
    box-shadow: 8px 8px 20px red

等價於

body {
    -webkit-box-shadow: 8px 8px 20px red;
    -moz-box-shadow: 8px 8px 20px red;
    -o-box-shadow: 8px 8px 20px red;
    -ms-box-shadow: 8px 8px 20px red;
    box-shadow: 8px 8px 20px red;
}

#混合書寫

混入和函數定義方法一致,但是應用卻大相徑庭。
定義方式:

aaa ()
    語句塊

譬如,

border-radius(npx)
    -webkit-border-radius npx
    -moz-border-radius npx
    border-radius npx
.box
    border-radius(5px)
// 使用混入書寫,你可以完全忽略括號,提供夢幻般私有屬性的支持。
    border-radius 5px

也可以不傳參數,用 arguments

border-radius()
    -webkit-border-radius arguments
    -moz-border-radius arguments
    border-radius arguments
box-shadow(args...)
    -webkit-box-shadow args
    -moz-box-shadow args
    box-shadow args
box-shadow1()
    -webkit-box-shadow agruments
    -moz-box-shadow agruments
    box-shadow agruments
.box
    box-shadow 1px 1px 5px red, 1px 3px 5px green
.box1
    box-shadow 1px 1px 5px red, 1px 3px 5px green

需要注意的是,argument 和 args…,前者可以準確的將所有參數傳遞,包括逗號之類的一些特殊符號。
看一下輸出結果:

.box {
    -webkit-box-shadow: #ddd 1px 1px #eee 2px 2px;
    -moz-box-shadow: #ddd 1px 1px #eee 2px 2px;
    box-shadow: #ddd 1px 1px #eee 2px 2px;
}
.box1 {
    -webkit-box-shadow: #ddd 1px 1px, #eee 2px 2px;
    -moz-box-shadow: #ddd 1px 1px, #eee 2px 2px;
    box-shadow: #ddd 1px 1px, #eee 2px 2px;
}

同 less, sass 一樣,引用父級也是用 &;利用 & 封裝一個條紋表格

stripe(even = #fff, odd = #eee)
    tr
        background-color odd
        &.even
        &:nth-child(even)
            background-color even

函數是可以返回值的。有時候返回值不是一個具體的值,而是表示符。

swap(a, b)
    b a

這樣的時候,寫成

swap(a, b)
    (b a)
swap(a, b)
    return b a

個人在實際項目中用到的方法少之又少;所以感覺,不做遊戲開發的話,用到方法的少。看到這兒,就算是已經入門了。

#註釋

Stylus支持三種註釋,單行註釋,多行註釋,以及多行緩衝註釋。
前面三種就不多說了,和以前的寫法完全一致。對於多行緩衝註釋,跟多行註釋類似,不同之處在於開始的時候,這裏是/*!.這個相當於告訴Stylus壓縮的時候這段無視直接輸出。

#條件

if, else if, else 和常見的條件是一樣的。在 stylus 裏,也想 ruby 一樣,用了 unless (除非)條件。也很好理解,其基本上與 if 相反,本質上是 (!(expr)). eg:

disable = true

unless disable 
    display none

另外,Stylus 支持後綴條件,這就意味着 if 和 unless 可以當作操作符;當右邊表達式爲真的時候執行左邊的操作對象。
一般適用於單行語句。
譬如:

negative(n)
  unless n is a 'unit'
    error('無效數值')
  if n < 0
    yes
  else
    no
// 就可以寫成下面這種形式了
negative(n)
  error('無效數值') unless n is a 'unit'
  return yes if n < 0
  no

#迭代

for <val-name> [, <key-name>] in <expression>

感覺實際開發中用不到,暫時先放着,待後續補齊吧。

#@import

任何 .css 擴展的文件名將作爲字面量。例如,

@import "reset.css"

// 渲染成 ===>>
@import "reset.css"

當使用 @import 沒有 .css 擴展,會被認爲是 Stylus 片段(如:@import”mixins/border-radius”)。

@import 工作原理爲:遍歷目錄隊列,並檢查任意目錄中是否有該文件(類似 node 的 require.paths)。該隊列默認爲單一路徑,從 filename 選項的 dirname 衍生而來。因此,如果你的文件名是 /tmp/testing/stylus/main.styl,導入將顯現爲 /tmp/testing/stylus/。

@import 也支持索引形式。這意味着當你 @import blueprint,則會理解成 blueprint.styl 或 blueprint/index.styl. 對於庫而言,這很有用,既可以展示所有特徵與功能,同時又能導入特徵子集。

還有像 @media,@font-face,@keyframes 等和 css 中的差不了太多。

注意,@keyframes 會通過 vendors 變量,會自動添加私有前綴(webkit moz official)。如果我們只想有標準解析,很簡單,修改 vendors = official.

#@extend

看個例子感受。

red = #E33E1E
yellow = #E2E21E

.message
  padding: 10px
  font: 14px Helvetica
  border: 1px solid #eee

.warning
  @extends .message
  border-color: yellow
  background: yellow + 70%

.error
  @extends .message
  border-color: red
  background: red + 70%

.fatal
  @extends .error
  font-weight: bold
  color: red

生成 css 如下

.message,
.warning,
.error,
.fatal {
  padding: 10px;
  font: 14px Helvetica;
  border: 1px solid #eee;
}
.warning {
  border-color: #e2e21e;
  background: #f6f6bc;
}
.error,
.fatal {
  border-color: #e33e1e;
  background: #f7c5bc;
}
.fatal {
  font-weight: bold;
  color: #e33e1e;
}

ok, stylus 的學習,就簡單到這兒了吧。後面有必要再深入學習一波。



那一夜我燒燬了所有的記憶,從此我的夢就透明瞭,那一天我扔掉了所有的昨天,從此我的腳步就輕盈了。 一一 泰戈爾(《飛鳥集》)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章