css預編譯--sass基礎篇

weixin_33766168發表於2018-05-14

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));
}

上面兩個程式碼塊第一個比較簡單,就是增加引數數目。下面的程式碼塊我們利用sassif 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; }

繼承btn1btn-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的基礎篇,進階篇的話會整理一下函式和方法規則相關的東西。

相關文章