iT邦幫忙

2

Scss - 小知識與進階功能 ( 下 )

接續上篇繼續介紹剩下的功能,這邊就比較偏程式面,設計函式會比較常使用到,GO!GO!GO!

迴圈部分

迴圈可使用 @each@for 來產生重複的樣式,使用方法如下

@each ... in ...

類似 javascript 裡面的 forEach 方法,對陣列內所有內容進行迴圈

編譯前

$themes: ('primary': blue, 'danger': red);

@each $name, $color in $themes {
  .btn-#{$name} {
    color: $color;
  }
}

編譯後

.btn-primary {
  color: blue;
}
.btn-danger {
  color: red;
}

@for

類似 javascript 裡面的 for 迴圈,對陣列內指定內容進行迴圈,有 tothrough 兩種用法,其中差別在 to 不包括最後的數字,through 則相反

編譯前

@for $i from 1 through 3 {
  .h#{$i} {
    font-size: 16px * (3 / $i);
  }
}

編譯後

.h1 {
  font-size: 48px;
}
.h2 {
  font-size: 24px;
}
/* 若使用 to 則 .h3 不會被編譯出來 */
.h3 {
  font-size: 16px;
}

判斷式

基本上 @if@else@else if 返回一段樣式,而 @whileif() 返回一個值,皆可搭配迴圈做使用

@if、@else、@else if

使用上與 javascript 的 if ... else 相同,但要特別注意 空字串空陣列0 都是 true

編譯前

@mixin triangle($size, $color, $direction) {
  height: 0;
  width: 0;

  border-color: transparent;
  border-style: solid;
  border-width: $size / 2;

  @if $direction == up {
    border-bottom-color: $color;
  } @else if $direction == right {
    border-left-color: $color;
  } @else if $direction == down {
    border-top-color: $color;
  } @else if $direction == left {
    border-right-color: $color;
  } @else {
    @error "Unknown direction #{$direction}.";
  }
}
.next {
  @include triangle(5px, black, right);
}

編譯後

.next {
  height: 0;
  width: 0;
  border-color: transparent;
  border-style: solid;
  border-width: 2.5px;
  border-left-color: black;
}

@while

類似 javascript 裡面的 while 判斷,必須 @return 一個值

編譯前

@function size($lv: 0) {
  $minSize: 26px;
  $value: 16px * (3 / $lv);
  @while $lv>1 {
    @return $minSize;
  }
  @while $lv<=1 {
    @return $value;
  }
}
@for $i from 1 through 3 {
  .h#{$i} {
    font-size: size($i);
  }
}

編譯後

.h1 {
  font-size: 48px;
}
.h2 {
  font-size: 26px;
}
.h3 {
  font-size: 26px;
}

if()、and、or、not

接下來是有關布林值的判斷式,這邊的 if() 與上面不同,但也相當好用

  • if($condition, $if-true, $if-false): 共有三個參數,分別為判斷式true值false值
  • and: 同 javascript 中的 &&,兩邊都須為 true
  • or: 同 javascript 中的 ||,僅有一邊須為 true
  • not: 同 javascript 中的 !,返回相反值
@debug if(true, 10px, 15px); // 10px
@debug if(false, 10px, 15px); // 15px
@debug true and false; // false
@debug true or false; // true
@debug not true; // false

其他部分

最後是 SCSS 中比較特別的兩個功能,@content@at-root

@content

@mixin 結合 @if@else@else if 判斷條件,再使用 @content 匯入內容,此方式在寫 RWD 的時候很好用,可以依序判斷參數,再做出對應的 CSS

編譯前

@mixin media($screen) {
  @if $screen == desktops {
    @media (min-width: 1200px) {
      @content;
    }
  } @else if $screen == tablets {
    @media (min-width: 768px) {
      @content;
    }
  } @else if $screen == phones {
    @content;
  }
}
html {
  @include media(desktops) {
    font-size: 20px;
  }
  @include media(tablets) {
    font-size: 18px;
  }
  @include media(phones) {
    font-size: 16px;
  }
}

編譯後

html {
  font-size: 16px;
}
@media (min-width: 1200px) {
  html {
    font-size: 20px;
  }
}
@media (min-width: 768px) {
  html {
    font-size: 18px;
  }
}

@at-root

在巢狀內寫入後,會於最外層編譯,若有 @media@supports 則編譯於其內側

編譯前

@media print {
  .list {
    margin: 10px;
    @at-root {
      .item {
        color: blue;
      }
    }
  }
}
.list {
  margin: 10px;
  @at-root {
    .item {
      color: blue;
    }
  }
}

編譯後

@media print {
  .list {
    margin: 10px;
  }
  .item {
    color: blue;
  }
}
.list {
  margin: 10px;
}
.item {
  color: blue;
}

@at-root 可在後方加入參數,withwithout 分別表示包括與不包括,另外還有如下兩個參數

  • all: 所有的規則與樣式
  • rule: 只包含樣式,不包括 @media@supports 等規則

編譯前

@media print {
  @at-root (without: all) {
    .a {
      color: blue;
    }
  }
  @at-root (with: rule) {
    .b {
      color: blue;
    }
  }
  @at-root (with: media) {
    .c {
      color: blue;
    }
  }
}

編譯後

.a {
  color: blue;
}
.b {
  color: blue;
}
@media print {
  .c {
    color: blue;
  }
}

介紹到這邊幾乎所有功能都介紹完哩,再來就是思考如何應用在實戰上囉~


尚未有邦友留言

立即登入留言