這是一篇sass基礎(chǔ)知識(shí)總結(jié),從sass的安裝說(shuō)起, 并講解了sass一些常見(jiàn)的函數(shù)。
安裝~咳咳,不得不說(shuō)好多開(kāi)發(fā)者本來(lái)是想使用sass的,但是因?yàn)閟ass是基于ruby的,高墻在上,ruby裝半天裝不上,于是放棄呼。這里推薦你看下W3Cplus的教程使用淘寶的鏡像來(lái)進(jìn)行安裝,包括node的一些包的安裝我都是使用的淘寶鏡像來(lái)進(jìn)行安裝的,很快很強(qiáng)大。
編譯~咳咳,很多朋友安裝完了,但是發(fā)現(xiàn)編譯起來(lái)很麻煩。這里繼續(xù)上鏈接sass編譯教程,我在這里推薦大家使用考拉來(lái)進(jìn)行編譯,雖然考拉已經(jīng)停止更新但是它確實(shí)是十分實(shí)用的,less,sass都可以編譯,而且可以在編譯時(shí)進(jìn)行壓縮。
sass和scss先來(lái)看看區(qū)別吧
$color : red;
//sass語(yǔ)法
.box
color:$color;
//scss語(yǔ)法
.box{
color:$color;
}
其實(shí)sass語(yǔ)法是sass最開(kāi)始的語(yǔ)法結(jié)構(gòu),是通過(guò)tab縮進(jìn)來(lái)進(jìn)行的一個(gè)規(guī)則,有點(diǎn)類(lèi)似jade模板的那種縮進(jìn),而且這種語(yǔ)法規(guī)則十分嚴(yán)格,有啥不對(duì)勁,編譯的時(shí)候就報(bào)錯(cuò)。
而scss呢,是sass的新語(yǔ)法格式,不要認(rèn)為他是另外一種預(yù)處理語(yǔ)言,其實(shí)它是sass在發(fā)現(xiàn)之前的語(yǔ)法結(jié)構(gòu)太過(guò)于嚴(yán)格,并且和css有點(diǎn)不像后重新定制的語(yǔ)法結(jié)構(gòu),它在外觀上是與css基本一致的,并且它十分寬松,你可以直接將之前的css代碼復(fù)制過(guò)來(lái)。
我在這里寫(xiě)在了一個(gè)代碼塊中只是示例,其實(shí)他們文件名是分別以.sass和.scss來(lái)結(jié)尾的。
變量聲明和調(diào)用這是sass的編程元素基礎(chǔ)之一。在JS中我們使用var來(lái)聲明變量,當(dāng)然ES6中新加了let,const。而在sass聲明和調(diào)用變量的規(guī)則如下
$height: 15px !default; //聲明默認(rèn)變量
$height: 50px; //聲明普通變量
body{
height: $height;
}
變量有默認(rèn)變量和普通變量之分,默認(rèn)變量只需像!important 一樣在值后面加上!default即可。其實(shí)一般情況下我們只需要聲明普通變量,默認(rèn)變量在開(kāi)發(fā)組件時(shí)使用比較方便。變量聲明我就不用說(shuō)了,真的很簡(jiǎn)單。
嵌套和局部變量,全局變量和JS類(lèi)似,sass語(yǔ)法中也有局部變量和全局變量。如下在最外層聲明的是全局變量,全局范圍內(nèi)可以調(diào)用,在em{}中聲明的是em的局部變量,只在em{}內(nèi)部?jī)?nèi)進(jìn)行調(diào)用。
$color:#000; //全局變量
.block {
color: $color;
}
em {
$color: #fff; //局部變量
a { //選擇器嵌套
color: $color;
font: { //屬性嵌套
size: 12px;
weight: bold;
}
&:hover { //偽類(lèi)嵌套
color: $color;
}
}
}
和JS類(lèi)似,sass也擁有自己的數(shù)據(jù)類(lèi)型分別是
· 數(shù)字: 如,1、 2、 13、 10px;
· 字符串:有引號(hào)字符串或無(wú)引號(hào)字符串,如,"foo"、 'bar'、 baz;
· 顏色:如,blue、 #04a3f9、 rgba(255,0,0,0.5);
· 布爾型:如,true、 false;
· 空值:如,null;
· 值列表:用空格或者逗號(hào)分開(kāi),如,1.5em 1em 0 2em 、 Helvetica, Arial, sans-serif。
混合宏編程的思想嘛?;旌虾晔且粋€(gè)類(lèi)似于函數(shù)的存在,當(dāng)然,他并不是函數(shù)。簡(jiǎn)單來(lái)說(shuō)就是加了參數(shù)功能的靈活度提升的可重用的代碼塊。
@mixin border-radius{
-webkit-border-radius: 5px;
border-radius: 5px;
}
button {
@include border-radius;}
這里是一個(gè)簡(jiǎn)單的混合宏的使用,先是用@mixin定義了一個(gè)名叫border-radius的混合宏,然后在代碼中利用@include進(jìn)行調(diào)用,其實(shí)這樣的話(huà)并不能太大體現(xiàn)出混合宏的特色。看下面的
@mixin border-radius1($radius){
-webkit-border-radius: $radius;
border-radius: $radius;
}
@mixin border-radius2($radius:5px){
-webkit-border-radius: $radius;
border-radius: $radius;
}
.box1 {
@include border-radius(5px);}
.box2 {
@include border-radius;}
.box2 {
@include border-radius(5px);}
從代碼里可以看出,混合宏可以像函數(shù)一樣傳入?yún)?shù),并且可以像ES6的函數(shù)擴(kuò)展一樣添加參數(shù)默認(rèn)值,如果在調(diào)用的時(shí)候不傳參數(shù),那么就會(huì)使用默認(rèn)的值,這樣極大的增加了代碼的靈活性,省卻很多開(kāi)發(fā)時(shí)間。
其實(shí),mixin的靈活還不僅僅如此,它可以傳入多個(gè)參數(shù),這樣我們想到了函數(shù)可以根據(jù)參數(shù)數(shù)量的不同來(lái)執(zhí)行不同的代碼。yes !sass也可以做到!
@mixin size($width,$height){ //兩個(gè)參數(shù)或者多個(gè)參數(shù)可以這樣這樣定義
width: $width;
height: $height;
}
.box-center {
@include size(100px,200px);}
@mixin box-shadow($shadows...){ //參數(shù)過(guò)多可以使用...來(lái)代替
@if length($shadows) >= 1 {
-webkit-box-shadow: $shadows;
box-shadow: $shadows;
} @else {
$shadows: 0 0 2px rgba(#000,.25);
-webkit-box-shadow: $shadow;
box-shadow: $shadow;
}
}
.box {
@include box-shadow(0 0 1px rgba(#000,.5),0 0 2px rgba(#000,.2));
}
上面兩個(gè)代碼塊第一個(gè)比較簡(jiǎn)單,就是增加參數(shù)數(shù)目。下面的代碼塊我們利用sass的if else方法來(lái)實(shí)現(xiàn)了判斷,如果參數(shù)數(shù)目大于等于1,也就是傳了參數(shù),那么我們執(zhí)行上面的代碼,如果沒(méi)有傳參我們執(zhí)行下面的代碼,設(shè)置默認(rèn)的$shadows值生成代碼塊。
但是混合宏也有不足之處:那就是調(diào)用一個(gè)混合宏生成的css代碼并不會(huì)進(jìn)行合并,這也是因?yàn)樗軌騻鲄⑺O(shè)置的,所以對(duì)于復(fù)用性很強(qiáng)的代碼塊不推薦使用混合宏。
繼承和占位符sass允許你使用@extend繼承別的代碼塊,并且通過(guò)@extend所繼承的代碼塊會(huì)在生成css的時(shí)候進(jìn)行合并~哈哈,完美解決了上面的問(wèn)題
.btn1 {
border: 1px solid #ccc;
padding: 6px 10px;
font-size: 14px;
}
%btn2 {
border: 1px solid #ccc;
padding: 6px 10px;
font-size: 14px;
}
%btn3 {
border: 1px solid #ccc;
padding: 6px 10px;
font-size: 14px;
}
.btn-primary1 {
background-color: #f36;
color: #fff;
@extend .btn1;}
.btn-primary2 {
background-color: #f36;
color: #fff;
@extend %btn2;}
上面的代碼中.btn1是預(yù)先定義好的類(lèi),然后我們?cè)?btn-primary1中繼承他的所有代碼塊,而%btn2就是在標(biāo)題里所提到的占位符,占位符的代碼塊如果不被繼承在生成的css中是不會(huì)顯示出來(lái)的,所以如果你是用sass編譯css的話(huà),公共類(lèi)使用占位符來(lái)定義是一個(gè)很不錯(cuò)的選擇。為了加深理解我們看下上面的代碼所生成的css代碼。
.btn1, .btn-primary1 {
border: 1px solid #ccc;
padding: 6px 10px;
font-size: 14px; }
.btn-primary2 {
border: 1px solid #ccc;
padding: 6px 10px;
font-size: 14px; }
.btn-primary1 {
background-color: #f36;
color: #fff; }
.btn-primary2 {
background-color: #f36;
color: #fff; }
繼承btn1的btn-primary1他和btn1進(jìn)行了合并,而我們使用占位符定義的%btn2,%btn3在生成代碼里沒(méi)有顯示,因?yàn)閎tn-primary2繼承了%btn2,所以他繼承的公共部分被單獨(dú)拿出來(lái),如果有多個(gè)代碼塊繼承%btn2,他們會(huì)進(jìn)行合并。
占位符還是混合宏,主要還是看你的代碼怎么使用,如果只是靜態(tài)的代碼公共塊,那么占位符會(huì)比較適合,而如果是可變的代碼例如寫(xiě)一個(gè)復(fù)雜的css3動(dòng)畫(huà)之類(lèi)的,可能混合宏比較適合了。
插值#{}
如果接觸過(guò)jade模板的朋友會(huì)比較熟悉,這里的插值和它用法是基本一致的。讓我們來(lái)看一個(gè)復(fù)雜的代碼塊
$properties: (margin, padding);
@mixin set-value($side, $value) {
@each $prop in $properties {
#{$prop}-#{$side}: $value;
}
}
.login-box {
@include set-value(top, 14px);}
首先我們聲明了一個(gè)$properties的變量,里面是一個(gè)值列表里面兩個(gè)字符串,@mixin方法里我們通過(guò)@each方法循環(huán)出值列表里面的字符串然后利用插值的方法將字符串插入進(jìn)去,我們看下生成的css代碼
.login-box {
margin-top: 14px;
padding-top: 14px; }
這里只是做一個(gè)示例,正常情況下我們不會(huì)用這么復(fù)雜的方法來(lái)生成這么短的css代碼,那樣才是真正的浪費(fèi)開(kāi)發(fā)時(shí)間,當(dāng)然茶余飯后做個(gè)組件開(kāi)發(fā)的話(huà),還是很有用的。
運(yùn)算sass允許我們做一些基本的運(yùn)算:加減乘除,但是我要說(shuō)的是:注意單位!注意單位!注意單位!當(dāng)然如果你異想天開(kāi)em+px,px*px,px/rem。。。我表示。。。
需要知道的是sass里允許進(jìn)行顏色運(yùn)算,也就是說(shuō) #222222 * 2你將會(huì)得到 #444444,其實(shí)顏色的運(yùn)算機(jī)制是分段運(yùn)算也就是說(shuō)如果22*2 22*2 22*2然后在進(jìn)行合并的。
字符串運(yùn)算:
字符串可以通過(guò)+來(lái)進(jìn)行鏈接,放心減號(hào)是不管用的。。。需要注意的是因?yàn)閟ass的字符串有兩種類(lèi)型,帶引號(hào)和不帶引號(hào),相同相加當(dāng)然出來(lái)的是一致的。如果有引號(hào)的字符串被添加了一個(gè)沒(méi)有引號(hào)的字符串 (也就是,帶引號(hào)的字符串在 + 符號(hào)左側(cè)), 結(jié)果會(huì)是一個(gè)有引號(hào)的字符串。 同樣的,如果一個(gè)沒(méi)有引號(hào)的字符串被添加了一個(gè)有引號(hào)的字符串 (沒(méi)有引號(hào)的字符串在 + 符號(hào)左側(cè)), 結(jié)果將是一個(gè)沒(méi)有引號(hào)的字符串,其實(shí)就是誰(shuí)在左邊就跟著誰(shuí)。
p:before {
content: "Foo " + Bar;
font-family: sans- + "serif";
}
//生成的css如下
p:before {
content: "Foo Bar";
font-family: sans-serif; }
文章來(lái)自:博客園/樓蘭小騎士