SASS入門2

2015年10月20日

1.嵌套

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

Sass的嵌套分為3種:
a.選擇器嵌套
b.屬性嵌套
c.偽類嵌套

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)簽,在寫CSS會(huì)這樣寫:

nav a {
  color:red;
}

header nav a {
  color:green;
}

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

nav {
  a {
    color: red;

    header & {
      color:green;
    }
  }  
}

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

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

在Sass中可以這樣寫:

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

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

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

編譯出來的CSS:

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

盡量避免選擇器選擇器嵌套

混合宏

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

1.聲明混合宏
不帶參數(shù)的混合宏:
在Sass中,使用"@mixin"來聲明一個(gè)混合宏,如:

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

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

帶參數(shù)的混合宏:
除了一個(gè)不帶參數(shù)的混合宏之外,還可以在定義混合宏時(shí)帶有參數(shù),如:

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

復(fù)雜的混合宏:
上面是一個(gè)簡(jiǎn)單的定義混合宏的方法,當(dāng)然,Sass中的混合宏還提供更為復(fù)雜的,你可以在大括號(hào)里面寫上帶有邏輯關(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í)候可以使用“ … ”來替代。簡(jiǎn)單的解釋一下,當(dāng) $shadow 的參數(shù)數(shù)量值大于或等于“ 1 ”時(shí),表示有多個(gè)陰影值,反之調(diào)用默認(rèn)的參數(shù)值“ 0 0 4px rgba(0,0,0,.3) ”。

2.調(diào)用混合宏
在Sass中通過@mixin關(guān)鍵詞聲明了一個(gè)混合宏,那么在實(shí)際調(diào)用中,其匹配了一個(gè)關(guān)鍵詞"@include"來調(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í)候編譯出來的CSS:

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

3.混合宏的參數(shù)
Sass的混合宏有一個(gè)強(qiáng)大的功能,可以傳參,那么在Sass中傳參主要有一下幾種情況:
A)傳一個(gè)不帶值的參數(shù)
在混合宏中,可以傳一個(gè)不帶任何值的參數(shù),比如:

@mixin border-radius($radius){
      -weblit-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"。
編譯出來的CSS:

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

B)傳一個(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è)你的頁面中的圓角很多地方都是“3px”的圓角,那么這個(gè)時(shí)候只需要調(diào)用默認(rèn)的混合宏“border-radius”:

.btn { @include border-radius;}

編譯出來的CSS:

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

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

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

編譯出來的CSS:

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

C)傳多個(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);
}

編譯出來的CSS:

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

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

@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: $shadows;
                      box-shadow: $shadows;
              }
}

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

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

D)混合宏的不足
混合宏在實(shí)際編碼中給我們帶來很多方便之處,特別是對(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"混合宏。先來看編譯出來的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ò)展/繼承

在Sass中通過關(guān)鍵詞"@extend"來繼承已存在的類樣式塊,從而實(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;
}

編譯出來之后:

//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-color: orange;
      color: #fff;
}

從示例代碼可以看出,在Sass中的繼承,可以繼承類樣式塊中所有樣式代碼,而且編譯出來的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)生任何代碼。示例:

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

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

//SCSS
%mt5{
      margin-top: 5px;
}
%pt5{
      padding-top: 5px;
}
.btn{
      @extend %mt5;
      @extend %pt5;
}
.block{
        @extend %mt5;
        span{
              @expend %pt5;
        }
}

編譯出來的CSS

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

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

混合宏 VS 繼承 VS 占位符

a)混合宏的使用
如果你的代碼塊中涉及到變量,建議使用混合宏來創(chuàng)建相同的代碼塊。

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

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

Paste_Image.png

插值#{}

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

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

它可以讓變量和屬性工作的很完美,上面的代碼編譯成CSS:

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

這是Sass插值中的一個(gè)簡(jiǎn)單的實(shí)例。當(dāng)你想設(shè)置屬性值的時(shí)候你可以使用字符串插入進(jìn)來。另一個(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);

編譯出來的CSS:

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

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

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

所以,#{}語法并不是隨處可用,你也不能在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ù),上面的代碼編譯出來的 CSS:

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

在 Sass 的社區(qū)正在積極討論插值的局限性,誰又知道呢,也許我們很快將能夠使用這些技術(shù)也說不定呢。

注釋

Sass有兩種注釋方式,暫且將其命名為:
1.塊注釋"/*......... */"
2.行注釋 "http://"
兩者區(qū)別,前者會(huì)在編譯出來的CSS顯示,后者在編譯出來的CSS中不會(huì)顯示,示例:

//定義一個(gè)占位符
%mt5{
      margin-top: 5px;
}

/*調(diào)用一個(gè)占位符*/
.box{
      @extend %mt5;
}

編譯出來的CSS

.box{
    margin-top: 5px;
}

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

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

  • 聲明變量 定義變量的語法: 在有些編程語言中(如,JavaScript)聲明變量都是使用關(guān)鍵詞“var”開頭,但是...
    Junting閱讀 1,479評(píng)論 0 6
  • 1、SCSS 是 Sass 的新語法格式,從外形上來判斷他和 CSS 長得幾乎是一模一樣,代碼都包裹在一對(duì)大括號(hào)里...
    夜幕小草閱讀 1,734評(píng)論 2 10
  • 基礎(chǔ) 聲明變量 普通變量 默認(rèn)變量 變量覆蓋:只需要在默認(rèn)變量之前重新聲明下變量即可 變量的調(diào)用 局部變量和全局變...
    Jill1231閱讀 1,304評(píng)論 0 1
  • 前言 什么是CSS預(yù)處理器 定義:CSS預(yù)處理器定義了一種新的語言,其基本思想是,用一種專門的編程語言,為CSS增...
    SA_Arthur閱讀 3,137評(píng)論 0 18
  • 初夏的太陽讓久居寒冬的我們心里感到一絲絲躁動(dòng)。慵懶的神經(jīng)開始發(fā)揮本性,每天早晨都要睡到上課遲到的時(shí)候。感覺自己的大...
    閉嘴吧猴頭閱讀 378評(píng)論 2 0