iT邦幫忙

2021 iThome 鐵人賽

DAY 22
0
自我挑戰組

30 天轉生到 bootstrap 5 的意識界系列 第 22

第 22 集:Bootstrap 客製化 utilities(下)

  • 分享至 

  • xImage
  •  

此篇延續 Bootstrap 客製化 Sass utilities(上)最後尚未介紹的 generate-utility,解析 generate-utility 是如何生成通用類別樣式。

generate-utility

generate-utility 來自於 mixins/_utilities.scss 這隻主要生成通用類別樣式的檔案。

主要分為三個區塊來解析

第一區塊:取 values 參數

取得 utilities 資料中 values 的值,並透過迴圈讀取出來,若 $values 不是 map 型態,則會將其轉換為 list 型態(為了讓最後生成通用類別樣式時可以取得到 key, value)。

@mixin generate-utility($utility, $infix, $is-rfs-media-query: false) {
  $values: map-get($utility, values);

  @if type-of($values) == "string" or type-of(nth($values, 1)) != "list" {
    $values: zip($values, $values);
  }
}
  • 透過回圈讀取 $values 內的 api 設置參數。
@each $key, $value in $values {
}

第二區塊:取得其它參數

property

property 為要產生的 css 屬性名稱,型態為字串或陣列。

判斷型態是否為字串:

  • 由於後續生成樣式使用迴圈讀 $properties 的方式進行,因此若型態為字串(只有一個屬性),則透過append 將 property 值插入到空白陣列中。
@if type-of($properties) == "string" {
  $properties: append((), $properties);
}

$property-class css 屬性對應的通用類別名稱。(ex:font-size 對應 fs

判斷參數中是否有設置 class 參數

  • true:取 class 值作為通用類別名稱開頭。
  • false:取 $properties 陣列的第一個元素作為通用類別名稱開頭。

$property-class 值為 null 則賦予空字串。

$property-class: if(map-has-key($utility, class), map-get($utility, class), nth($properties, 1));
$property-class: if($property-class == null, "", $property-class);

state

偽類 Pseudo-classes 參數。(ex::hover:focus

$property-class 值為 null 則賦予空陣列, @each 遇到空置列則不會執行回圈。

$state: if(map-has-key($utility, state), map-get($utility, state), ());

沒看到 Bootstrap 原始碼使用到,但看了一下生成通用類別的方法,想到了有趣的靈感。

state 使用特性:

  • css 屬性設置方式和一般通用類別相同。
  • class 名稱會在後方加上 :state 名稱。(ex::hover

利用 state 特性,來針對某個 css 屬性,設置對應的偽類樣式。

舉例滑鼠移過 container-fluid 元素時就改變背景顏色。


"container-fluid-hover": (
  property: background-color,
  state: hover,
  class: container-fluid,
  values: (
    "index": $dark;
    "product": $light;
  )
),

編譯後的樣式

  • 這樣只要使用對應的 .container-fluid-*hover 樣式就有 hover 效果了。
.container-fluid-index-hover:hover {
  background-color: $dark
}
.container-fluid-product-hover:hover {
  background-color: $light
}

優勢:

  • 可以縮減撰寫樣式的 scss 檔。

注意兩個前提:

  1. 除非原本的樣式原生的通用類別就有。
  2. 除非自己撰寫的樣式,類似的有複數以上。

若不符合上述前提,就沒有達到 縮短程式碼 這個目的,其實直接把偽類樣式寫在原本樣式的後方即可。


$infix

判斷有取得斷點的且 $property-class"" 的情況下,就將 $infix 前方的 - 符號拿掉後並覆蓋 $infix 值。

$infix: if($property-class == "" and str-slice($infix, 1, 1) == "-", str-slice($infix, 2), $infix);

property-class-modifier

判斷若 $value 的 key 值等於 null,則不加通用類別前綴字。

舉例 border

  • 是 null:border
  • 不是 null:border-0

通常用來作為 css 屬性的預設樣式。(ex:border、rounded、shadow)

$property-class-modifier: if($key, if($property-class == "" and $infix == "", "", "-") + $key, "");

rfs

判斷是否有設置響應式,隨著視窗大小計算適合的尺寸。(這邊先跳過,之後有緣再來寫一篇 rfs 計算方式)

@if map-get($utility, rfs) {
  @if $is-rfs-media-query {
    $val: rfs-value($value);

    $value: if($val == rfs-fluid-value($value), null, $val);
  }
  @else {
    $value: rfs-fluid-value($value);
  }
}

第三區塊:生成樣式

將以上取得的參數,組合起來產生通用類別的樣式。

生成的通用類別分為兩種:

  • 一般通用類別
  • 包偽類通用類別

兩種差別在於,是否有設置 state 偽類參數。

$property-class:通用類別前綴字。
$infix:斷點 point。
$property-class-modifier:通用類別 values
參數的 key 值。
$properties: 要執行的 css 屬性。
$value:通用類別 values 參數的 value 值。
$enable-important-utilities:是否在生成通用類別樣式後方加上 !important(預設是 true)。

.#{$property-class + $infix + $property-class-modifier} {
  @each $property in $properties {
    #{$property}: $value if($enable-important-utilities, !important, null);
  }
}

兩種生成樣式後的對照圖

一般通用類別:

含偽類通用類別:

小技巧:

  • 含偽類通用類別的樣式名稱可以把偽類 拿掉,只需移除 -#{$pseudo} 即可。


將修改 BS5 的核心 code 簡單刻了兩個版本 CodePen 連結:


上一篇
第 21 集:Bootstrap 客製化 utilities(上)
下一篇
第 23 集:Bootstrap 客製化 Grid 格線系統
系列文
30 天轉生到 bootstrap 5 的意識界30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言