Sass占位符選擇器`%`


摘錄自Understanding placeholder selectors.

@extend

@extend讓你能夠在多個選擇器中通過繼承的方式共享一段樣式:

.icon {
  transition: background-color ease .2s;
  margin: 0 .5em;
}

.error-icon {
  @extend .icon;
  /* error specific styles... */
}

.info-icon {
  @extend .icon;
  /* info specific styles... */
}

會被轉化為:

.icon, .error-icon, .info-icon {
  transition: background-color ease .2s;
  margin: 0 .5em;
}

.error-icon {
  /* error specific styles... */
}

.info-icon {
  /* info specific styles... */
}

有個問題就是, 如果你不可能用到icon這個類呢?

占位符選擇器%

占位符選擇器(Placeholder Selector)是以%而不是.作為開始符的選擇器. 它自身不會出現在編譯后的CSS文件中, 只會出現在@extend了它的那些選擇器中.

上例中, 用%icon替換.icon會得到:

.error-icon, .info-icon {
  transition: background-color ease .2s;
  margin: 0 .5em;
}

.error-icon {
  /* error specific styles... */
}

.info-icon {
  /* info specific styles... */
}

CSS中不會出現.icon類!

@extend vs. @include

乍看下, %選擇器和無參數mixin差不多, 在瀏覽器中產生的效果是一樣的, 但是編譯后的CSS有很大不同.

@mixin icon {
  transition: background-color ease .2s;
  margin: 0 .5em;
}

.error-icon {
  @include icon;
  /* error specific styles... */
}

.info-icon {
  @include icon;
  /* info specific styles... */
}

以上代碼會編譯成

.error-icon {
  transition: background-color ease .2s;
  margin: 0 .5em;
  /* error specific styles... */
}

.info-icon {
  transition: background-color ease .2s;
  margin: 0 .5em;
  /* info specific styles... */
}

可以看到, .error-icon.info-icon中繼承自mixinicon的部分重復了兩次, 有冗余. 但是用%選擇器配合@extend就不會有這樣的問題.

@extend的限制

@extend有個限制, 就是你不能@extend不同@media塊中的樣式. 這個限制同樣對%選擇器有效.

%icon {
  transition: background-color ease .2s;
  margin: 0 .5em;
}

@media screen {
  .error-icon {
    @extend %icon;
  }
  
  .info-icon {
    @extend %icon;
  }
}

這會導致編譯錯誤:

You may not @extend an outer selector from within @media.
You may only @extend selectors within the same directive.
From "@extend %icon" on line 8 of icons.scss

這是由於@extend的實現方式其實是用調用@extend的類替換被@extend的類, 上例中即用.error-icon, .info-icon替換%icon. 但是由於這些調用@extend的類屬於@media塊, 這樣直接替換會導致替換后的規則脫離@media塊, 因此是非法的.

但是, 反過來就沒事兒. 因為%icon屬性原本就是在@media內部生效的, .error-icon, .info-icon繼承來的這部分規則自然也只應該在該@media下生效.

@media screen {
  %icon {
    transition: background-color ease .2s;
    margin: 0 .5em;
  }
}

.error-icon {
  @extend %icon;
  background-color: red;
}

.info-icon {
  @extend %icon;
  background-color: green;
}

會被編譯成

@media screen {
  .error-icon, .info-icon {
    transition: background-color ease .2s;
    margin: 0 .5em;
  }
}

.error-icon {
  background-color: red;
}

.info-icon {
  background-color: green;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM