sass起源和簡介
css
其實不是一門程式語言, css
全稱 Cascading Style Sheets
(層疊樣式表)是一種用來表現HTML
(標準通用標記語言的一個應用)或 XML
(標準通用標記語言的一個子集)等檔案樣式的計算機語言。我們用它來實現表現層和結構層的分離,也就是 html
和樣式的分離。你可以用它為網頁制定樣式,但是他無法像 JavaScript
一樣宣告變數,呼叫函式,使用條件語句,可以說 JavaScript
是靈活的,動態的,而 css
是死板的,一成不變的。
所以,有人想要為其加入程式設計的思想,讓他擁有遍歷,擁有方法,甚至擁有繼承,能夠告訴你語法上的錯誤,所以有了css
預處理,它的思想是先用一門新的專門程式設計的語言來設計網頁樣式,再編譯成css
,其實最後引用的仍舊是編譯出來的css
。
說到css
預處理,可能大部分人首先想到的是Less
。現在做css
預處理的語言比較優秀的Less
是其一:它快速方便入門簡單,sass
是其二:相對來說說它更加靈活,語法更多(尤其是if else for
),當然好多人不使用的原因是嫌棄它安裝不方便(還好有淘寶映象),其三是Stylus
:他與sass
比較類似都是更加靈活強大。
想好什麼時候我們可以使用css預處理css
預處理讓我們對樣式的處理更加程式設計化,但是我們仍需要考慮好在怎樣的環境中使用它,因為我們知道,無論你的sass
程式碼多麼炫酷,邏輯多麼縝密,到最後都是生成了一個css
檔案。
所以我們需要根據專案的大小以及開發時間團隊成本來確定,如果專案比較小需要的css
並不是太多並且開發時間緊迫團隊裡很多人還不會使用,那麼可能使用原生的css
可能會更好一些。
sass基礎
安裝
很多開發者原本是想使用sass
的,但是因為sass
是基於ruby
的,牆在上,ruby
裝半天裝不上,於是放棄,這裡推薦使用淘寶的映象來進行安裝。
編譯
學習使用
推薦使用koala, koala
是一個前端前處理器語言圖形編譯工具,支援Less、Sass、Compass、CoffeeScript,幫助web開發者更高效地使用它們進行開發。跨平臺執行,完美相容windows、linux、mac。
如果是學習的話可以先使用koala
來進行除錯,如果使用到現代工程化專案中,推薦使用webpack
安裝配置sass-loader
sass和scss
先來看看區別吧
$color : red;
//sass語法
.box
color:$color;
//scss語法
.box{
color:$color;
}
其實 sass
語法是 sass
最開始的語法結構,是通過 tab
縮排來進行的一個規則,有點類似 jade
模板的那種縮排,而且這種語法規則十分嚴格,有啥不對勁,編譯的時候就報錯。
而 scss
呢,是 sass
的新語法格式,不要認為他是另外一種預處理語言,其實它是 sass
在發現之前的語法結構太過於嚴格,並且和 css
有點不像後重新定製的語法結構,它在外觀上是與css
基本一致的,並且它十分寬鬆,你可以直接將之前的 css
程式碼複製過來。
我在這裡寫在了一個程式碼塊中只是示例,其實他們檔名是分別以 .sass
和 .scss
來結尾的。
變數宣告和呼叫
這是 sass
的程式設計元素基礎之一。在 JS
中我們使用 var
來宣告變數,當然 ES6
中新加了 let const
。而在sass
宣告和呼叫變數的規則如下
$height: 15px !default; //宣告預設變數
$height: 50px; //宣告普通變數
body{
height: $height;
}
變數有預設變數和普通變數之分,預設變數只需像 !important
一樣在值後面加上 !default
即可。其實一般情況下我們只需要宣告普通變數,預設變數在開發元件時使用比較方便。
巢狀和區域性變數,全域性變數
和JS
類似,sass
語法中也有區域性變數和全域性變數。如下在最外層宣告的是全域性變數,全域性範圍內可以呼叫,在em{}
中宣告的是em
的區域性變數,只在em{}
內部內進行呼叫。
$color:#000; //全域性變數
.block {
color: $color;
}
em {
$color: #fff; //區域性變數
a { //選擇器巢狀
color: $color;
font: { //屬性巢狀
size: 12px;
weight: bold;
}
&:hover { //偽類巢狀
color: $color;
}
}
}
資料型別
和JS
類似,sass
也擁有自己的資料型別分別是
數字: 如,1、 2、 13、 10px;
字串:有引號字串或無引號字串,如,"foo"、 'bar'、 baz;
顏色:如,blue、 #04a3f9、 rgba(255,0,0,0.5);
布林型:如,true、 false;
空值:如,null;
值列表:用空格或者逗號分開,如,1.5em 1em 0 2em 、 Helvetica, Arial, sans-serif。
混合巨集
程式設計的思想,混合巨集是一個類似於函式的存在,當然,他並不是函式,簡單來說就是增加引數功能的使得靈活度提升的可重用的程式碼塊。
@mixin border-radius{
-webkit-border-radius: 5px;
border-radius: 5px;
}
button {
@include border-radius;
}
這裡是一個簡單的混合巨集的使用,先是用 @mixin
定義了一個名叫 border-radius
的混合巨集,然後在程式碼中利用 @include
進行呼叫,其實這樣的話並不能太大體現出混合巨集的特色。看下面的
@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);
}
從程式碼裡可以看出,混合巨集可以像函式一樣傳入引數,並且可以像 ES6
的函式擴充套件一樣新增引數預設值,如果在呼叫的時候不傳引數,那麼就會使用預設的值,這樣極大的增加了程式碼的靈活性,省卻很多開發時間。
其實,mixin
的靈活還不僅僅如此,它可以傳入多個引數,這樣我們想到了函式可以根據引數數量的不同來執行不同的程式碼,是的,sass也可以做到。
@mixin size($width,$height){ //兩個引數或者多個引數可以這樣這樣定義
width: $width;
height: $height;
}
.box-center {
@include size(100px,200px);
}
@mixin box-shadow($shadows...){ //引數過多可以使用...來代替
@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));
}
上面兩個程式碼塊第一個比較簡單,就是增加引數數目。下面的程式碼塊我們利用sass
的if else
方法來實現了判斷,如果引數數目大於等於1
,也就是傳了引數,那麼我們執行上面的程式碼,如果沒有傳參我們執行下面的程式碼,設定預設的$shadows
值生成程式碼塊。
但是混合巨集也有不足之處:那就是呼叫一個混合巨集生成的css
程式碼並不會進行合併,這也是因為他能夠傳參所設定的,所以對於複用性很強的程式碼塊不推薦使用混合巨集。
繼承和佔位符
sass
允許你使用@extend
繼承別的程式碼塊,並且通過@extend
所繼承的程式碼塊會在生成css
的時候進行合併~完美解決了上面的問題。
.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
是預先定義好的類,然後我們在.btn-primary1
中繼承他的所有程式碼塊,而%btn2
就是在標題裡所提到的佔位符,佔位符的程式碼塊如果不被繼承在生成的css
中是不會顯示出來的,所以如果你是用sass
編譯css
的話,公共類使用佔位符來定義是一個很不錯的選擇。為了加深理解我們看下上面的程式碼所生成的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
進行了合併,而我們使用佔位符定義的%btn2 %btn3
在生成程式碼裡沒有顯示,因為btn-primary2
繼承了%btn2
,所以他繼承的公共部分被單獨拿出來,如果有多個程式碼塊繼承%btn2
,他們會進行合併。
佔位符還是混合巨集,主要還是看你的程式碼怎麼使用,如果只是靜態的程式碼公共塊,那麼佔位符會比較適合,而如果是可變的程式碼例如寫一個複雜的css3動畫之類的,可能混合巨集比較適合了。
插值#{}
如果接觸過jade
模板的朋友會比較熟悉,這裡的插值和它用法是基本一致的。讓我們來看一個複雜的程式碼塊。
$properties: (margin, padding);
@mixin set-value($side, $value) {
@each $prop in $properties {
#{$prop}-#{$side}: $value;
}
}
.login-box {
@include set-value(top, 14px);
}
首先我們宣告瞭一個$properties
的變數,裡面是一個值列表裡面兩個字串,@mixin
方法裡我們通過@each
方法迴圈出值列表裡面的字串然後利用插值的方法將字串插入進去,我們看下生成的css
程式碼
.login-box {
margin-top: 14px;
padding-top: 14px; }
這裡只是做一個示例,正常情況下我們不會用這麼複雜的方法來生成這麼短的css
程式碼。
運算
sass
允許我們做一些基本的運算:加減乘除,但是我要說的是:注意單位!注意單位!注意單位!當然如果你異想天開em+px,px*px,px/rem.................
需要知道的是sass
裡允許進行顏色運算,也就是說 #222222 * 2
你將會得到 #444444
,其實顏色的運算機制是分段運算也就是說如果22*2 22*2 22*2
然後在進行合併的。
字串運算:
字串可以通過+
來進行連結,需要注意的是因為sass
的字串有兩種型別,帶引號和不帶引號,相同相加當然出來的是一致的。如果有引號的字串被新增了一個沒有引號的字串 (也就是,帶引號的字串在 + 符號左側), 結果會是一個有引號的字串。 同樣的,如果一個沒有引號的字串被新增了一個有引號的字串 (沒有引號的字串在 + 符號左側), 結果將是一個沒有引號的字串,其實就是誰在左邊就跟著誰。
p:before {
content: "Foo " + Bar;
font-family: sans- + "serif";
}
//生成的css如下
p:before {
content: "Foo Bar";
font-family: sans-serif; }
上面的內容就是sass的基礎篇,進階篇的話會整理一下函式和方法規則相關的東西。