SASS @extend官方文檔剖析

@extend用法剖析

提醒:建議繼承那些乾淨的無後代寫法的樣式css

咱們常常會遇到這樣的狀況,當咱們在開發頁面時候一個class須要包含前一個class的全部樣式,可是又必須有他本身特殊新增的樣式。可是這兩個class其實都是相差無幾的,只是有細微的差異。好比錯誤提示的樣式(.error和.specialerror),既而後着只是比前者多一兩句樣式,爲什麼還要寫兩個class呢,由於咱們不想把前者.error的樣式從新在寫一遍,無聊極了。可是這樣帶來一個問題,就是html標籤上會多出好幾個class。html

爲了解決這個問題,sass裏提供了@extend的解決方法
先看一個例子:sass

<div class="error specialerror">
  Oh no! You've been hacked!
</div>

咱們的css以下url

.error {
  border: 1px #f00;
  background-color: #fdd;
}
.specialerror {
  border-width: 3px;
}

這裏就出現咱們剛說的問題了,其實咱們內心是十萬個不肯意就這麼在後面唐突的加個specialerror的,由於若是隻寫specialerror,就丟失了前面的樣式(爲何呢,由於咱們沒有在specialerror裏複寫error的樣式,只是新增了)code

經過Sass的@extend,一個選擇器將繼承另外一個選擇器的樣式
例如:htm

.error {
  border: 1px #f00;
  background-color: #fdd;
}
.specialerror {
  @extend .error;
  border-width: 3px;
}

被編譯爲:繼承

.error, .specialerror {
  border: 1px #f00;
  background-color: #fdd;
}

.specialerror {
  border-width: 3px;
}

意味着.error全部的樣式都會加到.specialerror上,這樣.specialerror就會有.error的樣式了。這樣咱們就能夠只寫.specialerror了。目前就先這樣理解,其實這個@extend實現的方式是跟咱們現實邏輯顛倒的。ip

可是若是改爲這樣:ci

.error {
      border: 1px #f00;
      background-color: #fdd;
    }
    .specialerror {
      @extend .error;
      border-width: 3px;
    }
    .error.intrusion {
      background-image: url("/image/hacked.png");
    }

加上面這段樣式後<div class="specialerror intrusion"> 就會加上和<div class="error intrusion">同樣的背景開發

怎麼作到的呢

.error {
      border: 1px #f00;
      background-color: #fdd;
    }
    
.error.intrusion {
  background-image: url("/image/hacked.png");
}

.specialerror {
  @extend .error;
  border-width: 3px;
}

被編譯爲:

.error, .specialerror {
  border: 1px #f00;
  background-color: #fdd; }

.error.intrusion, .specialerror.intrusion {
  background-image: url("/image/hacked.png"); }

.specialerror {
  border-width: 3px; }

這裏須要重點講解下,其實咱們正常理解增長擴充添加就是copy而後paste,是的,這樣思考其實也是對的,就像文章一開始那個最簡單的例子。可是爲了不沒必要要的重複。@extend的邏輯稍稍不一樣。你能夠這樣認爲,使用@extend時候sass會將.error相關樣式先拷貝一份,

.specialerror {
      @extend .error;
      border-width: 3px;
    }

而後把字符「specialerror」存儲在@extend裏,遇到」error「字符就進行替換,這樣.specialerror就有了.error的樣式啦!這也就能解釋,爲何會出現下面.specialerror.intrusion的緣由了。

.error.intrusion, .specialerror.intrusion {
      background-image: url("/image/hacked.png"); }

當組合選擇器的樣式時, @extend 可以很聰明得避免沒必要要的重複,例如.seriousError.seriousError會被轉換成.seriousError。不會生成相似#main#footer的不可用選擇器。

求證例子:

.hoverlink {
  @extend a:hover;
}
a:hover {
  text-decoration: underline;
}

被編譯爲:

a:hover, .hoverlink {
  text-decoration: underline; }

就像上面的.error.intrusion ,任何使用 a:hover 都會替換爲 .hoverlink,即便中間包含其餘選擇器。例如:

.hoverlink {
  @extend a:hover;
}
.comment a.user:hover {
  font-weight: bold;
}

被編譯爲:

.comment a.user:hover, .comment .user.hoverlink {
  font-weight: bold; }

Multiple Extends

一個選擇器還能夠擴充多個選擇器的樣式例如:

.error {
  border: 1px #f00;
  background-color: #fdd;
}
.attention {
  font-size: 3em;
  background-color: #ff0;
}
.seriousError {
  @extend .error;
  @extend .attention;
  border-width: 3px;
}

被編譯爲:

.error, .seriousError {
  border: 1px #f00;
  background-color: #fdd; }

.attention, .seriousError {
  font-size: 3em;
  background-color: #ff0; }

.seriousError {
  border-width: 3px; }

對於下面這種只需注意下就行,就是.criticalError內 「@extend .seriousError」這句話。在運行這句語句時候,sass會檢測到.seriousError內有「@extend .error」。
因此.criticalError既有.error的樣式也有.seriousError的樣式,故criticalError須要替換的是error和seriousError。

.error {
  border: 1px #f00;
  background-color: #fdd;
}
.seriousError {
  @extend .error;
  border-width: 3px;
}
.criticalError {
  @extend .seriousError;
  position: fixed;
  top: 10%;
  bottom: 10%;
  left: 10%;
  right: 10%;
}

被編譯爲:

.error, .seriousError, .criticalError {
  border: 1px #f00;
  background-color: #fdd; }

.seriousError, .criticalError {
  border-width: 3px; }

.criticalError {
  position: fixed;
  top: 10%;
  bottom: 10%;
  left: 10%;
  right: 10%; }

選擇器序列
例如.foo .bar或者 .foo + .bar, 目前還不能擴展. 可是對於嵌套的選擇器仍是可使用@extend添加到其餘選擇器的 例如:

#fake-links .link {
  @extend a;
}

a {
  color: blue;
  &:hover {
    text-decoration: underline;
  }
}

編譯爲:

a, #fake-links .link {
  color: blue; }
  a:hover, #fake-links .link:hover {
    text-decoration: underline; }

當兩個沒有共同點的序列擴充組合時候, 將會產生兩個不一樣的選擇器: 一種是第一個序列在前,另外一種是第二個序列在前例如: #admin .tabbar會和#demo .overview調換位置。

#admin .tabbar a {
  font-weight: bold;
}
#demo .overview .fakelink {
  @extend a;
}

被編譯爲:

#admin .tabbar a,
#admin .tabbar #demo .overview .fakelink,
#demo .overview #admin .tabbar .fakelink {
  font-weight: bold; }

若是另個序列有一些共同的選擇器,這些選擇器將會被組合在一塊兒並且只有不一樣的將會保留下來。下面這個例子中, 每一個寫都包含id #admin, 因此產生的選擇器就會合並這兩個#admin。#admin .tabbar和 #admin .overview會調換位置,換完以後在省略重複的。

#admin .tabbar a {
      font-weight: bold;
    }
    #admin .overview .fakelink {
      @extend a;
    }

這被編譯爲:

#admin .tabbar a,
    #admin .tabbar .overview .fakelink,
    #admin .overview .tabbar .fakelink {
      font-weight: bold; }
相關文章
相關標籤/搜索