CSS 预处理器 Stylus分享
CSS 預處理器 Stylus分享
ps:為了分享,內容東拼西湊,并非原創,很多參考了 張鑫旭大大翻譯的中文文檔。這里放上兩個不錯的stylus鏈接:
https://github.com/leeseean/stylus-style-guidegithub stylus語法規范
http://blog.hooperui.com/561-2/ 預處理器的作用ect 寫的很好。。
一、簡介
由于原生css有一些缺陷,
一些CSS預處理器應運而生
使用最多的是
變量(variables),代碼混合( mixins),嵌套(nested rules)以及 代碼模塊化(Modules)。
復用,邏輯能力和抽象能力。
Stylus相較于SASS更加簡潔,甚至冒號也都可以省略,初學Stylus時感到它太神奇了,僅僅以空格分隔屬性名和多個屬性值就可以生成想要的CSS,而且還可以拼接字符串等等。與此同時,類似Ruby或Python完善的縮進語法,Stylus在簡約自由中有效的防止了語法歧義。
安裝
npm install stylus --save
例子
Stylus由Javascript編譯,其結構語句也和Javascript相差不多。Stylus較之LESS則要優越不少,不僅僅是可定義變量,如Javascript般的條件語句和循環語句也為Stylus帶來各種可能,加上豐富的內置函數,可以輕松判斷和操作各種變量。而利用這樣的動態性,就可以寫出非常強壯的CSS以滿足不同環境和條件下的需要。
二、從語法和mixin 混合開始
1、& 指向的是父選擇器。
字符&指向父選擇器。下面這個例子,我們兩個選擇器(textarea和input)在:hover偽類選擇器上都改變了color值
textarea
input
color #A7A7A7
&:hover
color #000
等同于:
textarea,
input {
color: #a7a7a7;
}
textarea:hover,
input:hover {
color: #000;
}
2、mixin 混合書寫。混入
先來一段官方描述:如果你發現自己在不停地重復一段樣式,那就應該把這段樣式構造成優良的混合器,尤其是這段樣式本身就是一個邏輯單元。再為其添加一個展示性的描述,能夠清晰明了的看出它是用來干嘛的。
顯然,你首先會想到的是需要各種瀏覽器廠商前綴的CSS3代碼。一個好的事情是,mixin本身不會被編譯到css代碼中。
混入和函數定義方法一致,但是應用卻大相徑庭。
例如,下面有定義的border-radius(n)方法,其卻作為一個mixin(如,作為狀態調用,而非表達式)調用。
當border-radius()選擇器中調用時候,屬性會被擴展并復制在選擇器中。
border-radius(n)
-webkit-border-radius n
-moz-border-radius n
border-radius n
form input[type=button]
border-radius (5px)
標紅括號可以省略。。
也可以把n替換為 arguments 這樣就可以傳遞多個值
如 border-radius 1px 2px / 3px 4px
編譯成
form input[type=button] {
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
}
3、而且在調用時,也不一定要使用括號的形式,可以使用CSS的形式,直接Mixin名加空格然后寫參數。所以有時候可以直接寫一個Mixin來修改CSS屬性的功能,比如看看下面這個兼容所有標準瀏覽器陰影的寫法,可以很方便的為標準調用加上各標準瀏覽器的前綴:
下面這個例子,IE瀏覽器利用了父級引用以及混合書寫來實現2px的邊框。
box-shadow()
-webkit-box-shadow arguments
-moz-box-shadow arguments
box-shadow arguments
html.ie8 &,
html.ie7 &,
html.ie6 &
border 2px solid arguments[length(arguments) - 1]
body
#login
box-shadow 1px 1px 3px #eee
其變身后面目:
body #login {
-webkit-box-shadow: 1px 1px 3px #eee;
-moz-box-shadow: 1px 1px 3px #eee;
box-shadow: 1px 1px 3px #eee;
}
html.ie8 body #login,
html.ie7 body #login,
html.ie6 body #login {
border: 2px solid #eee;
}
可以看到調用時的寫法與一般的寫法一樣,但是因為Mixin的存在,box-shadow不再是一個屬性,可以變成幾行帶有各瀏覽器前綴的CSS。
4、插值
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;
}
不僅僅是box-shadow,CSS3的許多屬性都需要添加前綴~
三、響應式支持
1、變量 可以直接指定表達式的值為變量,可以給變量賦多個值可以組成一個表達式列表
你可以使用"$"符號開始。結尾的分號(;)可有可無,但變量名和變量值之間的等號(=)是需要的。不要用@ (不會賦值)
有了變量,我們不需要為了修改一個顏色而輸入許多次,也不需要為了修改一個寬度去到找尋找他.(我們只需要修改定義好的變量,修改一次就足夠).
font-size = 14px
font = font-size "Lucida Grande", Arial
body
font font sans-serif
編譯為:
body {
font: 14px "Lucida Grande", Arial sans-serif;
}
2、Stylus有另外一個很酷的獨特功能,不需要分配值給變量就可以定義引用屬性。下面是個很好的例子,元素水平垂直居中對齊(典型的方法是使用百分比和margin負值),如下:
簡單地前置@字符在屬性名前來訪問該屬性名對應的值:
#logo
position: absolute
top: 50%
left: 50%
150px
height: 80px
margin-left: -(@width / 2)
margin-top: -(@height / 2)
另外使用案例是基于其他屬性有條件地定義屬性。在下面這個例子中,我們默認指定z-index值為1,但是,只有在z-
index之前未指定的時候才這樣:
position()
position: arguments
z-index: 1 unless @z-index
#logo
z-index: 20
position: absolute
屬性會“向上冒泡”查找堆棧直到被發現,或者返回null(如果屬性搞不定)。下面這個例子,@color被弄成了blue.(父元素之前定義過的blue。)
3、響應式的例子。關于數組的定義,對于響應式來說有非常好的幫助,因為響應式往往是一系列的尺寸或設備,無論如何,使用數組可以輕松的定義多組對應與索引的配套值。
$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- ' + $screen[$i] + ')')
@media $media
responsive($i)
// =>
body {
1600px;
margin-left: 180px;
}
@media screen and (max- 1920px) {
body {
1600px;
margin-left: 180px;
}
}
// ...
@media screen and (max- 320px) {
body {
300px;
margin-left: 0;
}
}
當然響應式不是簡單的改變尺寸,如果你需要控制某些內容的顯示則可以使用一個Boolean的數組來判斷是否顯示,控制結構或樣式則可以字符串的數組來放置一些預先寫好的Mixin名稱。
四、模塊化管理、易維護
當我們在做中、大型項目的時候,往往一個功能或者模塊,會在很多頁面都用到,如果我們把它們單獨的放到所有頁面對應的代碼中,那么每次修改,我們都要去改所有的代碼段,這顯然是低效的,如果將它們放到一個大的公共文件中,有很可能造成冗余,或許,你會說,可以放在一個單獨的文件中,然后引入到頁面中,就行了,這樣是可以,但是會多出來一個文件的請求,如果有多個,那么從維護性和性能兩方面考慮的話,就得不償失了。所以,我們可以使用處理器中的@import規則,把復用代碼段提取,然后在需要的頁面引入,這樣,同樣能達到“一處變、處處變”的效果,而且,不會有多余的請求發出,一個頁面可以只有一個css文件即可。
在CSS中,并不喜歡用@import來導入樣式,因為這樣的做法會增加HTTP的請求。但是在CSS預處理器中的導入(@import)規則和CSS的有所不同,它只是在語義上導入不同的文件,但最終結果是生成一個CSS文件。如果你是通過“@import 'file.css'”導入“file.css”樣式文件,那效果跟普通CSS導入樣式文件一樣。注意:導入文件中定義了變量、混合等信息也將會被引入到主樣式文件中,因此需要避免他們的相互沖突。
--------------------------------------------------
/* file.{type} */
body {
background: #EEE;
}
------------------------------------------------
@import "reset.css";
@import "file.{type}";
p {
background: #0982C1;
}
轉譯后---------------------------------------------
@import "reset.css";
body {
background: #EEE;
}
p {
background: #0982C1;
}
嵌套、繼承
如果我們在CSS中多個元素有一個相同的父元素,那么寫樣式會變得很乏味,我們需要一遍一遍的在每個元素前寫這個父元素.
section {
margin: 10px;
}
section nav {
height: 25px;
}
section nav a {
color: #0982C1;
}
section nav a:hover {
text-decoration: underline;
}
相反,使用CSS預處理器,我們可以在父元素的花括號({})寫這些元素。同時可以使用“&”符號來引用父選擇器。
section {
margin: 10px;
nav {
height: 25px;
a {
color: #0982C1;
&:hover {
text-decoration: underline;
}
}
}
}
Extend 擴展繼承
這可以說是處理器的一個亮點,你定義了一個類,后面如果有另一個類需要用到和已經定義了的類同樣的屬性和值,那么你可以通過@extend來直接引用已經定義的類,來再次使用它定義過的規則。
這樣不會多出來很多重復代碼段嗎?可能你跟我有過同樣的困惑,其實它生成的,是一個群組選擇器,也就是多個類共用一段css樣式規則,這樣做的好處是,在你想定義有共性又有差異的一組元素時,不需要寫多個類,只需要寫它單獨定義的類即可。
在多個元素應用相同的樣式時,我們在CSS通常都是這樣寫:
p,
ul,
ol {
/* 樣式寫在這 */
}
這樣做非常的好,但往往我們需要給單獨元素添加另外的樣式,這個時候我們就需要把其中選擇器單獨出來寫樣式,這樣一回來我們維護樣式就相當的麻煩。為了應對這個問題,CSS預處理器可以從一個選擇繼承另一個選擇器下的所有樣式。
.block {
margin: 10px 5px;
padding: 2px;
}
p {
@extend .block; /* 繼承.block所有樣式 */
border: 1px solid #EEE;
}
ul, ol {
@extend .block; /* 繼承.block所有樣式 */
color: #333;
text-transform: uppercase;
}
轉譯后:
.block, p, ul, ol {
margin: 10px 5px;
padding: 2px;
}
p {
border: 1px solid #EEE;
}
ul, ol {
color: #333;
text-transform: uppercase;
}
五、圖片與色彩的處理
1、切圖
對于CSS Sprite相信是所有切圖者的主要工作產出,以前我也推薦過一些在線的制作Sprite的工具,不過現在有了Stylus。
其中for不同于Javascript,rowList為數組遍歷出的一個元素,而$row為索引,可以這樣理解 `for [value], [index] in [array]` 。所以可以在兩個嵌套的for中獲取縱橫的位置以及國家代碼,來生成CSS。
作為預處理工具,Stylus自然也需要預處理器,不過它不像Sass需要Ruby環境,Stylus由Javascript實現,所以有Javascript就可以處理Stylus。
2、顏色操作
如同其他CSS預處理工具一樣,Stylus在顏色方面也擁有許多內置函數,無論是判斷,提取還是修改都十分強大。函數 `red` , `blue` , `green` , `alpha` 將分別返回顏色對應的rgba值,`dark` 和 `light` 用于判斷顏色屬于亮色還是暗色,`hue` , `saturation` , `lightness` 則分別返回顏色的色相、飽和度以及亮度,其中色相是在色環上的角度,單位是deg。我經常用的是`lighten` 和 `darken` 這兩個函數,其作用是增加或減少一個顏色的亮度,另外還有飽和度的操作函數 `desaturate` 和 `satucate`。
通過增加或減少百分值調整顏色亮度。顏色亮,加;暗,則減。
我們也可以通過增加或減去色度調整色調。例如,紅色增加65deg就變成了黃色。
六、運算符
1、優先級qwq
下標運算符[]允許我們通過索引獲取表達式內部值。括號表達式可以充當元組(如(15px 5px),(1, 2, 3))
下面這個例子使用錯誤處理的元組(并展示了該結構的多功能性):
add(a, b)
if a is a 'unit' and b is a 'unit'
a + b
else
(error 'a 和 b 必須是 units!')
body
padding add(1,'5')
// => padding: error "a 和 b 必須是 units";
padding add(1,'5')[0]
// => padding: error;
padding add(1,'5')[0] == error
// => padding: true;
padding add(1,'5')[1]
// => padding: "a 和 b 必須是 units";
這兒有個更復雜的例子。現在,我們調用內置的error()函數,當標識符(第一個值)等于error的時候返回錯誤信息。
if (val = add(1,'5'))[0] == error
error(val[1])
2、范圍.. ...
同時提供包含界線操作符(..)和范圍操作符(...),見下表達式:
1..5
// => 1 2 3 4 5
1...5
// => 1 2 3 4
3、存在操作符:in
檢查左邊內容是否在右邊的表達式中。
nums = 1 2 3
1 in nums
// => true
4、條件賦值:?= :=
條件賦值操作符?=(別名?:)讓我們無需破壞舊值(如果存在)定義變量。該操作符可以擴展成三元內is defined的二元操作。
color := white
color ?= white
color = color is defined ? color : white
(Is defined 是 是否分配過了值 qwq)
5、方法
函數 函數內方法 標識符 (內置 unit 都換成了px單位 就可以無視單位了)
add(a, b = a)
a = unit(a, px)
b = unit(b, px)
a + b
add(15%, 10deg)
// => 25
可能和 屬性賦值 混淆 那么加個括號 或者加個return
swap(a, b)
return (b a)
條件、別名、參數、哈希等等
下面,我們定義get(hash, key)方法,用來返回key值或null. 我們遍歷每個鍵值對,如果鍵值匹配,返回對應的值。
get(hash, key)
return pair[1] if pair[0] == key for pair in hash
下面例子可以證明,語言函數模樣的Stylus表達式具有更大的靈活性。
hash = (one 1) (two 2) (three 3)
get(hash, two)
// => 2
get(hash, three)
// => 3
get(hash, something)
// => null
七、區別(三者對比
1、變量
2、作用域
3、繼承
Sass和Stylus的繼承非常像,能把一個選擇器的所有樣式繼承到另一個選擇器上。使用『@extend』開始,后面接被繼承的選擇器。
.test{
margin: 10px5px;
padding: 2px;
}
p{
@extend.test;/*繼承.block*/
border: 1pxsolid#aaa;
}
ul,li{
@extend.test; /*繼承.block*/
color: #aaa;
}
將被編譯成標準 css:
.test,p,ul,ol {
margin: 10px5px;
padding:2px;
}
p {
border: 1px solid #aaa
}
ul,li {
color:#aaa;
}
Less 繼承:與前兩者繼承方式有所區別,它不是在選擇器上繼承,而是將Mixins中的樣式嵌套到每個選擇器里面。然而這樣會帶來一個明顯的缺點:每個選擇器中會出現重復的樣式
不管什么原因,如果遇到Stylus搞不定的特殊需求,你可以使用@css使其作為CSS字面量解決之。
Less 的發展有 Bootstrap,Sass 的發展有 Compass
雖然各種預處理器功能強大,但使用最多的,還是以下特性:
變量(variables),代碼混合( mixins),嵌套(nested rules)以及 代碼模塊化(Modules)。
原生的css 也有變量的 后來出的 常常給用來 切換背景色(主題模式)
它不需要經過任何轉譯步驟,因為它是瀏覽器原生支持的 是動態的
它是DOM 的一部分
是 - - 來命名的用兩個“-”開頭表示聲明變量,
如:--white-color: #FFF
用var(...)引用變量值,
如:background: var(--white-color)
總結
以上是生活随笔為你收集整理的CSS 预处理器 Stylus分享的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 为什么有些语言会比别的快?
- 下一篇: 从桌面到移动:异构计算翻天覆地的技术变革