Sass / Scss 教學 2

Posted on  Sep 2, 2017  in  CSS  by  Amo Chen  ‐ 5 min read

Sass 系列教學:

繼上篇基本的變數介紹之後,本篇來談談 Sass 中的巢狀(nested rules) 、命名空間(namespaces) 、引用(import) 等語法。

巢狀結構 (Nested Rules)

假設在 HMTL 文件中有以下的結構:

<div id="main">
  <p>
    Look at
    <a class="red box" href="">this link</a>
  </p>
</div>

以往在撰寫 CSS 碼時,如果想針對結構內的階層關係進行設定時,就可能會空格分隔來表達,例如:

#main p {
  color: #777;
  width: 50%;
}

#main p .redbox {
  background-color: red;
  color: white;
}

如果 HTML 文件的階層結構簡單,那麼這種寫法其實沒有什麼問題;一旦階層結構複雜,那麼就可能出現很多 CSS 區塊都是針對某一個區塊內的元素而撰寫的設定,結果就會形成又臭又長的 CSS 碼。因此 Sass 也可以用巢狀的結構來表達 CSS 的階層關係,像上述的 CSS 範例,可以 Sass 寫成:

#main p {

  color: #777;
  width: 50%;

  .redbox {
    background-color: red;
    color: white;
  }

}

善用這樣的巢狀結構寫法,可以讓你的 Sass 更簡潔、更具閱讀性喔!

p.s. 官方建議,如果能夠使用簡單的結構語法,就不要使用太多巢狀結構,否則網頁載入速度會變慢,建議最多不要超過 3 層或 4 層

用 & 符號參照巢狀結構的父選取器 (Referencing Parent Selectors)

CSS 中有定義一些 pseudo-classes (或稱偽類、準類別),被使用來為元素增加一些特效,如 :hover , :link , :visited 等這些以冒號(:)開頭的類別名稱。例如把滑鼠移到某個網頁連結時,連結會變色的 CSS 語法:

a {
  font-weight: bold;
  text-decoration: none;
}

a :hover {
  color:#FF00FF;
}

上述其實還是一種巢狀的結構,只是都作用到同一個元素(例如範例的 a 元素)上。這樣的情況就能夠用對 :hover 使用 符號來代表其作用的父選取器,所以上述的 CSS 範例的 Sass 就可以寫成:

a {

  font-weight: bold;
  text-decoration: none;

  &:hover {
    color:#FF00FF;
  }

}

更多關於 Parent Selectors

命名空間 (Namespaces)

在 CSS 中,有定義很多屬性都是相同字串開頭 ,例如 font-family, font-size, font-weight 這些都是以 font 開頭,因此在 Sass 中就定義了命名空間的寫法,例如以下的 CSS 碼:

.serif-font {
  font-family: serif;
  font-size: 25em;
  font-weight: bold;
}

可以用 Sass 的命名空間表達成:

.serif-font {
  font: {
    family: serif;
    size: 25em;
    weight: bold;
  }
}

此外,命名空間也可以有自己的設定喔!例如,設定命名空間 font 的長寬為 2px / 3px

.serif-font {
  font: 2px / 3px {
    family: serif;
    size: 25em;
    weight: bold;
  }
}

上述範例會被編譯成:

.serif-font {
  font: 2px/3px;
  font-family: serif;
  font-size: 25em;
  font-weight: bold;
}

@import

如果一個專案撰寫了很多個 scss / sass 檔案,就可以透過 @import 引用這些 scss/sass 檔案。 @import 對實務上有很大的幫助,因為可以把常用的、慣用的 CSS 碼放在不同的 scss/ sass 檔案內,達到模組化的功用!

語法:

@import "scss_file1", "scss_file2";

p.s. @import 不需加副檔名

p.s. 如果 scss/sass 檔名前加上底線(例如 _index.scss ),就代表這個檔案不需要 compile 成 CSS 檔案,且 @import 時檔名並不用加底線。

@extend

繼承,這是我所能想到的最好的解釋了。以往如果有相同的 CSS 屬性,是無法用繼承的方式進行屬性的複製與改寫,得重新撰寫 CSS 碼才行。現在透過 Sass 的 @extend 就能夠進行屬性的繼承了!

語法:

@extend selector;

例如 Sass 官方提供的範例:

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

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

.seriousError 繼承了 .error 的樣式,所以會被編譯成:

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

.seriousError {
  border-width: 3px;
}

p.s. 每一個 Sass 區塊並沒有限定能夠使用 @extend 幾次,使用多重繼承也是可以的,只是要注意屬性覆蓋的問題,根據 CSS 的原則,前後屬性如相同,以最後出現的為準。

此外,在 Sass 中,有一種 extend only 的用法,如果在選取器(selector)名稱後加上 % 符號及名稱,就代表此一選取器只提供 @extend 繼承,且 % 符號及 % 後的名稱,會被繼承者的 #. 符號所取代,而定義 extend only 的 Sass 區塊並不會被 Sass 編譯進 CSS 中。

例如:

a%ext-only {
  color: red;
}
.notice {
  @extend %ext-only;
}

就會被 Sass 編譯成:

a.notice {
  color: red;
}

以上的用法要注意,不可與定義 extend only 的 Sass 區塊內的元素衝突!例如把 .notice 改成 h1.notice 就會產生錯誤,因為原始可接受的定義是 extend-only-selector#idextend-only-selector.class ,以上述範例來說就是 a#id , a.class

!optional

在使用 @extend 時,後方的選取器(selector)必須實際存在或沒有任何錯誤存在,如果想 @extend 一個不存在的選取器或有錯誤暫時不想修正,可以在 @extend 最後面加上 !optional 標籤即可,例如前述的 extend only 的錯誤就可以用 !optional 來修正。

語法:

@extend selector !optional ;

關於 !optional Flag

@mixin

@mixin 就像其字面意思一樣,可以用來混在 Sass 區塊中。因此它的作用其實很像函數,只要定義好 @mixin 之後,就可以不斷重複利用。

語法 1:

@mixin mixin-name { ... }

語法 2:

@mixin 可以像函數一樣使用參數。

@mixin mixin-name($arg1, $arg2, ...) { ... }

語法 3:

語法3的意義其實跟語法2一模一樣,只是語法 3 會更好閱讀跟理解參數的意思。

@mixin mixin-name($arg1: value1, $arg2: value2, ...) { ... }

以下是使用 @mixin 的範例:

@mixin clear-fix {
  display: inline-block;
}

@include

定義好 @mixin 之後,要使用 @mixin 的方法就是使用 @include

語法 1:

@include mixin-name;

語法 2:

@include mixin-nam(arg1, arg2, ...);

例如調用先前定義好的 mixin clear-fix :

p {
  @include clear-fix;
}

更多 @include

@content

@content 也經常與 @mixin 一起使用,因為 @content 的作用是能夠讓 @mixin 傳入一整個 CSS 區塊的用法。

範例 1:

@mixin colors {
  width: 1000px;
  @content;
}

.title {
  @inclue colors { background-color: blue; }
}

範例1的寫法其實,就是將 { background-color: blue; } 一整個區塊傳進 @mixin colors 的 @content 內。其結果就像以下的 CSS 碼:

.title {
  width: 1000px;
  background-color: blue;
}

@content 的用法雖然便利,不過也要注意區域變數的問題,例如以下的範例 2,我們可能會誤以為 @include colors { color: $color; } 傳入的 $color 是 blue ,但事實上此 $color@mixin colors($color: blue)$color 不同, @include colors { color: $color; }$color 取決於位於 .title 內的區域變數或全域變數。

範例 2:

$color: white;
@mixin colors($color: blue) {
  background-color: $color;
  @content;
}

.title {
width: 1000px;
  @include colors { color: $color; }
}

範例 2 的結果如下:

.title {
  width: 1000px;
  background-color: blue;
  color: white;
}

@function

@function 用法幾乎與 @mixin 相同,不過它多了 @return 可以使用回傳值!

語法:

@function func($arg1, $arg2, ...) {
  @return $variable ;
}

範例:

@function double($n) {
  @return $n * 2;
}

$width: 20;
.cell-width {
  width: double($width);
}

上述範例會被編譯成:

.cell-width {
  width: 40;
}

@if

@if 判斷式,請直接看範例!

範例:

$type: ie;
p {
    @if $type == ie { color: blue; }
    @elif $type == chrome { color: green; }
    @else { color: black; }
}

@for

這也沒什麼好說明的,可以直接看範例。

語法:

@for $i from $number1 through $number2 {
    ...
}

範例:

@for $variable from 1 through 3 {
  .item-#{$1} { width: 100px * $i; }
}

範例結果:

.item-1 { width: 100px; }
.item-2 { width: 200px; }
.item-3 { width: 300px; }

@each

語法:

@each $variable in <list>
  ...
}

範例:

@each $variable in 1, 2, 3 {
    .item-#{$variable} { width: 100px * $variable; }
}

範例結果:

.item-1 {
  width: 100px;
}

.item-2 {
  width: 200px;
}

.item-3 {
  width: 300px;
}

@while

直接看範例:

$i: 6;
@while $i > 0 {
  .item-#{$i} { width: 2em * $i; }
  $i: $i - 2;
}

範例結果:

.item-6 {
  width: 12em;
}

.item-4 {
  width: 8em;
}

.item-2 {
  width: 4em;
}

@debug & @warn

Sass 也提供一些 Debug 的技巧,例如 @debug , @warn ,兩者的用法相同,可以在開發過程善用它,以減少除錯的次數。例如可以在 Sass 檔內添加一行:

@debug 10em + 12em;

在編譯時就會跳出以下的訊息提示:

Line 1 DEBUG: 22em

以上是簡單的 Sass 語法介紹,有興趣者也可以至 Sass

對抗久坐職業傷害

研究指出每天增加 2 小時坐著的時間,會增加大腸癌、心臟疾病、肺癌的風險,也造成肩頸、腰背疼痛等常見問題。

然而對抗這些問題,卻只需要工作時定期休息跟伸展身體即可!

你想輕鬆改變現狀嗎?試試看我們的 PomodoRoll 番茄鐘吧! PomodoRoll 番茄鐘會根據你所設定的專注時間,定期建議你 1 項辦公族適用的伸展運動,幫助你打敗久坐所帶來的傷害!

追蹤新知

看完這篇文章了嗎?還意猶未盡的話,追蹤粉絲專頁吧!

我們每天至少分享 1 篇文章/新聞或者實用的軟體/工具,讓你輕鬆增廣見聞提升專業能力!如果你喜歡我們的文章,或是想了解更多特定主題的教學,歡迎到我們的粉絲專頁按讚、留言讓我們知道。你的鼓勵,是我們的原力!

贊助我們的創作

看完這篇文章了嗎? 休息一下,喝杯咖啡吧!

如果你覺得 MyApollo 有讓你獲得實用的資訊,希望能看到更多的技術分享,邀請你贊助我們一杯咖啡,讓我們有更多的動力與精力繼續提供高品質的文章,感謝你的支持!