Stylus使用指南

Stylus彷佛並非頗有名,以致於不少人不知道它,但提到SASS相信有很多人據說過甚至使用過很長時間。其實不管是LESS、SASS仍是Stylus甚至是Absurd這些預處理工具,都是對CSS的一種延伸和強化。出現這些工具的緣由很簡單,CSS自己只是一種描述性質的東西,甚至它不能算是語言而是樣式表,因此咱們須要一個有條件語句和變量甚至是函數的東西去動態生成CSS代碼來達到提升效率和加強可維護性的目的。css

本文主要以Stylus語法自己和簡單的使用爲主要內容,它的目的是介紹和簡單指南。將不會過多涉及Javascript的API調用等問題。html

介紹

官方的介紹很是簡短而精煉:前端

Expressive, dynamic, robust CSSgit


富有表現力的動態的強壯的CSS,它反應了一些主要特色。github

首先Stylus相較於SASS更加簡潔,甚至冒號也均可以省略,初學Stylus時感到它太神奇了,僅僅以空格分隔屬性名和多個屬性值就能夠生成想要的CSS,並且還能夠拼接字符串等等。與此同時,相似Ruby或Python完善的縮進語法,Stylus在簡約自由中有效的防止了語法歧義。web

body
  border 10px*.1 soli+'d' darken(red,10%)

// =>
body {
    border: 1px solid #e60000;
}

其次是動態,這正是其精髓所在,Stylus由Javascript編譯,其結構語句也和Javascript相差很少,前端人員能夠很輕鬆的上手。雖然這方面Absurd是一個極端,但Stylus較之LESS則要優越很多,不只僅是可定義變量,如Javascript般的條件語句和循環語句也爲Stylus帶來各類可能,加上豐富的內置函數,能夠輕鬆判斷和操做各類變量。而利用這樣的動態性,就能夠寫出很是強壯的CSS以知足不一樣環境和條件下的須要。npm

pos(type, args)
  i = 0
  position unquote(type)
  {args[i]} args[i + 1] is a 'unit' ? args[i += 1] : 0
  {args[i += 1]} args[i + 1] is a 'unit' ? args[i += 1] : 0

absolute()
  pos('absolute', arguments)
fixed()
  pos('fixed', arguments)

#prompt
  absolute top 150px left 5px
  width 200px
  margin-left -(@width / 2)
#logo
  fixed top left

// =>
#prompt {
  position: absolute;
  top: 150px;
  left: 5px;
  width: 200px;
  margin-left: -100px;
}
#logo {
  position: fixed;
  top: 0;
  left: 0;
}

簡單指南

能夠看到上面的代碼中使用了Mixin(混合)還有三目運算符等手段構建了一個針對position的方法,用來快速生成一個定位代碼片斷。有底向上來看這段代碼,#prompt和#logo是2個ID選擇器,在其中調用了一些Mixin,其實Mixin與Function的區別在於,Mixin的內容是一段CSS代碼,而Function應該是一個值並自動返回,因此調用它們的時候,前者將會替換爲一段CSS,然後者將返回一個Boolean或者像素或者顏色之類的東西,也許用於判斷也許直接放入CSS。而後其中的absolute和fixed分別調用了pos這個Mixin。數組

前綴

並且在調用時,也不必定要使用括號的形式,可使用CSS的形式,直接Mixin名加空格而後寫參數。因此有時候能夠直接寫一個Mixin來修改CSS屬性的功能,好比看看下面這個兼容全部標準瀏覽器陰影的寫法,能夠很方便的爲標準調用加上各標準瀏覽器的前綴:瀏覽器

box-shadow()
  -webkit-box-shadow arguments
  -moz-box-shadow arguments
  -ms-box-shadow arguments
  -o-box-shadow arguments
  box-shadow arguments
box-shadow 2px 1px 10px red

// =>
-webkit-box-shadow: 2px 1px 10px #f00;
-moz-box-shadow: 2px 1px 10px #f00;
-ms-box-shadow: 2px 1px 10px #f00;
-o-box-shadow: 2px 1px 10px #f00;
box-shadow: 2px 1px 10px #f00;

能夠看到調用時的寫法與通常的寫法同樣,可是由於Mixin的存在,box-shadow再也不是一個屬性,能夠變成5行帶有各瀏覽器前綴的CSS。不只僅是box-shadow,CSS3的許多屬性都須要添加前綴,那是否是能夠更近一步呢,來寫一個前綴Mixin吧:sass

// add prefix for attribute
prefix(p_attr, argu...)
  $pfs = webkit moz ms o
  for $pf in $pfs
    -{$pf}-{p_attr} argu
  {p_attr} argu
// box shadow mixin
box-shadow()
  prefix(box-shadow, arguments)
// run
box-shadow 2px 1px 10px red
顏色

如同其餘CSS預處理工具同樣,Stylus在顏色方面也擁有許多內置函數,不管是判斷,提取仍是修改都十分強大。函數 red , blue , green , alpha 將分別返回顏色對應的rgba值,darklight 用於判斷顏色屬於亮色仍是暗色,hue , saturation , lightness 則分別返回顏色的色相、飽和度以及亮度,其中色相是在色環上的角度,單位是deg。我常常用的是lightendarken 這兩個函數,其做用是增長或減小一個顏色的亮度,另外還有飽和度的操做函數 desaturatesatucate

彷佛沒有用於修改色相的函數,不過這個需求很容易經過其餘辦法搞定。首先使用hue等函數將原始色的色相、飽和度、亮度以及透明度取出,而後對色相的角度進行修改,好比加90deg,最後再使用hsla函數,把去除的對應值看成參數傳入便可。下面用一組三態按鈕來舉個栗子:

See the Pen Single Button by Zhang zhengzheng (@tychio) on CodePen

能夠看到Stylus中的第一行代碼 $clr = #99ff22 只要修改這個顏色值就能夠改變按鈕的總體風格,並沒有需考慮hover和active狀態時對應的顏色。好比邊框使用 darken 來加深,陰影泛光可使用 lighten 來加亮,在觸碰時總體使用了 saturate 來改變飽和度,按下的Active狀態我使用了 invert 函數,能夠翻轉顏色,在視覺設計中這個顏色叫作對位色,即色相處於色環的對面的兩種顏色,好比綠對紅,黃對藍,例子中使用了黃綠,因此對位色就是紫色。固然也可使用上面提到的複雜一些的方法來修改色相,達到使用間隔色之類的效果。

響應式

對於響應式的支持,Stylus的media也能夠省略花括號,但和Sass有一些區別。Stylus在@media的括號中會原樣輸出,也就是說,咱們不能使用變量或混合還有計算等手段來直接寫media query。好比通常狀況下須要寫一個min-width,若是這樣寫

$mobiWidth = 768px
@media screen and (min-width $mobiWidth - 1px)
  body
    margin 0

產生的CSS代碼則仍然是

@media screen and (min-width $mobiWidth - 1px) {
  body {
    margin: 0;
  }
}

這不是一個bug,儘管在Github上有無數的人提出issue或者在其後+1,做者仍然不爲所動,緣由不明,不過幸運地是有不少人都提出解決辦法,下面是一個比較好的方法:

media()
  join(' and ', arguments)
$mobiWidth = 768px
$media = media('screen', '(min-width: ' + ($mobiWidth - 1px) + ')')
@media $media
  body
    margin 0

/// =>

@media screen and (min-width: 767px) {
  body {
    margin: 0;
  }
}

這樣就可使用變量來做爲media的參數了,只是寫起來會比sass麻煩一些,但我以爲這樣也許更自由,你能夠改進這個方法,好比傳一個object來做爲query條件,而不是拼接一個字符串。另外這個方法還用到了 join 內置函數,和Javascript中的Array方法join同樣,很容易使用,除了它還有 push , unshift 函數。

關於數組的定義,對於響應式來講有很是好的幫助,由於響應式每每是一系列的尺寸或設備,不管如何,使用數組能夠輕鬆的定義多組對應與索引的配套值。好比個人blog,對於不一樣寬度的設備中有不一樣的內容寬度以及邊距,來看看簡化的代碼:

$screen = 1920px 1280px 1024px 768px 640px 320px
$width = 1600px 1080px 840px 600px 480px 300px
$margin = 180px 100px 80px 40px 20px 0
media()
  join(' and ', arguments)
responsive(p_index)
  body
    width $width[p_index]
    margin-left $margin[p_index]
responsive(0)
for $i in 0 1 2 3 4 5
  $media = media('screen', '(max-width: ' + $screen[$i] + ')')
  @media $media
      responsive($i)

// =>
body {
  width: 1600px;
  margin-left: 180px;
}
@media screen and (max-width: 1920px) {
  body {
    width: 1600px;
    margin-left: 180px;
  }
}
// ...
@media screen and (max-width: 320px) {
  body {
    width: 300px;
    margin-left: 0;
  }
}

固然響應式不是簡單的改變尺寸,若是你須要控制某些內容的顯示則可使用一個Boolean的數組來判斷是否顯示,控制結構或樣式則能夠字符串的數組來放置一些預先寫好的Mixin名稱。

CSS Sprite

對於CSS Sprite相信是全部切圖者的主要工做產出,之前我也推薦過一些在線的製做Sprite的工具,不過如今有了Stylus,也許咱們可能更快的完成這一切。以前公司有須要國旗icon,因此作了這個小項目national_flag用來建立和維護國旗icon的CSS Sprite。因爲國家數目衆多,每一個國家對應一個國家代碼,因此我定義了一個二維數組用來表現圖片中國旗的位置,而後在數組中填入代碼,用來拼接圖標的class名稱,而後按照數組中的序號和尺寸就能夠生成對應的background-position了。主要代碼以下:

iconBuild(id, col, row)
    .country-{id}
        background-position (0px - (row * $size)) (0px - (col * $size))
/*r /c-> 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16*/
$row00 = CN AF AZ BH BD BN KH TL IN ID IR IQ IL JP JO KZ KW
$row01 = KG LA LB MY MV MN MM NP KP OM PK PS PH QA SA SG KR
$row02 = LK SY TJ TH TM AE UZ VN YE DZ AO BJ BW BF BI CM CV
$row03 = CF RO KM CG CI CD DJ EG GQ ER ET GA GH GN GW KE LS
$row04 = LR __ MG MW ML MR MU MA MZ NA NE NG RW ST SN SC SL
$row05 = SO ZA SD __ TZ __ TG TN UG ZM ZW __ __ __ __ __ __
$row06 = JM PR DO KN VC LC TT CR __ SV GT HN NI PA __ DE __
$row07 = MK AT __ __ __ BG CY __ __ DK SK SI ES EE FI FR __
$row08 = GR HU IE IS IT LV LI LT LU MT MD MC ME NO NL PL PT
$row09 = UK CZ __ RU SM __ SE CH TR UA EU __ CA __ MX __ US
$row10 = AR BO BR CL CO EC GY __ __ PE __ UY VE HK LY NZ RS
$row11 = PY AU SR TJ FM AI __ __ __ __ __ __ __ __ __ __ __
$pos = $row00 $row01 $row02 $row03 $row04 $row05 $row06 $row07 $row08 $row09 $row10 $row11
for $rowList, $row in $pos
    for $country, $col in $rowList
        if $country != __
            iconBuild($country, $row, $col)

其中for不一樣於Javascript,rowList爲數組遍歷出的一個元素,而$row爲索引,能夠這樣理解 for [value], [index] in [array] 。因此能夠在兩個嵌套的for中獲取縱橫的位置以及國家代碼,來生成CSS。

Stylue應用

做爲預處理工具,Stylus天然也須要預處理器,不過它不像Sass須要Ruby環境,Stylus由Javascript實現,因此有Javascript就能夠處理Stylus。

編譯工具
  • SublimeText2-Stylus2CSS是一款SublimeText2的Stylus插件。另外我使用這個項目的SublimeText2插件來高亮styl文件的代碼。
  • 另外今年8月WebStorm7也纔剛剛支持 - Stylus Support
  • CodePen支持各類CSS預處理,天然包括Stylus,上面的按鈕例子就是嵌入的CodePen。
  • Stylus官方在線實際上是一些示例,不過它是可編輯的,因此你也能夠隨便寫些什麼,即時能夠看到結果。不過好像還在使用低版本的Stylus,好比一些內置函數就不可用。
Grunt插件

不過說處處理文件,Grunt仍是個人最愛,尤爲Stylus是由Javascript實現,在Nodejs中天然是得天獨厚。npmjs上有許多用來處理Stylus的插件,下面簡單介紹一下Grunt的官方Stylus插件grunt-contrib-stylus。先來看看最簡單的配置方法:

stylus: {
  compile: {
    files: {
      'path/to/result.css': 'path/to/source.styl'
    }
  }
}

如此就能夠利用Grunt將source.styl文件中的Stylus代碼編譯爲result.css的CSS代碼。固然還可使用數組來進行多個Stylus文件的打包編譯。固然不只於此,先來看看主要的幾個配置項:

paths 將自動使用@import來引入一些Stylus文件,好比一些Mixin集合,放在一個Stylus文件中進行維護,寫在paths中後,就能夠在每一個Stylus文件中調用它們。define 能夠定義一些全局變量,而後在Stylus中使用,但我不喜歡使用這個配置,而是更喜歡把全局變量放在一個單獨的Stylus文件中,而後將這個文件加入paths的數組中。一句話,把全部不會直接產出CSS的Stylus代碼分紅若干個Stylus文件,而後所有添加到paths中,這樣在全部Stylus文件中均可以隨時調用了,但要注意這些Stylus文件的調用關係和使用前後順序。

compresslinenos 是兩個Boolean值,用來控制是否壓縮處理後的CSS代碼以及是否在CSS代碼中保留註釋。

banner 是一個字符串,會被放置在CSS文件的最前面,通常我用來寫註釋,好比

banner: '\/** \n * <%= pkg.name %> - <%= pkg.description %>\n * version <%= pkg.version %> \n * author <%= pkg.author %> \n * date <%= grunt.template.today() %> \n**/\n'

firebug 將控制是否使用一個Firebug的Stylus插件FireStylus for Firebug,能夠在Firefox中調試Stylus。

use 能夠引入一些Stylus的其餘grunt插件。

配合watch等Grunt插件就能夠達到自動化的Stylus開發,寫樣式將會很是有效率。

總結

Stylus是一個由Javascript實現的CSS預處理工具,文件後綴爲styl,其擁有變量、函數、混合、條件及循環語句等功能,還有豐富的內置函數用於處理顏色、數字、數組等數據。在grunt的輔助下,Stylus將帶來極大的開發效率。

原文地址: http://www.tychio.net/tech/2013/11/16/stylus-guide.html

相關文章
相關標籤/搜索