天天看點

Sass的基本特性

1.聲明變量

Sass 聲明變量用美元符号“$”開頭。

Sass 的變量包括三個部分:

  • 聲明變量的符号“$”
  • 變量名稱
  • 賦予變量的值

2.普通變量與預設變量

普通變量 : 定義之後可以在全局範圍内使用。

$fontSize: 12px;
body{
    font-size:$fontSize;
}

//編譯後的css代碼:

body{
    font-size:12px;
}
           

預設變量 : sass 的預設變量僅需要在值後面加上 !default 即可。

$baseLineHeight:1.5 !default;
body{
    line-height: $baseLineHeight; 
}

//編譯後的css代碼:

body{
    line-height:1.5;
}
           

sass 的預設變量一般是用來設定預設值,然後根據需求來覆寫的,覆寫的方式也很簡單,隻需要在預設變量之前重新聲明下變量即可。

$baseLineHeight: 2;
$baseLineHeight: 1.5 !default;
body{
    line-height: $baseLineHeight; 
}

//編譯後的css代碼:

body{
    line-height:2;
}
           

可以看出現在編譯後的 line-height 為 2,而不是我們預設的 1.5。預設變量的價值在進行元件化開發的時候會非常有用。

3.局部變量和全局變量

先來看一下代碼例子:

//SCSS
$color: orange !default;//定義全局變量(在選擇器、函數、混合宏...的外面定義的變量為全局變量)
.block {
  color: $color;//調用全局變量
}
em {
  $color: red;//定義局部變量
  a {
    color: $color;//調用局部變量
  }
}
span {
  color: $color;//調用全局變量
}

//css 的結果:

.block {
  color: orange;
}
em a {
  color: red;
}
span {
  color: orange;
}
           

上面的示例示範可以得知,在元素内部定義的變量不會影響其他元素。如此可以簡單的了解成,全局變量就是定義在元素外面的變量,如下代碼:

$color:orange !default;

$color 就是一個全局變量,而定義在元素内部的變量,比如 $color:red; 是一個局部變量。

基本上,局部變量隻會在局部範圍内覆寫全局變量。

4.嵌套

Sass 中還提供了選擇器嵌套功能,但這也并不意味着你在 Sass 中的嵌套是無節制的,因為你嵌套的層級越深,編譯出來的 CSS 代碼的選擇器層級将越深,這往往是大家不願意看到的一點。這個特性現在正被衆多開發者濫用。

選擇器嵌套為樣式表的作者提供了一個通過局部選擇器互相嵌套實作全局選擇的方法,Sass 的嵌套分為三種:

  • 選擇器嵌套
  • 屬性嵌套
  • 僞類嵌套

選擇器嵌套

假設我們有一段這樣的結構:

<header>
<nav>
    <a href=“##”>Home</a>
    <a href=“##”>About</a>
    <a href=“##”>Blog</a>
</nav>
<header>
           

想選中 header 中的 a 标簽,在寫 CSS 會這樣寫:

nav a {
  color:red;
}

header nav a {
  color:green;
}
           

那麼在 Sass 中,就可以使用選擇器的嵌套來實作:

nav {
  a {
    color: red;

    header & {
      color:green;
    }
  }  
}
           

屬性嵌套

Sass 中還提供屬性嵌套,CSS 有一些屬性字首相同,隻是字尾不一樣,比如:border-top/border-right,與這個類似的還有 margin、padding、font 等屬性。假設你的樣式中用到了:

.box {
    border-top: 1px solid red;
    border-bottom: 1px solid green;
}
           

在 Sass 中我們可以這樣寫:

.box {
  border: {
   top: 1px solid red;
   bottom: 1px solid green;
  }
}
           

僞類嵌套

其實僞類嵌套和屬性嵌套非常類似,隻不過他需要借助

&

符号一起配合使用。我們就拿經典的“clearfix”為例吧:

.clearfix{
&:before,
&:after {
    content:"";
    display: table;
  }
&:after {
    clear:both;
    overflow: hidden;
  }
}

//編譯出來的 CSS:

clearfix:before, .clearfix:after {
  content: "";
  display: table;
}
.clearfix:after {
  clear: both;
  overflow: hidden;
}
           

5.聲明混合宏

如果你的整個網站中有幾處小樣式類似,比如顔色,字型等,在 Sass 可以使用變量來統一處理,那麼這種選擇還是不錯的。但當你的樣式變得越來越複雜,需要重複使用大段的樣式時,使用變量就無法達到我們目了。這個時候 Sass 中的混合宏就會變得非常有意義。

不帶參數混合宏:

在 Sass 中,使用“@mixin”來聲明一個混合宏。如:

@mixin border-radius{
    -webkit-border-radius: 5px;
    border-radius: 5px;
}
           

其中 @mixin 是用來聲明混合宏的關鍵詞,有點類似 CSS 中的 @media、@font-face 一樣。border-radius 是混合宏的名稱。大括号裡面是複用的樣式代碼。

帶參數混合宏:

除了聲明一個不帶參數的混合宏之外,還可以在定義混合宏時帶有參數,如:

@mixin border-radius($radius:5px){
    -webkit-border-radius: $radius;
    border-radius: $radius;
}
           

複雜的混合宏:

上面是一個簡單的定義混合宏的方法,當然, Sass 中的混合宏還提供更為複雜的,你可以在大括号裡面寫上帶有邏輯關系,幫助更好的做你想做的事情,如:

@mixin box-shadow($shadow...) {
  @if length($shadow) >= 1 {
    @include prefixer(box-shadow, $shadow);
  } @else{
    $shadow:0 0 4px rgba(0,0,0,.3);
    @include prefixer(box-shadow, $shadow);
  }
}
           

這個 box-shadow 的混合宏,帶有多個參數,這個時候可以使用“ … ”來替代。簡單的解釋一下,當 $shadow 的參數數量值大于或等于“ 1 ”時,表示有多個陰影值,反之調用預設的參數值“ 0 0 4px rgba(0,0,0,.3) ”。

6.調用混合宏

在 Sass 中通過 @mixin 關鍵詞聲明了一個混合宏,那麼在實際調用中,其比對了一個關鍵詞“@include”來調用聲明好的混合宏。例如在你的樣式中定義了一個圓角的混合宏“border-radius”:

@mixin border-radius{
    -webkit-border-radius: 3px;
    border-radius: 3px;
}
           

在一個按鈕中要調用定義好的混合宏“border-radius”,可以這樣使用:

button {
    @include border-radius;
}

//這個時候編譯出來的 CSS:

button {
  -webkit-border-radius: 3px;
  border-radius: 3px;
}
           

7.混合宏的參數

Sass 的混合宏有一個強大的功能,可以傳參,那麼在 Sass 中傳參主要有以下幾種情形:

傳一個不帶值的參數

在混合宏中,可以傳一個不帶任何值的參數,比如:

@mixin border-radius($radius){
  -webkit-border-radius: $radius;
  border-radius: $radius;
}
           

在混合宏“border-radius”中定義了一個不帶任何值的參數“$radius”。

在調用的時候可以給這個混合宏傳一個參數值:

.box {
  @include border-radius(3px);
}
           

這裡表示給混合宏傳遞了一個“border-radius”的值為“3px”。

編譯出來的 CSS:

.box {
  -webkit-border-radius: 3px;
  border-radius: 3px;
}
           

傳一個帶值的參數

在 Sass 的混合宏中,還可以給混合宏的參數傳一個預設值,例如:

@mixin border-radius($radius:3px){
  -webkit-border-radius: $radius;
  border-radius: $radius;
}
           

在混合宏“border-radius”傳了一個參數“$radius”,而且給這個參數賦予了一個預設值“3px”。

在調用類似這樣的混合宏時,會多有一個機會,假設你的頁面中的圓角很多地方都是“3px”的圓角,那麼這個時候隻需要調用預設的混合宏“border-radius”:

.btn {
  @include border-radius;
}

//編譯出來的 CSS:

.btn {
  -webkit-border-radius: 3px;
  border-radius: 3px;
}
           

但有的時候,頁面中有些元素的圓角值不一樣,那麼可以随機給混合宏傳值,如:

.box {
  @include border-radius(50%);
}

//編譯出來的 CSS:

.box {
  -webkit-border-radius: 50%;
  border-radius: 50%;
}
           

傳多個參數

Sass 混合宏除了能傳一個參數之外,還可以傳多個參數,如:

@mixin center($width,$height){
  width: $width;
  height: $height;
  position: absolute;
  top: 50%;
  left: 50%;
  margin-top: -($height) / 2;
  margin-left: -($width) / 2;
}
           

在混合宏“center”就傳了多個參數。在實際調用和其調用其他混合宏是一樣的:

.box-center {
  @include center(500px,300px);
}

//編譯出來 CSS:

.box-center {
  width: 500px;
  height: 300px;
  position: absolute;
  top: 50%;
  left: 50%;
  margin-top: -150px;
  margin-left: -250px;
}
           

有一個特别的參數“…”。當混合宏傳的參數過多之時,可以使用參數來替代,如:

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

//編譯出來的CSS:

.box {
  -webkit-box-shadow: 0 0 1px rgba(0, 0, 0, 0.5), 0 0 2px rgba(0, 0, 0, 0.2);
  box-shadow: 0 0 1px rgba(0, 0, 0, 0.5), 0 0 2px rgba(0, 0, 0, 0.2);
}
           

混合宏的不足

混合宏在實際編碼中給我們帶來很多友善之處,特别是對于複用重複代碼塊。但其最大的不足之處是會生成備援的代碼塊。比如在不同的地方調用一個相同的混合宏時。

8.擴充/繼承

在 Sass 中也有繼承一說,也是繼承類中的樣式代碼塊。在 Sass 中是通過關鍵詞 “@extend”來繼承已存在的類樣式塊,進而實作代碼的繼承。如下所示:

//SCSS
.btn {
  border: 1px solid #ccc;
  padding: 6px 10px;
  font-size: 14px;
}

.btn-primary {
  background-color: #f36;
  color: #fff;
  @extend .btn;
}

.btn-second {
  background-color: orange;
  color: #fff;
  @extend .btn;
}
           

編譯出來之後:

//CSS
.btn, .btn-primary, .btn-second {
  border: 1px solid #ccc;
  padding: 6px 10px;
  font-size: 14px;
}

.btn-primary {
  background-color: #f36;
  color: #fff;
}

.btn-second {
  background-clor: orange;
  color: #fff;
}
           

從示例代碼可以看出,在 Sass 中的繼承,可以繼承類樣式塊中所有樣式代碼,而且編譯出來的 CSS 會将選擇器合并在一起,形成組合選擇器:

.btn, .btn-primary, .btn-second {
  border: 1px solid #ccc;
  padding: 6px 10px;
  font-size: 14px;
}
           

9.占位符 %placeholder

Sass 中的占位符 %placeholder 功能是一個很強大,很實用的一個功能,這也是我非常喜歡的功能。他可以取代以前 CSS 中的基類造成的代碼備援的情形。因為 %placeholder 聲明的代碼,如果不被 @extend 調用的話,不會産生任何代碼。來看一個示範:

%mt5 {
  margin-top: 5px;
}
%pt5{
  padding-top: 5px;
}
           

這段代碼沒有被 @extend 調用,他并沒有産生任何代碼塊,隻是靜靜的躺在你的某個 SCSS 檔案中。隻有通過 @extend 調用才會産生代碼:

//SCSS
%mt5 {
  margin-top: 5px;
}
%pt5{
  padding-top: 5px;
}

.btn {
  @extend %mt5;
  @extend %pt5;
}

.block {
  @extend %mt5;

  span {
    @extend %pt5;
  }
}
           

編譯出來的CSS:

//CSS
.btn, .block {
  margin-top: 5px;
}

.btn, .block span {
  padding-top: 5px;
}
           

從編譯出來的 CSS 代碼可以看出,通過 @extend 調用的占位符,編譯出來的代碼會将相同的代碼合并在一起。這也是我們希望看到的效果,也讓你的代碼變得更為幹淨。

10.混合宏 VS 繼承 VS 占位符

  • 混合宏: 不會自動合并相同的樣式代碼,如果在樣式檔案中調用同一個混合宏,會産生多個對應的樣式代碼,造成代碼的備援。不過他可以傳參數。
  • 建議: 如果代碼塊中涉及到變量,建議使用混合宏來建立相同的代碼塊。
  • 繼承: 使用繼承後,編譯出來的 CSS 會将使用繼承的代碼塊合并到一起,通過組合選擇器的方式向大家展現,比如 .mt, .block, .block span, .header, .header span。這樣編譯出來的代碼相對于混合宏來說要幹淨的多。但是他不能傳變量參數。
  • 建議: 如果代碼塊不需要專任何變量參數,而且有一個基類已在檔案中存在,那麼建議使用 Sass 的繼承。
  • 占位符: 編譯出來的 CSS 代碼和使用繼承基本上是相同,隻是不會在代碼中生成占位符 mt 的選擇器。那麼占位符和繼承的主要差別的,“占位符是獨立定義,不調用的時候是不會在 CSS 中産生任何代碼;繼承是首先有一個基類存在,不管調用與不調用,基類的樣式都将會出現在編譯出來的 CSS 代碼中。”
    Sass的基本特性

11.注釋

在 Sass 中注釋有兩種方式,我暫且将其命名為:

  • 1.類似 CSS 的注釋方式,使用 ” ”
  • 2.類似 JavaScript 的注釋方式,使用“//”

兩者差別,前者會在編譯出來的 CSS 顯示,後者在編譯出來的 CSS 中不會顯示,來看一個示例:

//定義一個占位符

%mt5 {
  margin-top: 5px;
}

/*調用一個占位符*/

.box {
  @extend %mt5;
}
           

編譯出來的CSS:

.box {
  margin-top: 5px;
}

/*調用一個占位符*/
           

12.資料類型

Sass 和 JavaScript 語言類似,也具有自己的資料類型,在 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。

SassScript 也支援其他 CSS 屬性值(property value),比如 Unicode 範圍,或 !important 聲明。然而,Sass 不會特殊對待這些屬性值,一律視為無引号字元串 (unquoted strings)。

13.值清單

所謂值清單 (lists) 是指 Sass 如何處理 CSS 中:

margin: 10px 15px 0 0
           

或者:

font-face: Helvetica, Arial, sans-serif
           

像上面這樣通過空格或者逗号分隔的一系列的值。

事實上,獨立的值也被視為值清單——隻包含一個值的值清單。

Sass清單函數(Sass list functions)賦予了值清單更多功能(Sass進級會有講解):

  • nth函數(nth function) 可以直接通路值清單中的某一項;
  • join函數(join function) 可以将多個值清單連結在一起;
  • append函數(append function) 可以在值清單中添加值;
  • @each規則(@each rule) 則能夠給值清單中的每個項目添加樣式。

值清單中可以再包含值清單,比如 1px 2px, 5px 6px 是包含 1px 2px 與 5px 6px 兩個值清單的值清單。如果内外兩層值清單使用相同的分隔方式,要用圓括号包裹内層,是以也可以寫成 (1px 2px) (5px 6px)。當值清單被編譯為 CSS 時,Sass 不會添加任何圓括号,因為 CSS 不允許這樣做。(1px 2px) (5px 6px)與 1px 2px 5px 6px 在編譯後的 CSS 檔案中是一樣的,但是它們在 Sass 檔案中卻有不同的意義,前者是包含兩個值清單的值清單,而後者是包含四個值的值清單。

可以用 () 表示空的清單,這樣不可以直接編譯成 CSS,比如編譯 font-family: ()時,Sass 将會報錯。如果值清單中包含空的值清單或空值,編譯時将清除空值,比如 1px 2px () 3px 或 1px 2px null 3px。