CSS 設計模型研究&比較
CSS 設計模型研究&比較

CSS 設計模型研究&比較

Tags
CSS
SCSS
Design Pattern
Author
Published
Published July 8, 2022

SCSS設計模式研究結果

Color 參數正名

在寫程式上大家都會用RGB()或是hex色碼填入顏色,但在人類眼中,並不會看到一串 #CCCCCC 腦袋中就會轉換成顏色的吧 😆。
 
所以在 SASS/SCSS 中,可以用 $var 來為這些色碼取名字,在跟需求或UI/UX討論前先定義好已知會用到的顏色,溝通會順利須多。
 
在SCSS中,也可以設定為 config 的方式,在撰寫程式上會比較像是 functional 的感覺
 
在CSS中也可以用 --var 定義不同的顏色名稱,如果只需要命名功能可以只用 css 就好,殺雞焉用牛刀🔪
 
$color_ok: #87D06A; $color_line: #00B900; $color_info: #D0B69F; $color_hint: #908580; $color_error: #CA5940; $color_vital: #F9EDE9; $color_cancel: #707070; $color_accent: #E8F0E4; $color_primary: #3E3A39; $color_warning: #FDAF32; $color_unusual: #62B7FF; $color_secondary: #899185; $color_line_act: #00AA00; $color_primary_act: #5D5857; $color_secondary_act: #62695E; $color_grey_1: #BFBFBF; $color_grey_2: #DDD; $color_grey_3: #E5E5E5; $color_grey_4: #EEEEEF; $color_0: #eeeef1; $color_2: #383635; $color_3: #9fa0a0; $color_6: #4d4d4d; $color_8: #8b9187; $color_9: #6c6c6c; $color_10:#F4F4F4; $color_12:#C4C4C4; $color_13:#999493; $color_17:#8991854d; $color_20:#272f4b;
$color_config:( ok: #87D06A, line: #00B900, info: #D0B69F, hint: #908580, error: #CA5940, vital: #F9EDE9, cancel: #707070, accent: #E8F0E4, primary: #3E3A39, warning: #FDAF32, unusual: #62B7FF, secondary: #899185, line_act: #00AA00, primary_act: #5D5857, secondary_act: #62695E, grey_1: #BFBFBF, grey_2: #DDD, grey_3: #E5E5E5, grey_4: #EEEEEF )

CSS設計模式研究

💡
並不一定只能使用一個,可以混用,看哪個對大家跟系統最有利就用他們吧!

7-1 Pattern

 
7-1 Pattern 是將樣式依據他會在那個範圍用到,以及用到他的組件或 HTML 會在那邊呈現,來設計一套資料夾分類,將可能會共用道的樣式都依照這邊的資料夾做分類,在維護上可以更快速的找到他。
 
notion image
筆者在使用時對這些分類的想法會是這些
  • base: functional css 簡單通用型css組合
  • component: 模組化的css,像是按鈕
  • layout: nav bar、footer項目的css
  • utils: 參數化,需要預先載入給其他sass檔案使用的css樣式
  • vendors: 修改第三方畫面套件的畫面
 

Functional CSS

用 class 做成單一的 css ,在HTML直接引用多個 class 來呈現
 
 
目標
  1. 減少每個組件中樣式的複雜度
  1. 提升單一 css 通用性
優點:
  1. 所有單一css都class化減少重複css撰寫
  1. 階層與HTML放在一起,減少跳躍HTML與樣式互相查看
缺點:
  1. HTML中class過於攏長
  1. 在pug中辨識度不高
特色:
將會用到的css抽成一行多單多行的css class,在寫html時就可以直接套上想要得效果,由於大部分的class中只有一行的css,所以在觀看上可以根據class名稱就知道該css效果。
// 正常 .o-fw-normal { font-weight: 400; }; .o-fw-500 { font-weight: 500; }; // 粗體 .o-fw-bold { font-weight: 700; }; .o-fw-900 { font-weight: 900; };
<div class="o-br-8"> <div class="o-fw-normal">normal: 我是文字 ABC 123</div> <div class="o-fw-500">500: 我是文字 ABC 123</div> <div class="o-fw-bold">bold: 我是文字 ABC 123</div> <div class="o-fw-900">900: 我是文字 ABC 123</div> </div>
.o-br-8 .o-fw-normal normal: 我是文字 ABC 123 .o-fw-500 500: 我是文字 ABC 123 .o-fw-bold bold: 我是文字 ABC 123 .o-fw-900 900: 我是文字 ABC 123

OOCSS

用物件的方式來處理重複使用的組件或畫面,首先 我們先建立了一個config清單,就是一份 config 設定,未來要擴充不用再寫落落長的 code,只要在這裡新增 config 就好
$btn-config:( primary:( class: "primary", font-color: white, h-font-color: white, color: $color_primary, h-color: $color_primary_act, outline: false ), outline-primary:( class: "ol-primary", color: $color_primary, h-color: $color_primary_act, outline: true ) );
接著我們來看這個長長的這段 %開頭這個是什麼 可以把它當成Java裡面的抽象類別,他本身不會被使用,而是要向下方被 extend 實體後 才會被套用
再來下面的default-btn 跟outline-btn 要分成兩個是因為他們的樣式對於某些部分有差異。
%btn { width: 100%; display: flex; justify-content: center; } %default-btn { @extend %btn; &.disabled, &[disabled], fieldset[disabled] & { background-color: $color_grey_2 !important; color: white !important; } } %outline-btn { @extend %btn; &.disabled, &[disabled], fieldset[disabled] & { background-color: white !important; color: $color_grey_2 !important; } }
由於上面我們是寫出按鈕不太會變動的部分,而有些東西是需要依照 config 內容去改變的,我在這裡新增了兩個 mixin 來將我們要的按鈕產出。但是到這裡為止這裡也都還是包好 mixin 的狀態,接著就要透過 config 清單來成立我們的實體class。
@each $name, $value in $btn-config { $class: map-get($value, class); $color: map-get($value, color); $h-color: map-get($value, h-color); $outline: map-get($value, outline); .o-btn-#{$class}{ @if $outline { @include outline-btn($color, $h-color); } @else { $font-color: map-get($value, font-color); $h-font-color: map-get($value, h-font-color); @include default-btn($font-color, $h-font-color, $color, $h-color); } } }
現在建完了每一個樣式,但有時候這些組建樣式會因為 RWD 變成大的或小的,因此要來新增附加樣式,回來看到前面 %btn 內,簡單來說就是讓他可以在內部去控制附加參數樣式,其他的變動也都是相類似的方式,並且要讓他們可以使用組合技
%btn { &.o-btn-sm { padding: 12px 10px; line-height: 14px; font-size: 14px; font-weight: 400; border-width: 1px; &.o-btn-spacing { letter-spacing: 15px; text-indent: 15px; padding-right: 4px; padding-left: 4px; } icon, .icon { height: 14px; &:before { font-size: 14px; } } } // ...省略 }
優點:
  1. 模組化應用,套用快速,且適合製作許多組合技
缺點:
  1. html的css會過於攏長,並且辨認度降低
  1. 全局class會很大包

CSS Module feat. 類OOCSS

可以先從這裡理解一下 CSS Module: https://denny.qollie.com/2016/01/09/css-modules/
而在vue裡面,這是個預設就有個模式,而他在套用的時候會自動把class名稱以bem的命名模式命名,比免重覆,下面的檔案style告訴她用moule 這時候開始 class的套用 就會交由js來處理,要透過$style這個隱性的computed參數來管理,也因為他在computed內,可從js去控制、讀取。
<template lang="pug"> #TestPage a(:class="[$style.btn]") 登出 </template> <script> export default { name: "TestPage", mounted() { console.log(this.$style); } }; </script> <style lang="scss" module> .btn {} </style>
接著 css module還有一個特殊的功能叫做composes 他可以將你寫好的其他module的class放進來
像是下面,這樣當套用了.btn , css module會自動幫忙在套上.red,而且可以套多個
composes一定要在第一句設定
.red {color: red;} .outline {border: 1px solid black;} .btn {composes: red;} .outline-btn {composes: red outline;}
.btn { composes: red from "./color.module.scss"; }
如果寫了一個scss檔案,他要是module的話,副檔名要叫做.module.scss
優點:
  1. 由於可由js控制,非常好進行操作
缺點:
  1. js參數上會有一大包沒有使用的class(以目前的做法)
  1. 在專案上鮮少遇到這樣使用的人