# Bootstrap 5 客製化 [Bootstrap Utility API 文檔](https://getbootstrap.com/docs/5.1/utilities/api/#css-variable-utilities) ## 基本配置 **1. 創建資料夾** ``` mkdir 1029 ``` **2. 初始化項目** ``` npm init -y ``` **3. 安裝 Bootstrap** ``` npm i bootstrap ``` **4. 安裝延伸模組 ( Live Sass Compiler )** ![](https://i.imgur.com/tc50wIB.png) **5. 新增一 SCSS 檔 ( custom.scss ),並引入 Bootstrap 必要程式碼** ``` // custom.scss @import "../node_modules/bootstrap/scss/functions"; @import "../node_modules/bootstrap/scss/variables"; // Custom Variables Code @import "../node_modules/bootstrap/scss/utilities"; // Custom Utilities Code @import "../node_modules/bootstrap/scss/bootstrap.scss"; ``` **6. 儲存後,點擊 Watch Sass 編譯出 CSS 檔 ( custom.css )** ![](https://i.imgur.com/w5RQZY2.png) **7. 新增一 HTML 檔 ( index.html ),並引入該 CSS 檔** ``` // index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="./scss/custom.css"> </head> <body> ... </body> </html> ``` ## 通用 通用類別變數都加在我們的 `_utilities.scss` 樣式表的 $utilities 變數中。每組通用類別如下所示: ``` $utilities: ( "opacity": ( property: opacity, values: ( 0: 0, 25: .25, 50: .5, 75: .75, 100: 1, ) ) ); ``` 輸出: ``` .opacity-0 { opacity: 0; } .opacity-25 { opacity: .25; } .opacity-50 { opacity: .5; } .opacity-75 { opacity: .75; } .opacity-100 { opacity: 1; } ``` ## 變數 文檔中有提到應避免修該 Bootstrap 的核心文件,所以我認為不應該直接更改在`_variables.scss`樣式表中 * **撰寫位置** ``` @import "../node_modules/bootstrap/scss/functions"; @import "../node_modules/bootstrap/scss/variables"; // Custom Variables Code $box-shadow-xl: 0 1rem 3rem rgba($black, .175); @import "../node_modules/bootstrap/scss/utilities"; . . . ``` * **新增** ``` $theme-colors: ( "custom-color": #900 ); ``` * **修改** ``` $theme-colors: ( "primary": #0074d9, "danger": #ff4136 ); ``` * **刪除** ``` $theme-colors: map-remove($theme-colors, "info", "light", "dark"); ``` ## 屬性 使用 **property** 屬性指定合法的 CSS 屬性,若 **class** 屬性被忽略,則做為 **class** 屬性的預設值,此屬性為**必須** ``` $utilities: ( "text-decoration": ( property: text-decoration, values: none underline line-through ) ); ``` 輸出: ``` .text-decoration-none { text-decoration: none !important; } .text-decoration-underline { text-decoration: underline !important; } .text-decoration-line-through { text-decoration: line-through !important; } ``` ## 屬性值 使用 **values** 屬性指定特定 **property** 的名稱和規則,此屬性為**必須** * 作為 **List** ``` values: none underline line-through ``` * 作為 **Map** ``` values: ( 0: 0, 25: .25, 50: .5, 75: .75, 100: 1, ) ``` * 作為 **Sass Variables** ``` values: $position-values ``` ## 前綴 使用 **class** 屬性更改已編譯 CSS 中所使用的 class 前綴,若 **class : null** 則沒有前綴 ``` $utilities: ( "opacity": ( property: opacity, class: o, values: ( 0: 0, 25: .25, 50: .5, 75: .75, 100: 1, ) ) ); ``` 輸出: ``` .o-0 { opacity: 0; } .o-25 { opacity: .25; } .o-50 { opacity: .5; } .o-75 { opacity: .75; } .o-100 { opacity: 1; } ``` ## 狀態 使用 **state** 屬性來生成偽類 ( 若需使用多個偽類則使用空格分隔 ) ``` $utilities: ( "opacity": ( property: opacity, class: opacity, state: hover, values: ( 0: 0, 25: .25, 50: .5, 75: .75, 100: 1, ) ) ); ``` 輸出 : ``` .opacity-0-hover:hover { opacity: 0; } .opacity-25-hover:hover { opacity: .25; } .opacity-50-hover:hover { opacity: .5; } .opacity-75-hover:hover { opacity: .75; } .opacity-100-hover:hover { opacity: 1; } ``` ## 響應式 添加 **responsive** 屬性以生成橫跨所有斷點的響應式通用類別 ``` $utilities: ( "opacity": ( property: opacity, responsive: true, values: ( 0: 0, 25: .25, 50: .5, 75: .75, 100: 1, ) ) ); ``` 輸出: ``` .opacity-0 { opacity: 0; } .opacity-25 { opacity: .25; } .opacity-50 { opacity: .5; } .opacity-75 { opacity: .75; } .opacity-100 { opacity: 1; } @media (min-width: 576px) { .opacity-sm-0 { opacity: 0; } .opacity-sm-25 { opacity: .25; } .opacity-sm-50 { opacity: .5; } .opacity-sm-75 { opacity: .75; } .opacity-sm-100 { opacity: 1; } } @media (min-width: 768px) { .opacity-md-0 { opacity: 0; } .opacity-md-25 { opacity: .25; } .opacity-md-50 { opacity: .5; } .opacity-md-75 { opacity: .75; } .opacity-md-100 { opacity: 1; } } @media (min-width: 992px) { .opacity-lg-0 { opacity: 0; } .opacity-lg-25 { opacity: .25; } .opacity-lg-50 { opacity: .5; } .opacity-lg-75 { opacity: .75; } .opacity-lg-100 { opacity: 1; } } @media (min-width: 1200px) { .opacity-xl-0 { opacity: 0; } .opacity-xl-25 { opacity: .25; } .opacity-xl-50 { opacity: .5; } .opacity-xl-75 { opacity: .75; } .opacity-xl-100 { opacity: 1; } } @media (min-width: 1400px) { .opacity-xxl-0 { opacity: 0; } .opacity-xxl-25 { opacity: .25; } .opacity-xxl-50 { opacity: .5; } .opacity-xxl-75 { opacity: .75; } .opacity-xxl-100 { opacity: 1; } } ``` ## CSS 變數 使用 **css-var** 屬性,會產生 CSS 變數 ( 應該是根據 class 值 ),用以代替 **property: value** 屬性 ``` $utilities: ( "text-opacity": ( css-var: true, class: text-opacity, values: ( 25: .25, 50: .5, 75: .75, 100: 1 ) ), ); ``` ## 覆蓋 使用 **相同 key** 覆蓋現有通用類別 ``` @import "bootstrap/scss/functions"; @import "bootstrap/scss/variables"; @import "bootstrap/scss/utilities"; $utilities: ( "overflow": ( responsive: true, property: overflow, values: visible hidden scroll auto, ), ); @import "../node_modules/bootstrap/scss/bootstrap.scss"; ``` ## 加入 可以透過 **map-merge** 將新的通用類別加入到預設的 $utilities map ``` @import "bootstrap/scss/functions"; @import "bootstrap/scss/variables"; @import "bootstrap/scss/utilities"; $utilities: map-merge( $utilities, ( "cursor": ( property: cursor, class: cursor, responsive: true, values: auto pointer grab, ) ) ); @import "../node_modules/bootstrap/scss/bootstrap.scss"; ``` ## 修改 使用 **map-get 和 map-merge 函式** 修改 $utilities map 中預設的通用類別 ``` @import "bootstrap/scss/functions"; @import "bootstrap/scss/variables"; @import "bootstrap/scss/utilities"; $utilities: map-merge( $utilities, ( "width": map-merge( map-get($utilities, "width"), ( values: map-merge( map-get(map-get($utilities, "width"), "values"), (10: 10%, 20: 20%), //以此類推 ), ), ), ) ); @import "../node_modules/bootstrap/scss/bootstrap.scss"; ``` ## 開啟響應式 使用此 API 可以將目前關閉 responsive 屬性的通用類別啟動 ``` @import "bootstrap/scss/functions"; @import "bootstrap/scss/variables"; @import "bootstrap/scss/utilities"; $utilities: map-merge( $utilities, ( "border": map-merge( map-get($utilities, "border"), ( responsive: true ), ), ) ); @import "../node_modules/bootstrap/scss/bootstrap.scss"; ``` ## 重新命名 使用此 API 可以覆蓋該通用類別的 **class** 屬性 ``` @import "bootstrap/scss/functions"; @import "bootstrap/scss/variables"; @import "bootstrap/scss/utilities"; $utilities: map-merge( $utilities, ( "margin-start": map-merge( map-get($utilities, "margin-start"), ( class: ml ), ), ) ); @import "../node_modules/bootstrap/scss/bootstrap.scss"; ``` ## 刪除 透過 **將鍵值設置為 null** 以刪除任何通用類別 ``` @import "bootstrap/scss/functions"; @import "bootstrap/scss/variables"; @import "bootstrap/scss/utilities"; $utilities: map-merge( $utilities, ( "width": null ) ); @import "../node_modules/bootstrap/scss/bootstrap.scss"; ```