SASS(二)

樣式規則(Style Rules)

總覽

  和css同樣,樣式規則是Sass的基礎,原理也差很少:用選擇器選擇你所要改變樣式的元素,而後聲明一些屬性去決定它的樣式。css

Sass:git

.button {
  padding: 3px 10px;
  font-size: 12px;
  border-radius: 3px;
  border: 1px solid #e1e4e8;
}

css:github

.button {
  padding: 3px 10px;
  font-size: 12px;
  border-radius: 3px;
  border: 1px solid #e1e4e8;
}

1)嵌套(Nesting)web

  固然Sass致力於讓碼生幸福,不會讓咱們一遍又一遍地去寫重複的選擇器,因此你能夠寫嵌套樣式,Sass會自動把外層選擇器和內層樣式規則結合起來。瀏覽器

Sass:sass

nav {
  ul {
    margin: 0;
    padding: 0;
    list-style: none;
  }

  li { display: inline-block; }

  a {
    display: block;
    padding: 6px 12px;
    text-decoration: none;
  }
}

css:app

nav ul {
  margin: 0;
  padding: 0;
  list-style: none;
}
nav li {
  display: inline-block;
}
nav a {
  display: block;
  padding: 6px 12px;
  text-decoration: none;
}

注意:嵌套規則很好用,可是同時你也沒法從視覺上去感覺你到底產生了多少css,嵌套得越深加載所需帶寬越高,瀏覽器渲染工做量也越大,因此儘可能嵌套淺一些。ide

1.選擇器列表(Selecor Lists)函數

  嵌套規則在處理選擇器列表(就是用逗號分隔的選擇器)上仍是比較智能的,每一個複合選擇器(逗號之間的)分別嵌套,再被結合爲一個選擇器列表。this

Sass:

.alert, .warning {
  ul, p {
    margin-right: 0;
    margin-left: 0;
    padding-bottom: 0;
  }
}

css:

.alert ul, .alert p, .warning ul, .warning p {
  margin-right: 0;
  margin-left: 0;
  padding-bottom: 0;
}

2.選擇器鏈接符(Selector Combinators)

  你也能夠嵌套使用了鏈接符的選擇器,鏈接符能夠放在外部選擇器的尾部,內部選擇器的開頭,或者是自身要鏈接的選擇器之間。

Sass:

ul > {
  li {
    list-style-type: none;
  }
}

h2 {
  + p {
    border-top: 1px solid gray;
  }
}

p {
  ~ {
    span {
      opacity: 0.8;
    }
  }
}

css:

ul > li {
  list-style-type: none;
}

h2 + p {
  border-top: 1px solid gray;
}

p ~ span {
  opacity: 0.8;
}

3.高級嵌套(Advanced Nesting)

  萬一你不想讓你的嵌套僅僅按順序以派生鏈接符(就那空格)結合起來,Sass也是支持你的。詳情見下節父選擇器。

2)插值(Interpolation)

  你可使用插值來從表達式(好比變量、函數調用)中注入動態值到你的選擇器中,這在你書寫混合變量的時候格外有用,由於這樣的話你就能夠根據用戶傳入的變量來決定使用什麼選擇器。

Sass:

@mixin define-emoji($name, $glyph)
  span.emoji-#{$name}
    font-family: IconFont
    font-variant: normal
    font-weight: normal
    content: $glyph

@include define-emoji("women-holding-hands", "👭")

css:

@charset "UTF-8";
span.emoji-women-holding-hands {
  font-family: IconFont;
  font-variant: normal;
  font-weight: normal;
  content: "👭";
}

PS:Sass只有在求得插值以後纔會去解析選擇器,因此你能夠放心地在選擇器的任何地方使用插值,不用擔憂它是否是尚未解析。

你能夠在須要動態決定選擇器的時候把插值和父選擇器&、at-rules和選擇器函數結合使用來達到效果。詳情見下節父選擇器。

 屬性聲明(Property Declarations)

   和css同樣,Sass裏的屬性聲明定義了和選擇器匹配的元素的樣式。可是Sass定義了額外的特性來加強易書寫性和智能性。重要的是,聲明的值能夠是Sass表達式,它會被求值而後包含在結果中。

Sass:

.circle {
  $size: 100px;
  width: $size;
  height: $size;
  border-radius: $size / 2;
}

css:

.circle {
  width: 100px;
  height: 100px;
  border-radius: 50px;
}

1)插值(Interpolation)

  屬性名能夠包括插值,這樣的話就能夠按需決定使用哪一個屬性名了。甚至整個屬性名均可以由插值決定。

Sass:

@mixin prefix($property, $value, $prefixes) {
  @each $prefix in $prefixes {
    -#{$prefix}-#{$property}: $value;
  }
  #{$property}: $value;
}

.gray {
  @include prefix(filter, grayscale(50%), moz webkit);
}

css:

.gray {
  -moz-filter: grayscale(50%);
  -webkit-filter: grayscale(50%);
  filter: grayscale(50%);
}

2)嵌套(Nesting)

  不少css屬性以相同的前綴開頭,這些前綴扮演着相似於命名空間的做用。舉個例子,font-family、font-size、font-weight就都以font-開頭。Sass經過容許屬性聲明嵌套來使寫法更加簡易。外層屬性會加到內層屬性上,經過連字符來鏈接。

Sass:

.enlarge {
  font-size: 14px;
  transition: {
    property: font-size;
    duration: 4s;
    delay: 2s;
  }

  &:hover { font-size: 36px; }
}

css:

.enlarge {
  font-size: 14px;
  transition-property: font-size;
  transition-duration: 4s;
  transition-delay: 2s;
}
.enlarge:hover {
  font-size: 36px;
}

PS:有些css屬性使用命名空間名做爲屬性名的簡略寫法,這種狀況你能夠同時使用簡略寫法和複雜的嵌套寫法。

Sass:

.info-page {
  margin: auto {
    bottom: 10px;
    top: 2px;
  }
}

css:

.info-page {
  margin: auto;
  margin-bottom: 10px;
  margin-top: 2px;
}

3)隱式聲明(Hidden Declarations)

  有時候你想要一個屬性聲明只在特定時候出現,若是一個屬性的值是null或者空的未加引號的字符串,Sass就不會把它編譯到css中。

$rounded-corners: false;

.button {
  border: 1px solid black;
  border-radius: if($rounded-corners, 5px, null);
}

css:

.button {
  border: 1px solid black;
}

4)自定義屬性(Custom Properties)

  css自定義屬性,也被稱爲css變量,它們的聲明語法比較特殊,容許變量名包含幾乎任何文本,並且這些變量JavaScript也能夠訪問,因此任何變量對於書寫者來講均可能有意義,包括被正常轉爲SassScript的變量。所以Sass解析自定義屬性聲明的時候跟正常屬性聲明不同。全部相似於SassScript的字符會原樣輸出爲css。惟一注入動態變量到自定義屬性的方法是插值。

Sass:

$primary: #81899b;
$accent: #302e24;
$warn: #dfa612;

:root {
  --primary: #{$primary};
  --accent: #{$accent};
  --warn: #{$warn};

  // Even though this looks like a Sass variable, it's valid CSS so it's not
  // evaluated.
  --consumed-by-js: $primary;
}

css:

:root {
  --primary: #81899b;
  --accent: #302e24;
  --warn: #dfa612;
  --consumed-by-js: $primary;
}

注意:不幸的是插值會移除字符串的引號,因此未來自Sass變量的被引號包裹的字符串注入自定義屬性就比較困難,可是你可使用inspect()方法來保留引號。

Sass:

$font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto;
$font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas;

:root {
  --font-family-sans-serif: #{inspect($font-family-sans-serif)};
  --font-family-monospace: #{inspect($font-family-monospace)};
}

 css:

:root {
  --font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto;
  --font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas;
}

父選擇器(Parent Selector)

   父選擇器&是Sass首創的一個選擇器,用於在嵌套選擇器中指向其外層選擇器,利用父選擇器能夠實現外層選擇器的多重複雜重用,好比增長一個僞類或者其餘選擇器。

  和正常的嵌套機制不一樣,當父選擇器在一個選擇器內部使用時它指代的就是這個選擇器。

Sass:

.alert {
  // The parent selector can be used to add pseudo-classes to the outer
  // selector.
  &:hover {
    font-weight: bold;
  }

  // It can also be used to style the outer selector in a certain context, such
  // as a body set to use a right-to-left language.
  [dir=rtl] & {
    margin-left: 0;
    margin-right: 10px;
  }

  // You can even use it as an argument to pseudo-class selectors.
  :not(&) {
    opacity: 0.8;
  }
}

css:

.alert:hover {
  font-weight: bold;
}
[dir=rtl] .alert {
  margin-left: 0;
  margin-right: 10px;
}
:not(.alert) {
  opacity: 0.8;
}

注意:因爲父選擇器能夠表明類選擇器好比h1,它只能出如今類選擇器可以出現的地方即複合選擇器開頭,例如span&就是不合法的寫法。咱們也在嘗試放鬆這些限制,你想的話能夠加入咱們

1)添加後綴(Adding Suffix)

  你也可使用父選擇器來爲外層選擇器添加後綴,這在使用某些例如BEM這種使用高度結構化類名的命名原則時會格外有用,只要外層選擇器以含有字母和數字的名稱(好比class,id,元素選擇器)結尾,你就可使用父選擇器添加額外文本。

Sass:

.accordion {
  max-width: 600px;
  margin: 4rem auto;
  width: 90%;
  font-family: "Raleway", sans-serif;
  background: #f4f4f4;

  &__copy {
    display: none;
    padding: 1rem 1.5rem 2rem 1.5rem;
    color: gray;
    line-height: 1.6;
    font-size: 14px;
    font-weight: 500;

    &--open {
      display: block;
    }
  }
}

css:

.accordion {
  max-width: 600px;
  margin: 4rem auto;
  width: 90%;
  font-family: "Raleway", sans-serif;
  background: #f4f4f4;
}
.accordion__copy {
  display: none;
  padding: 1rem 1.5rem 2rem 1.5rem;
  color: gray;
  line-height: 1.6;
  font-size: 14px;
  font-weight: 500;
}
.accordion__copy--open {
  display: block;
}

2)SassScript用法(In SassScript)

   父選擇器能夠在SassScript中使用,屬於特殊表達式,返回當前父選擇器,和選擇器函數使用的格式同樣,包含以空格分隔的列表即複雜選擇器(the complex selectors )的以逗號分隔的選擇器列表(the selector list),複雜選擇器又可能包含不帶引號的字符串即複合選擇器(the compound selectors)。

Sass:

SCSS SYNTAX
.main aside:hover,
.sidebar p {
  parent-selector: &;
  // => ((unquote(".main") unquote("aside:hover")),
  //     (unquote(".sidebar") unquote("p")))
}

css:

.main aside:hover,
.sidebar p {
  parent-selector: .main aside:hover, .sidebar p;
}

  若是父選擇器在樣式規則外層使用,它會返回null,而null屬於falsey,所以你能夠藉此來決定在一個樣式規則中要不要引用一個混合類型。

Sass:

@mixin app-background($color) {
  #{if(&, '&.app-background', '.app-background')} {
    background-color: $color;
    color: rgba(#fff, 0.75);
  }
}

@include app-background(#036);

.sidebar {
  @include app-background(#c6538c);
}

css:

.app-background {
  background-color: #036;
  color: rgba(255, 255, 255, 0.75);
}

.sidebar.app-background {
  background-color: #c6538c;
  color: rgba(255, 255, 255, 0.75);
}

高級嵌套(Advanced Nesting)

  你能夠把父選擇器做爲正常表達式使用,也就是說你能夠把它傳入函數或者插值,即便是在別的選擇器裏。結合選擇器函數和@at-root規則使用能夠達到很是強大的嵌套效果。

  舉個例子,假設你要寫一個選擇器來匹配外層選擇器和一個元素選擇器,你能夠像這樣使用selector-unify()函數來結合父選擇器和另外一個自定義選擇器:

Sass:

@mixin unify-parent($child) {
  @at-root #{selector-unify(&, $child)} {
    @content;
  }
}

.wrapper .field {
  @include unify-parent("input") {
    /* ... */
  }
  @include unify-parent("select") {
    /* ... */
  }
}

css:

.wrapper input.field {
  /* ... */
}
.wrapper select.field {
  /* ... */
}

注意:Sass在處理嵌套的時候,它也不知道這些選擇器是由什麼樣的插值產生的,因此它會自動把外層選擇器加到內層選擇器前面,即便你使用了父選擇器做爲SassScript表達式。因此你要使用@at-root規則來明確告訴Sass不要去包含外層選擇器。

 佔位符選擇器(Placeholder Selectors)

   Sass還有一種特殊的選擇器‘佔位符’。它的長相和行爲都很像一個類選擇器,不一樣的是它以%開頭而且不輸出到css中。事實上,任何含有了佔位符選擇器的複雜選擇器(被逗號隔離的那些)及其對應樣式規則都不會被輸出到css中。

Sass:

.alert:hover, %strong-alert {
  font-weight: bold;
}

%strong-alert:hover {
  color: red;
}

css:

.alert:hover {
  font-weight: bold;
}

   一個選擇器它都被所有忽略了那要它幹嗎?誒,它還能夠被擴展。不像類選擇器,若是不進行擴展,而且不要求庫的用戶爲其HTML使用特定的類名,則佔位符不會出現使得css一團亂。

Sass:

%toolbelt {
  box-sizing: border-box;
  border-top: 1px rgba(#000, .12) solid;
  padding: 16px 0;
  width: 100%;

  &:hover { border: 2px rgba(#000, .5) solid; }
}

.action-buttons {
  @extend %toolbelt;
  color: #4285f4;
}

.reset-buttons {
  @extend %toolbelt;
  color: #cddc39;
}

css:

.action-buttons, .reset-buttons {
  box-sizing: border-box;
  border-top: 1px rgba(0, 0, 0, 0.12) solid;
  padding: 16px 0;
  width: 100%;
}
.action-buttons:hover, .reset-buttons:hover {
  border: 2px rgba(0, 0, 0, 0.5) solid;
}

.action-buttons {
  color: #4285f4;
}

.reset-buttons {
  color: #cddc39;
}

  在編寫一個Sass庫時有些樣式規則只須要某些狀況下起做用,這時候佔位符就顯得格外有用。但根據經驗,若是你只是爲本身的應用編寫樣式表的話,若是有可用的類選擇器,擴展類選擇器一般更好。

相關文章
相關標籤/搜索