文章簡介:其實現在的Sass已經有了兩套文法規則:一個依舊是用縮排作為分隔字元來區分代碼塊的;另一套規則和CSS一樣採用了大括弧({})作為分隔字元。後一種文法規則又名SCSS,在Sass3之後的版本都支援這種文法規則。我們這裡討論的如無特殊說明,全指scss。 |
什麼是sass?
Sass是是一種基於ruby編寫的CSS前置處理器,誕生於2007年,是最早也是最成熟的一款CSS前置處理器語言,它可以使用變數、嵌套、混入、繼承,運算,函數等功能,使得CSS的開發,變得簡單清晰可維護,同時也大大節省了設計者的時間,提高了效率。Sass最後還是會編譯出合法的CSS讓瀏覽器使用,也就是說它本身的文法並不太容易讓瀏覽器識別,因為它不是標準的CSS格式,在它的文法內部可以使用動態變數等,所以它更像一種極簡單的動態語言。
其實現在的Sass已經有了兩套文法規則:一個依舊是用縮排作為分隔字元來區分代碼塊的;另一套規則和CSS一樣採用了大括弧({})作為分隔字元。後一種文法規則又名SCSS,在Sass3之後的版本都支援這種文法規則。我們這裡討論的如無特殊說明,全指scss。
為什麼是sass?
sass雖然是最早的,但是一開始還是不太好用,而且使用縮排作為分隔字元,不符合css使用大括弧的習慣,所以less以後起之秀的身份輕鬆贏得了人心,後來sass借鑒於less的一些思想,改進了自己的設計,並有了scss,然後經過幾個版本的更新,特別版本3.2.0做了些革命性的更新,以使它從其他幾個編譯處理器中脫穎而出。下面我們抽幾個優秀的思想一起看下。
- 預設變數:sass版本3.0引入了預設變數!default,使變數更好控制。
- @content:sass版本3.2.0對mixin進行了補充,以使其可以接受一整塊樣式,大多應用在css3的@media情況下。
- 佔位選取器%:sass版本3.2.0引入了佔位選取器%,對於不傳遞參數的mixin,以後都可以考慮使用它,因為有兩個優點——不調用就不會產生css;解析的css是以組合方式申明的,而不是mixin的拷貝方式。
- 變數參數:sass版本3.2.0對變數參數進行了補充,使其可以設定css3的多個屬性值的參數,如box-shadow,transition它們都可以擁有多個值,並以逗號隔開。而mixin的參數本來就是以逗號分開的,所以這樣一來對css3定義些mixin就會報錯,於是有了變數後面加三個點來表示這個參數是表示可以傳遞多個值的。
目前來說,sass的庫也是最多的,在方便我們學習的同時,也從另一方面表明其優越性。
sass文法
sass有兩種尾碼名檔案:一種尾碼名為sass;另一種就是我們這裡使用的scss檔案,這種和我們平時寫的css檔案格式差不多,使用大括弧包裹的。而本教程中所說的所有sass檔案都指尾碼名為scss的檔案。
匯入
sass的匯入(@import)規則和CSS的有所不同,它只是在語義上匯入不同的檔案,但最終結果是產生一個CSS檔案。但是如果你在sass檔案中匯入css檔案如 @import 'reset.css'
,那效果跟普通CSS匯入樣式檔案一樣,不會合并到一個檔案。然後所有的sass匯入檔案都可以忽略尾碼名.scss
。
PS:一般來說基礎的檔案命名方法以_開頭,如_mixin.scss
。這種檔案在匯入的時候可以不寫底線,如可寫成@import "mixin"
被匯入sass檔案a.scss:
//a.scss //------------------------------- body { background: #eee; }
需要匯入樣式的sass檔案b.scss:
@import "reset.css"; @import "a"; p{ background: #0982c1; }
轉譯出來的b.css樣式:
@import "reset.css"; body { background: #eee; } p{ background: #0982c1; }
根據上面的代碼可以看出,b.scss
編譯後,reset.css
繼續保持import的方式,而a.scss
則被整合進來了。
注釋
sass有兩種注釋方式,一種是標準的css注釋方式/* */
,另一種則是//
雙斜杆形式的單行注釋,不過這種單行注釋不會被轉譯出來。
標準的css注釋
/* *我是css的標準注釋 *設定body內距 */ body{ padding 5px }
//
雙斜杆單行注釋
單行注釋跟JavaScript語言中的注釋一樣,使用又斜杠(//),但單行注釋不會輸入到CSS中。
//我是雙斜杠表示的單行注釋 $mainColor: #369; //定義主體顏色
變數
在sass中你也可以聲明變數,並在整個樣式表中使用。sass支援任何變數(例如:顏色、數值、文本等)。然後你可以在任意地方引用變數。
sass聲明變數必須是$
開頭,後面緊跟變數名,而變數值和變數名之間就需要使用冒號(:)
分隔開(就像CSS屬性設定一樣),如果值後面加上!default
則表示預設值。一般我們定義的變數都為屬性值,可直接使用,當然變數還有另外一種用法,以#{$variables}
形式插入。
//sass style //------------------------------- //聲明變數
$baseLineHeight: 1.6;
$baseFontSize: 14px
!default; $baseLineHeight: 1.5
!default; $bodyBgColor: #fff
!default; $textColor: #333 !default; $borderDirection: top
!default; //調用變數
body { font-size: $baseFontSize; line-height: $baseLineHeight; background-color:$bodyBgColor; color:$textColor; }
.border-#{$borderDirection}{ border-#{$borderDirection}:1px solid #ccc; }
//css style //-------------------------------
body { font-size: 14px; line-height: 1.6; color:#333; background-color:#fff; }
.border-top{ border-top:1px solid #ccc; }
上面的變數我們使用了預設定義,但是對於line-height我們除預設值之外我們又定義了一個,所以實際解析的時候應用了我們重新定義的,而不是預設值。這種設計方案在引入一些基礎sass檔案很受用,我們不必修改引入的基本檔案,而是直接在引入檔案之前,重新定義下我們需要改變的變數就ok了。
除此之外,一個變數可以包含多個值,然後通過nth($variables,index)來調用其中的某個值
//sass style //------------------------------- $linkColor:
#08c #333 !default;//第一個值為預設值,第二個滑鼠滑過值
a{ color:nth($linkColor,1);
&:hover{
color:nth($linkColor,2); } }
//css style //-------------------------------
a{ color:#08c; } a:hover{ color:#333; }
嵌套(Nesting)
sass的嵌套包括兩種:一種是選取器的嵌套;另一種是屬性的嵌套。我們一般說起或用到的都是選取器的嵌套。
選取器嵌套
所謂選取器嵌套指的是在一個選取器中嵌套另一個選取器來實現繼承,從而增加了sass檔案的結構性和可讀性。
在選取器嵌套中,可以使用&
表示父元素選取器
//sass style //-------------------------------
#top_nav{ line-height: 40px;
text-transform: capitalize; background-color:#333;
li{ float:left; } a{ display: block;
padding: 0 10px;
color: #fff;
&:hover{ color:#ddd;
} } } //css style //-------------------------------
#top_nav{
line-height: 40px; text-transform: capitalize; background-color:#333; }
#top_nav li{ float:left; }
#top_nav a{ display: block; padding: 0 10px; color: #fff; }
#top_nav a:hover{ color:#ddd; }
屬性嵌套
所謂屬性嵌套指的是有些屬性擁有同一個開始單詞,如border-width,border-color
都是以border開頭。拿個官網的執行個體看下:
//sass style //-------------------------------
.fakeshadow {
border: { style: solid; left: { width: 4px; color: #888; }
right: { width: 2px; color: #ccc; } } }
//css style //-------------------------------
.fakeshadow { border-style: solid; border-left-width: 4px; border-left-color: #888; border-right-width: 2px; border-right-color: #ccc; }
當然這隻是個屬性嵌套的例子,如果實際這樣使用,那估計得瘋掉。
混合(mixin)
mixin是sass中最強大的特性,他可以將一部分樣式抽出,作為單獨定義的模組,被很多選取器重複使用。在sass中,可以為公用的CSS樣式定義一個mixin,然後在需要使用這些樣式的地方直接調用定義好的mixin。當然mixin最強大的部分還在於它可以傳遞參數。
sass中聲明一個mixins時需要使用@mixin
,然後後面緊跟mixins的名,他也可以定義參數,同時可以給這個參數設定一個預設值,但參數名是使用$
符號開始,而且和參數值之間需要使用冒號(:
)分開,多個參數以逗號分開。這裡又有另外一種情況,那就是如果一個屬性值可以有多個值,如box-shadow和transition等,那麼我們的參數就可以用變數名加三個點表示,如$variables...
。
聲明mixins(@mixin)
//mixin opacity 預設透明度為50% @mixin opacity($opacity:50) { opacity: $opacity / 100; filter: alpha(opacity=$opacity); }
//box-shadow可以有多個值,所以在變數參數後面添加... @mixin box-shadow($shadow...) { -moz-box-shadow:$shadow; box-shadow:$shadow; }
調用mixins(@include)
在選取器調用定義好的mixins需要使用@include
,然後在其後緊跟要調用的mixins名。如果使用預設的參數值,則可以省略括弧。
//sass style //-------------------------------
.opacity{ @include opacity; } .opacity-80{ @include opacity(80); }
.box{ border:1px solid #ccc;
@include box-shadow(0 2px 2px rgba(0,0,0,.3),0 3px 3px rgba(0,0,0,.3),0 4px 4px rgba(0,0,0,.3)); }
#logo{ @include box-shadow(0 5px 5px rgba(0,0,0,.3)); &:hover{ @include opacity; } }
//css style //-------------------------------
.opacity{ opacity:0.5; filter: alpha(opacity=50); }
.opacity-80{ opacity:0.8; filter: alpha(opacity=80); }
.box{ border:1px solid #ccc; -moz-box-shadow:0 2px 2px rgba(0,0,0,.3),0 3px 3px rgba(0,0,0,.3),0 4px 4px rgba(0,0,0,.3);
box-shadow:0 2px 2px rgba(0,0,0,.3),0 3px 3px rgba(0,0,0,.3),0 4px 4px rgba(0,0,0,.3); }
#logo{ -moz-box-shadow:0 5px 5px rgba(0,0,0,.3);
box-shadow:0 5px 5px rgba(0,0,0,.3); }
#logo:hover{ opacity:0.5; filter: alpha(opacity=50); }
從上面執行個體中可以看出:1、opacity和logo hover都調用了@include opacity;
,但是解析出來的樣式並沒有組合聲明;2、box-shadow這個mixin使用了變數後面加三個點來傳遞參數,以適用它可以申明多個值。
@content
又是css3的出現帶來一些麻煩,而@content就是從sass3.2.0開始引入來解決css3的@media樣式麻煩的。它可以使mixin接受一整塊樣式,接受的樣式從@content開始。
//sass style //-------------------------------
@mixin max-screen($res){ @media only screen and ( max-width: $res ) { @content; } }
@include max-screen(480px) { body { color: red } } //css style //-------------------------------
@media only screen and (max-width: 480px) { body { color: red } }
PS:mixin所定義出來的樣式,通過@include調用後解析出來的樣式是以拷貝形式存在的,而下面的繼承是以聯合申明的方式存在的,所以從3.2.0版本以後,建議傳遞參數的用mixin,而非傳遞參數類的使用下面的繼承
繼承
sass中,選取器繼承可以讓選取器繼承另一個選取器的所有樣式,並聯合申明。使用選取器的繼承,要使用關鍵詞@extend
,後面緊跟需要繼承的選取器。
//sass style //-------------------------------
h1{ border: 4px solid #ff9aa9; }
.speaker{ @extend h1; border-width: 2px; }
//css style //-------------------------------
h1,.speaker{ border: 4px solid #ff9aa9; }
.speaker{ border-width: 2px; }
佔位選取器
從sass 3.2.0以後就可以定義佔位選取器%
,這種選取器的優勢在於——如果不調用則不會有任何多餘的css檔案,避免了以前在一些基礎的檔案中預定義了很多基礎的樣式,然後實際應用中不管是否使用了extend去繼承相應的樣式,都會解析出來所有的樣式。佔位選取器以%
標識定義,直接跟名字
//sass style //-------------------------------
%ir{ color: transparent; text-shadow: none; background-color: transparent; border: 0; }
%clearfix{ @if $lte7 { *zoom: 1; } &:before,
&:after { content: ""; display: table; font: 0/0 a; } &:after { clear: both; } }
#header{ h1{ @extend %ir; width:300px; } }
.ir{ @extend %ir; }
//css style //-------------------------------
#header h1, .ir{ color: transparent; text-shadow: none; background-color: transparent; border: 0; }
#header h1{ width:300px; }
如上代碼,定義了兩個佔位選取器%ir
和%clearfix
,其中clearfix這個沒有調用,所以解析出來的css樣式也就沒有clearfix部分。佔位選取器的出現,使css檔案更加簡練可控,沒有多餘。所以以後要定義一些基礎的樣式檔案時候,可以使用佔位選取器。
運算
sass具有運算的特性,可以對數值型的Value
(如:數字、顏色、變數等)進行加減乘除四則運算。請注意運算子前後請留一個空格,不然會出錯。
$baseFontSize: 14px !default; $baseLineHeight: 1.5 !default; $baseGap:
$baseFontSize * $baseLineHeight !default; $halfBaseGap:
$baseGap / 2 !default; $samllFontSize: $baseFontSize - 2px !default;
//grid $_columns: 12 !default;
// Total number of columns $_column-width: 60px !default;
// Width of a single column $_gutter: 20px !default;
// Width of the gutter $_gridsystem-width: $_columns * ($_column-width + $_gutter);
//grid system width
函數
sass定義了很多函數可供使用,當然你也可以自己定義函數,以@fuction開始。sass的官方函數連結為:sass fuction,實際項目中我們使用最多的應該是顏色函數,而顏色函數中又以lighten
減淡和darken
加深為最,其調用方法為lighten($color,$amount)
和darken($color,$amount)
,它們的第一個參數都是顏色值,第二個參數都是百分比。
//sass style //-------------------------------
$baseFontSize: 10px !default; $gray:
#ccc !defualt;
// pixels to rems @function pxToRem($px) { @return $px / $baseFontSize * 1rem; }
body{ font-size:$baseFontSize; color:lighten($gray,10%); }
.test{ font-size:pxToRem(16px); color:darken($gray,10%); }
//css style //-------------------------------
body{ font-size:10px; color:#E6E6E6; } .test{ font-size:1.6rem; color:#B3B3B3; }
關於顏色函數可以在上面提的sass fuction前面的幾個都是顏色方面的函數,分為RGBA Functions,HSL Functions,Opacity Functions,Other Color Functions。建議其他的函數可以瀏覽器下,大概瞭解下有這麼個東西,以後可以方便查閱。
變數範圍
sass的變數範圍比較容易混淆,一句話來說就是——如果定義了個全域變數,然後在某個選取器中重新覆蓋了,那麼後面所有的這個變數都是那個覆蓋的值。而如果沒有在全域裡面定義,只在選取器裡面定義某個變數,外面是無法調用的。還有一種特殊情況就是擁有!default預設值的變數,它會先找全域有沒有重新定義,如果沒有則使用預設值,如有則使用重新定義的值。
//sass style //------------------------------- $color:#fff;
.test{ $color:red; color:$color; } .test2{ color:$color; }
//css style //------------------------------- .test { color: red; } .test2 { color: red; }
從上面可以看出,$color在test裡面重新定義了下,在test2裡面得到的是重新定義後的值,也就是全域變數的$color經過test裡面的局部定義之後,值會改變。這就是很多人所說的sass沒有全域變數和局部變數之分,當然事實並非如此。這裡會給你一個詳細的解答:Sass variable default scope
其他
條件判斷
@if
可一個條件單獨使用,也可以和@else
結合多條件使用
//sass style //-------------------------------
$type: monster; p { @if $type == ocean { color: blue; } @else if $type == matador { color: red; }
@else if $type == monster { color: green; } @else { color: black; } }
//css style //------------------------------- p { color: green; }
for迴圈
for迴圈有兩種形式,分別為:@for $var from <start> through <end>
和@for $var from <start> to <end>
。$i表示變數,start表示起始值,end表示結束值,這兩個的區別是關鍵字through表示包括end這個數,而to則不包括end這個數。
//sass style //-------------------------------
@for $i from 1 through 3 { .item-#{$i} { width: 2em * $i; } }
//css style //-------------------------------
.item-1 { width: 2em; }
.item-2 { width: 4em; } .item-3 { width: 6em; }
sass中的三目判斷
if($condition, $if_true, $if_false)
,三個參數分別表示條件,條件為真的值,條件為假的值。
if(true, 1px, 2px) => 1px if(false, 1px, 2px) => 2px