Sass 入門(基本特性-基礎(chǔ))

聲明變量


定義變量的語(yǔ)法:

在有些編程語(yǔ)言中(如,JavaScript)聲明變量都是使用關(guān)鍵詞“var”開(kāi)頭,但是在 Sass 不使用這個(gè)關(guān)鍵詞,而是使用大家都喜歡的美元符號(hào)“$”開(kāi)頭。我想用一張圖來(lái)解釋,我一直堅(jiān)信,一圖勝千言萬(wàn)語(yǔ):


示列圖

來(lái)看一個(gè)簡(jiǎn)單的示例,假設(shè)你的按鈕顏色可以給其聲明幾個(gè)變量:

$brand-primary : darken(#428bca, 6.5%) !default; // #337ab7
$btn-primary-color : #fff !default;
$btn-primary-bg : $brand-primary !default;
$btn-primary-border : darken($btn-primary-bg, 5%) !default;

如果值后面加上!default則表示默認(rèn)值。

注:了解 Bootstrap 的 Sass 版本的同學(xué),就一眼能看出,上面的示例代碼是 Bootstrap 定義 primarybutton 的顏色。

普通變量與默認(rèn)變量


普遍變量

定義之后可以在全局范圍內(nèi)使用。

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

編譯后的css代碼:

body{
    font-size:12px;
}

默認(rèn)變量

sass的默認(rèn)變量?jī)H需要在值后面加上 !default即可。

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

編譯后的css 代碼:

body{
    line-height:1.5;
}

sass 的默認(rèn)變量一般是用來(lái)設(shè)置默認(rèn)值,然后根據(jù)需求來(lái)覆蓋的,覆蓋的方式也很簡(jiǎn)單,只需要在默認(rèn)變量之前重新聲明下變量即可。

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

編譯后的css代碼:

body{
    line-height:2;
}

可以看出現(xiàn)在編譯后的 line-height 為 2,而不是我們默認(rèn)的 1.5。默認(rèn)變量的價(jià)值在進(jìn)行組件化開(kāi)發(fā)的時(shí)候會(huì)非常有用。

變量的調(diào)用


定義聲明好變量

$brand-primary : darken(#428bca, 6.5%) !default; // #337ab7
$btn-primary-color: #fff !default;
$btn-primary-bg : $brand-primary !default;
$btn-primary-border : darken($btn-primary-bg, 5%) !default;

在按鈕button 中調(diào)用

.btn-primary {
   background-color: $btn-primary-bg;
   color: $btn-primary-color;
   border: 1px solid $btn-primary-border;
}

編譯出來(lái)后的css:

.btn-primary {
  background-color: #337ab7;
  color: #fff;
  border: 1px solid #2e6da4;
}

局部變量和全局變量


代碼例子:

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

css 的結(jié)果:

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

上面的示例演示可以得知,在元素內(nèi)部定義的變量不會(huì)影響其他元素。如此可以簡(jiǎn)單的理解成,全局變量就是定義在元素外面的變量,如上代碼第一句:

$color:orange !default;

$color 就是一個(gè)全局變量,而定義在元素內(nèi)部的變量,比如 $color:red; 是一個(gè)局部變量

除此之外,Sass 現(xiàn)在還提供一個(gè) !global 參數(shù)。!global 和 !default 對(duì)于定義變量都是很有幫助的。我們之后將會(huì)詳細(xì)介紹這兩個(gè)參數(shù)的使用以及其功能。

全局變量的影子
當(dāng)在局部范圍(選擇器內(nèi)、函數(shù)內(nèi)、混合宏內(nèi)...)聲明一個(gè)已經(jīng)存在于全局范圍內(nèi)的變量時(shí),局部變量就成為了全局變量的影子。基本上,局部變量只會(huì)在局部范圍內(nèi)覆蓋全局變量
上面例子中的 em 選擇器內(nèi)的變量 $color 就是一個(gè)全局變量的影子。

//SCSS
$color: orange !default;//定義全局變量
.block {
  color: $color;//調(diào)用全局變量
}
em {
  $color: red;//定義局部變量(全局變量 $color 的影子)
  a {
    color: $color;//調(diào)用局部變量
  }
}

什么時(shí)候聲明變量?
我的建議,創(chuàng)建變量只適用于感覺(jué)確有必要的情況下。不要為了某些駭客行為而聲明新變量,這絲毫沒(méi)有作用。只有滿足所有下述標(biāo)準(zhǔn)時(shí)方可創(chuàng)建新變量:

 * 該值至少重復(fù)出現(xiàn)了兩次;
 * 該值至少可能會(huì)被更新一次;
 * 該值所有的表現(xiàn)都與變量有關(guān)(非巧合)。

基本上,沒(méi)有理由聲明一個(gè)永遠(yuǎn)不需要更新或者只在單一地方使用變量。

溫馨小提示:您在學(xué)習(xí) sass 時(shí),除了在我們網(wǎng)頁(yè)上可以做練習(xí),還有一個(gè)便利在線編輯器網(wǎng)址如下:

http://sassmeister.com/

嵌套-選擇器嵌套


Sass 中還提供了選擇器嵌套功能,但這也并不意味著你在 Sass 中的嵌套是無(wú)節(jié)制的,因?yàn)槟闱短椎膶蛹?jí)越深,編譯出來(lái)的 CSS 代碼的選擇器層級(jí)將越深,這往往是大家不愿意看到的一點(diǎn)。這個(gè)特性現(xiàn)在正被眾多開(kāi)發(fā)者濫用。

選擇器嵌套為樣式表的作者提供了一個(gè)通過(guò)局部選擇器相互嵌套實(shí)現(xiàn)全局選擇的方法,Sass 的嵌套分為三種:
* 選擇器嵌套
* 屬性嵌套
* 偽類嵌套

1、選擇器嵌套

假設(shè)我們有一段這樣的結(jié)構(gòu):

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

想選中 header 中的 a 標(biāo)簽,在寫(xiě) CSS 會(huì)這樣寫(xiě):

  nav a {
  color:red;
}

header nav a {
  color:green;
}

那么在 Sass 中,就可以使用選擇器的嵌套來(lái)實(shí)現(xiàn):

nav {
  a {
    color: red;

    header & {
      color:green;
    }
  }  
}

嵌套-屬性嵌套


Sass 中還提供屬性嵌套,CSS 有一些屬性前綴相同,只是后綴不一樣,比如:border-top/border-right,與這個(gè)類似的還有 margin、padding、font 等屬性。假設(shè)你的樣式中用到了:

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

在 Sass 中我們可以這樣寫(xiě):

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

嵌套-偽類嵌套


其實(shí)偽類嵌套和屬性嵌套非常類似,只不過(guò)他需要借助&符號(hào)一起配合使用。我們就拿經(jīng)典的“clearfix”為例吧:

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

編譯出來(lái)的 CSS:

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

避免選擇器嵌套:

  • 選擇器嵌套最大的問(wèn)題是將使最終的代碼難以閱讀。開(kāi)發(fā)者需要花費(fèi)巨大精力計(jì)算不同縮進(jìn)級(jí)別下的選擇器具體的表現(xiàn)效果。
  • 選擇器越具體則聲明語(yǔ)句越冗長(zhǎng),而且對(duì)最近選擇器的引用(&)也越頻繁。在某些時(shí)候,出現(xiàn)混淆選擇器路徑和探索下一級(jí)選擇器的錯(cuò)誤率很高,這非常不值得。

混合宏-聲明混合宏


如果你的整個(gè)網(wǎng)站中有幾處小樣式類似,比如顏色,字體等,在 Sass 可以使用變量來(lái)統(tǒng)一處理,那么這種選擇還是不錯(cuò)的。但當(dāng)你的樣式變得越來(lái)越復(fù)雜,需要重復(fù)使用大段的樣式時(shí),使用變量就無(wú)法達(dá)到我們目了。這個(gè)時(shí)候 Sass 中的混合宏就會(huì)變得非常有意義。在這一節(jié)中,主要向大家介紹 Sass 的混合宏。

1、聲明混合宏
在 Sass 中,使用“@mixin”來(lái)聲明一個(gè)混合宏

不帶參數(shù)混合宏

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

其中 @mixin 是用來(lái)聲明混合宏的關(guān)鍵詞,有點(diǎn)類似 CSS 中的 @media、@font-face 一樣。border-radius 是混合宏的名稱。大括號(hào)里面是復(fù)用的樣式代碼。

帶參數(shù)混合宏

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

復(fù)雜的混合宏:
帶有邏輯關(guān)系

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

這個(gè) box-shadow 的混合宏,帶有多個(gè)參數(shù),這個(gè)時(shí)候可以使用“… ”來(lái)替代。簡(jiǎn)單的解釋一下,當(dāng) $shadow 的參數(shù)數(shù)量值大于或等于“ 1 ”時(shí),表示有多個(gè)陰影值,反之調(diào)用默認(rèn)的參數(shù)值“ 0 0 4px rgba(0,0,0,.3) ”。
注:復(fù)雜的混合宏中的邏輯關(guān)系(@if...@else)后面小節(jié)會(huì)有講解。

混合宏-調(diào)用混合宏


在 Sass 中通過(guò) @mixin 關(guān)鍵詞聲明了一個(gè)混合宏,那么在實(shí)際調(diào)用中,其匹配了一個(gè)關(guān)鍵詞“@include”來(lái)調(diào)用聲明好的混合宏。例如在你的樣式中定義了一個(gè)圓角的混合宏“border-radius”:

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

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

button {
    @include border-radius;
}

這個(gè)時(shí)候編譯出來(lái)的 CSS:

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

混合宏的參數(shù)--傳一個(gè)不帶值的參數(shù)


Sass 的混合宏有一個(gè)強(qiáng)大的功能,可以傳參,那么在 Sass 中傳參主要有以下幾種情形:

A) 傳一個(gè)不帶值的參數(shù)

在混合宏中,可以傳一個(gè)不帶任何值的參數(shù),比如:

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

在混合宏“border-radius”中定義了一個(gè)不帶任何值的參數(shù)“$radius”。
在調(diào)用的時(shí)候可以給這個(gè)混合宏傳一個(gè)參數(shù)值:

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

這里表示給混合宏傳遞了一個(gè)“border-radius”的值為“3px”。

編譯出來(lái)的 CSS:

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

混合宏的參數(shù)--傳一個(gè)帶值的參數(shù)


在 Sass 的混合宏中,還可以給混合宏的參數(shù)傳一個(gè)默認(rèn)值,例如:

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

在混合宏“border-radius”傳了一個(gè)參數(shù)“$radius”,而且給這個(gè)參數(shù)賦予了一個(gè)默認(rèn)值“3px”。

在調(diào)用類似這樣的混合宏時(shí),會(huì)多有一個(gè)機(jī)會(huì),假設(shè)你的頁(yè)面中的圓角很多地方都是“3px”的圓角,那么這個(gè)時(shí)候只需要調(diào)用默認(rèn)的混合宏“border-radius”:

.btn {
  @include border-radius;
}

編譯出來(lái)的 CSS:

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

但有的時(shí)候,頁(yè)面中有些元素的圓角值不一樣,那么可以隨機(jī)給混合宏傳值,如:

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

編譯出來(lái)的 CSS:

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

混合宏的參數(shù)--傳多個(gè)參數(shù)


Sass 混合宏除了能傳一個(gè)參數(shù)之外,還可以傳多個(gè)參數(shù),如:

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

在混合宏“center”就傳了多個(gè)參數(shù)。在實(shí)際調(diào)用和其調(diào)用其他混合宏是一樣的:

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

編譯出來(lái) CSS:

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

有一個(gè)特別的參數(shù)“”。當(dāng)混合宏傳的參數(shù)過(guò)多之時(shí),可以使用參數(shù)來(lái)替代,如:

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

在實(shí)際調(diào)用中:

.box {
  @include box-shadow(0 0 1px rgba(#000,.5),0 0 2px rgba(#000,.2));

編譯出來(lái)的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);
}

混合宏的參數(shù)--混合宏的不足


混合宏在實(shí)際編碼中給我們帶來(lái)很多方便之處,特別是對(duì)于復(fù)用重復(fù)代碼塊。但其最大的不足之處是會(huì)生成冗余的代碼塊。比如在不同的地方調(diào)用一個(gè)相同的混合宏時(shí)。如:

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

.box {
  @include border-radius;
  margin-bottom: 5px;
}

.btn {
  @include border-radius;
}

示例在“.box”和“.btn”中都調(diào)用了定義好的“border-radius”混合宏。先來(lái)看編譯出來(lái)的 CSS:

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

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

上例明顯可以看出,Sass 在調(diào)用相同的混合宏時(shí),并不能智能的將相同的樣式代碼塊合并在一起。這也是 Sass 的混合宏最不足之處。

擴(kuò)展/繼承


繼承對(duì)于了解 CSS 的同學(xué)來(lái)說(shuō)一點(diǎn)都不陌生,先來(lái)看一張圖:


繼承圖

圖中代碼顯示“.col-sub .block li,.col-extra .block li” 繼承了 “.item-list ul li”選擇器的 “padding : 0;” 和 “ul li” 選擇器中的 “l(fā)ist-style : none outside none;”以及 * 選擇器中的 “box-sizing:inherit;”。

在 Sass 中也具有繼承一說(shuō),也是繼承類中的樣式代碼塊。在 Sass 中是通過(guò)關(guān)鍵詞 “@extend”來(lái)繼承已存在的類樣式塊,從而實(shí)現(xiàn)代碼的繼承。如下所示:

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

編譯出來(lái)之后:

//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 中的繼承,可以繼承類樣式塊中所有樣式代碼,而且編譯出來(lái)的 CSS 會(huì)將選擇器合并在一起,形成組合選擇器:

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

占位符 %placeholder


Sass 中的占位符 %placeholder 功能是一個(gè)很強(qiáng)大,很實(shí)用的一個(gè)功能,這也是我非常喜歡的功能。他可以取代以前 CSS 中的基類造成的代碼冗余的情形。因?yàn)?%placeholder 聲明的代碼,如果不被 @extend 調(diào)用的話,不會(huì)產(chǎn)生任何代碼。來(lái)看一個(gè)演示:

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

這段代碼沒(méi)有被 @extend 調(diào)用,他并沒(méi)有產(chǎn)生任何代碼塊,只是靜靜的躺在你的某個(gè) SCSS 文件中。只有通過(guò) @extend 調(diào)用才會(huì)產(chǎn)生代碼:

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

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

.block {
  @extend %mt5;

  span {
    @extend %pt5;
  }
}

編譯出來(lái)的CSS:

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

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

從編譯出來(lái)的 CSS 代碼可以看出,通過(guò) @extend 調(diào)用的占位符,編譯出來(lái)的代碼會(huì)將相同的代碼合并在一起。這也是我們希望看到的效果,也讓你的代碼變得更為干凈。

混合宏 VS 繼承 VS 占位符


初學(xué)者都常常糾結(jié)于這個(gè)問(wèn)題“什么時(shí)候用混合宏,什么時(shí)候用繼承,什么時(shí)候使用占位符?”其實(shí)他們各有各的優(yōu)點(diǎn)與缺點(diǎn),先來(lái)看看他們使用效果:

//SCSS中混合宏使用
@mixin mt($var){
  margin-top: $var;  
}

.block {
  @include mt(5px);

  span {
    display:block;
    @include mt(5px);
  }
}

.header {
  color: orange;
  @include mt(5px);

  span{
    display:block;
    @include mt(5px);
  }
}

//SCSS 繼承的運(yùn)用
.mt{
  margin-top: 5px;  
}

.block {
  @extend .mt;

  span {
    display:block;
    @extend .mt;
  }
}

.header {
  color: orange;
  @extend .mt;

  span{
    display:block;
    @extend .mt;
  }
}

//SCSS中占位符的使用
%mt{
  margin-top: 5px;  
}

.block {
  @extend %mt;

  span {
    display:block;
    @extend %mt;
  }
}

.header {
  color: orange;
  @extend %mt;

  span{
    display:block;
    @extend %mt;
  }
}

a) Sass 中的混合宏使用

  舉例代碼見(jiàn)上面 2-24 行

.block {

  margin-top: 5px; }

  .block span {

    display: block;

    margin-top: 5px; }



.header {

  color: orange;

  margin-top: 5px; }

  .header span {

    display: block;

    margin-top: 5px; }

總結(jié):編譯出來(lái)的 CSS 清晰告訴了大家,他不會(huì)自動(dòng)合并相同的樣式代碼,如果在樣式文件中調(diào)用同一個(gè)混合宏,會(huì)產(chǎn)生多個(gè)對(duì)應(yīng)的樣式代碼,造成代碼的冗余,這也是 CSSer 無(wú)法忍受的一件事情。不過(guò)他并不是一無(wú)事處,他可以傳參數(shù)。

個(gè)人建議:如果你的代碼塊中涉及到變量,建議使用混合宏來(lái)創(chuàng)建相同的代碼塊。

b) Sass 中繼承

同樣的,將上面代碼中的混合宏,使用類名來(lái)表示,然后通過(guò)繼承來(lái)調(diào)用:

 代碼見(jiàn)右側(cè) 26-48 行

.mt, .block, .block span, .header, .header span {

  margin-top: 5px; }



.block span {

  display: block; }



.header {

  color: orange; }

  .header span {

    display: block; }

總結(jié):使用繼承后,編譯出來(lái)的 CSS 會(huì)將使用繼承的代碼塊合并到一起,通過(guò)組合選擇器的方式向大家展現(xiàn),比如 .mt, .block, .block span, .header, .header span。這樣編譯出來(lái)的代碼相對(duì)于混合宏來(lái)說(shuō)要干凈的多,也是 CSSer 期望看到。但是他不能傳變量參數(shù)。

個(gè)人建議:如果你的代碼塊不需要專任何變量參數(shù),而且有一個(gè)基類已在文件中存在,那么建議使用 Sass 的繼承。

c) 占位符

最后來(lái)看占位符,將上面代碼中的基類 .mt 換成 Sass 的占位符格式:

  代碼見(jiàn) 50-72 行

  .block, .block span, .header, .header span {

  margin-top: 5px; }



.block span {

  display: block; }



.header {

  color: orange; }

  .header span {

    display: block; }

總結(jié):編譯出來(lái)的 CSS 代碼和使用繼承基本上是相同,只是不會(huì)在代碼中生成占位符 mt 的選擇器。那么占位符和繼承的主要區(qū)別的,“占位符是獨(dú)立定義,不調(diào)用的時(shí)候是不會(huì)在 CSS 中產(chǎn)生任何代碼;繼承是首先有一個(gè)基類存在,不管調(diào)用與不調(diào)用,基類的樣式都將會(huì)出現(xiàn)在編譯出來(lái)的 CSS 代碼中。”

來(lái)看一個(gè)表格,關(guān)系說(shuō)明圖:

關(guān)系圖

插值#{}


使用 CSS 預(yù)處理器語(yǔ)言的一個(gè)主要原因是想使用 Sass 獲得一個(gè)更好的結(jié)構(gòu)體系。比如說(shuō)你想寫(xiě)更干凈的、高效的和面向?qū)ο蟮?CSS。Sass 中的插值(Interpolation)就是重要的一部分。讓我們看一下下面的例子:

$properties: (margin, padding);
@mixin set-value($side, $value) {
    @each $prop in $properties {
        #{$prop}-#{$side}: $value;
    }
}
.login-box {
    @include set-value(top, 14px);
}

@each...in...語(yǔ)句會(huì)在《Sass進(jìn)級(jí)篇》中 1-6 @each循環(huán) 中講解。
它可以讓變量和屬性工作的很完美,上面的代碼編譯成 CSS:

 .login-box {
    margin-top: 14px;
    padding-top: 14px;
}

這是 Sass 插值中一個(gè)簡(jiǎn)單的實(shí)例。當(dāng)你想設(shè)置屬性值的時(shí)候你可以使用字符串插入進(jìn)來(lái)。另一個(gè)有用的用法是構(gòu)建一個(gè)選擇器。可以這樣使用:

@mixin generate-sizes($class, $small, $medium, $big) {
    .#{$class}-small { font-size: $small; }
    .#{$class}-medium { font-size: $medium; }
    .#{$class}-big { font-size: $big; }
}
@include generate-sizes("header-text", 12px, 20px, 40px);

編譯出來(lái)的 CSS:

ader-text-small { font-size: 12px; }
.header-text-medium { font-size: 20px; }
.header-text-big { font-size: 40px; }

一旦你發(fā)現(xiàn)這一點(diǎn),你就會(huì)想到超級(jí)酷的 mixins,用來(lái)生成代碼或者生成另一個(gè) mixins。然而,這并不完全是可能的。第一個(gè)限制,這可能會(huì)很刪除用于 Sass 變量的插值:

$margin-big: 40px;
$margin-medium: 20px;
$margin-small: 12px;
@mixin set-value($size) {
    margin-top: $margin-#{$size};
}
.login-box {
    @include set-value(big);
}

上面的 Sass 代碼編譯出來(lái),你會(huì)得到下面的信息:

error style.scss (Line 5: Undefined variable: “$margin-".)

所以,#{}語(yǔ)法并不是隨處可用,你也不能在 mixin 中調(diào)用:

@mixin updated-status {
    margin-top: 20px;
    background: #F00;
}
$flag: "status";
.navigation {
    @include updated-#{$flag};
}

上面的代碼在編譯成 CSS 時(shí)同樣會(huì)報(bào)錯(cuò):

error style.scss (Line 7: Invalid CSS after "...nclude updated-": expected "}", was "#{$flag};")
幸運(yùn)的是,可以使用 @extend 中使用插值。例如:

%updated-status {
    margin-top: 20px;
    background: #F00;
}
.selected-status {
    font-weight: bold;
}
$flag: "status";
.navigation {
    @extend %updated-#{$flag};
    @extend .selected-#{$flag};
}

上面的 Sass 代碼是可以運(yùn)行的,因?yàn)樗o了我們力量,可以動(dòng)態(tài)的插入 .class 和 %placeholder。當(dāng)然他們不能接受像 mixin 這樣的參數(shù),上面的代碼編譯出來(lái)的 CSS:

.navigation {
    margin-top: 20px;
    background: #F00;
}
.selected-status, .navigation {
    font-weight: bold;
}

注釋


注釋對(duì)于一名程序員來(lái)說(shuō),是極其重要,良好的注釋能幫助自己或者別人閱讀源碼。在 Sass 中注釋有兩種方式,我暫且將其命名為:

1、類似 CSS 的注釋方式,使用 ”/* ”開(kāi)頭,結(jié)屬使用 ”*/ ”
2、類似 JavaScript 的注釋方式,使用“//”

兩者區(qū)別,前者會(huì)在編譯出來(lái)的 CSS 顯示,后者在編譯出來(lái)的 CSS 中不會(huì)顯示,來(lái)看一個(gè)示例:

//定義一個(gè)占位符

%mt5 {
  margin-top: 5px;
}

/*調(diào)用一個(gè)占位符*/

.box {
  @extend %mt5;
}

編譯出來(lái)的css:

.box {
  margin-top: 5px;
}

/*調(diào)用一個(gè)占位符*/

數(shù)據(jù)類型


Sass 和 JavaScript 語(yǔ)言類似,也具有自己的數(shù)據(jù)類型,在 Sass 中包含以下幾種數(shù)據(jù)類型:

  • 數(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。

SassScript 也支持其他 CSS 屬性值(property value),比如 Unicode 范圍,或 !important 聲明。然而,Sass 不會(huì)特殊對(duì)待這些屬性值,一律視為無(wú)引號(hào)字符串 (unquoted strings)。
后兩個(gè)小節(jié)詳細(xì)講解字符串和值列表數(shù)據(jù)類型,其它類型與JavaScript中的用法一致。

字符串


SassScript 支持 CSS 的兩種字符串類型:

  • 有引號(hào)字符串 (quoted strings),如 "Lucida Grande" 、'http://sass-lang.com'
  • 無(wú)引號(hào)字符串 (unquoted strings),如 sans-serifbold。

在編譯 CSS 文件時(shí)不會(huì)改變其類型。只有一種情況例外,使用 #{ }插值語(yǔ)句 (interpolation) 時(shí),有引號(hào)字符串將被編譯為無(wú)引號(hào)字符串,這樣方便了在混合指令 (mixin) 中引用選擇器名。

@mixin firefox-message($selector) {
  body.firefox #{$selector}:before {
    content: "Hi, Firefox users!";
  }
}
@include firefox-message(".header");

編譯為:

body.firefox .header:before {
  content: "Hi, Firefox users!"; }

需要注意的是:當(dāng) deprecated = property syntax 時(shí) (暫時(shí)不理解是怎樣的情況),所有的字符串都將被編譯為無(wú)引號(hào)字符串,不論是否使用了引號(hào)。

值列表


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

margin: 10px 15px 0 0

或者:

 font-face: Helvetica, Arial, sans-serif

像上面這樣通過(guò)空格或者逗號(hào)分隔的一系列的值。
事實(shí)上,獨(dú)立的值也被視為值列表——只包含一個(gè)值的值列表。
Sass列表函數(shù)(Sass list functions)賦予了值列表更多功能(Sass進(jìn)級(jí)會(huì)有講解):

  • nth函數(shù)(nth function) 可以直接訪問(wèn)值列表中的某一項(xiàng);
  • join函數(shù)(join function) 可以將多個(gè)值列表連結(jié)在一起;
  • append函數(shù)(append function) 可以在值列表中添加值;
  • @each規(guī)則(@each rule) 則能夠給值列表中的每個(gè)項(xiàng)目添加樣式。

值列表中可以再包含值列表,比如 1px 2px, 5px 6px 是包含 1px 2px 與 5px 6px 兩個(gè)值列表的值列表。如果內(nèi)外兩層值列表使用相同的分隔方式,要用圓括號(hào)包裹內(nèi)層,所以也可以寫(xiě)成 (1px 2px) (5px 6px)。當(dāng)值列表被編譯為 CSS 時(shí),Sass 不會(huì)添加任何圓括號(hào),因?yàn)?CSS 不允許這樣做。(1px 2px) (5px 6px)與 1px 2px 5px 6px 在編譯后的 CSS 文件中是一樣的,但是它們?cè)?Sass 文件中卻有不同的意義,前者是包含兩個(gè)值列表的值列表,而后者是包含四個(gè)值的值列表。
可以用 () 表示空的列表,這樣不可以直接編譯成 CSS,比如編譯 font-family: ()時(shí),Sass 將會(huì)報(bào)錯(cuò)。如果值列表中包含空的值列表或空值,編譯時(shí)將清除空值,比如 1px 2px () 3px 或 1px 2px null 3px。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,963評(píng)論 6 542
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,348評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 178,083評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,706評(píng)論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,442評(píng)論 6 412
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,802評(píng)論 1 328
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,795評(píng)論 3 446
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,983評(píng)論 0 290
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,542評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,287評(píng)論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,486評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,030評(píng)論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,710評(píng)論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 35,116評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 36,412評(píng)論 1 294
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,224評(píng)論 3 398
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,462評(píng)論 2 378

推薦閱讀更多精彩內(nèi)容

  • 1、SCSS 是 Sass 的新語(yǔ)法格式,從外形上來(lái)判斷他和 CSS 長(zhǎng)得幾乎是一模一樣,代碼都包裹在一對(duì)大括號(hào)里...
    夜幕小草閱讀 1,734評(píng)論 2 10
  • 編譯 使用 sass --watch監(jiān)控文件的改變,并對(duì)其進(jìn)行實(shí)時(shí)編譯語(yǔ)法: sass --watch input...
    放風(fēng)箏的小小馬閱讀 444評(píng)論 0 0
  • 2015年10月20日 1.嵌套 Sass 中還提供了選擇器嵌套功能,但這也并不意味著你在 Sass 中的嵌套是無(wú)...
    a0d560da7818閱讀 617評(píng)論 0 1
  • 基礎(chǔ) 聲明變量 普通變量 默認(rèn)變量 變量覆蓋:只需要在默認(rèn)變量之前重新聲明下變量即可 變量的調(diào)用 局部變量和全局變...
    Jill1231閱讀 1,304評(píng)論 0 1
  • -------------------------一、控制指令--------------------------...
    夜幕小草閱讀 3,166評(píng)論 0 5