# CSS設計模式 CSS是個較基礎的語言,因此使用頻率較高。 這也代表在越大型越複雜的系統中,CSS的撰寫句數越多,越不好維護。 所以衍伸出了許多理論與方法,就是為了提高可讀性、延展性、效率...等。 一個良好的css設計應具有以下特點: 1. 結構清晰 => 提高可讀性 2. 可重用性 => 減少重複樣式 3. 避免污染 => 限定樣式範圍 4. 響應式 => 適應不同裝置 5. 易擴展 => 提高維護性 6. 標準化 => 保持統一風格 7. 優化效能 => 減少 CSS 大小 以下介紹一些CSS設計理論 ## 1. 物件導向 CSS:OOCSS By Nicole Sullivan ### Sperate Structure & Skin - 分離結構與顏色 > 即將顏色樣式與大小樣式分離,針對元素中的顏色的樣式單獨抽出做分離,避免重複性高的 CSS。 這樣不好❌ .box-1 { width: 200px; height: 200px; background-color: yellow; border: 1px solid black; box-shadow: rgba(0, 0, 0, 0.5) 2px 0px 2px; } .box-2 { width: 320px; height: 400px; overflow: hidden; background-color: yellow; border: 1px solid black; box-shadow: rgba(0, 0, 0, 0.5) 2px 0px 2px; }; .button { width: 120px; height: 48px; background-color: yellow; border: 1px solid black; box-shadow: rgba(0, 0, 0, 0.5) 2px 0px 2px; } 可以改成這樣寫✔️ .box-1 { width: 200px; height: 200px; } .box-2 { width: 320px; height: 400px; overflow: hidden; }; .button { width: 120px; height: 48px; } .skin { background-color: yellow; border: 1px solid black; box-shadow: rgba(0, 0, 0, 0.5) 2px 0px 2px; } ### Sperate Container & Content - 容器與內容分離 > 分離 html 與 css,盡量將可共用的 class 單獨分離出來,這樣好處是若有多處重複的樣式,可使用同一個 class。 範例:box 內有一個標題跟一個內文,標題內有一部分特殊樣式: 這樣不好❌ .box-1 div { color: red; } .box-1 p { color: black; } .box-1 div span { color: green; } 改成這樣✔️ .title { color: red; } .content { color: black; } .green-text { color: green; } > 範例: <button class="btn btn-primary btn-large"></button> btn: 按鈕的基本樣式 | btn-primary: 按鈕的顏色 | btn-large: 按鈕的大小 透過這樣分離的方式,來讓網頁樣式更便於管理、可讀性高、好維護的效果。 ## 2. SMACSS(Scalable and Modular Architecture for CSS) > 顧名思義就是可擴展與模組化的設計模式。 基本架構: 1). Base - 預設樣式,在寫程式碼前就思考了 2). Layout - 主要組件,使用id定位 3). Module - 次要組件,使用class定位 4). State - 狀態,使用is前綴、使用 JavaScript DOM 事件為class,允許使用 !important 5). Theme - 根據主題抽離樣式 ### 1). Base 包含 reset CSS 與 HTML tag 常用的樣式設定。 >你應該有聽過、甚至使用過 reset CSS, 若不知道是什麼的話,我來解釋一下,由於瀏覽器預設會有一些 CSS 樣式(例如:間距),所以為了確保畫面樣式的一致性及達到設計需求,通常我們在 CSS 最前面放上 reset CSS,把一些 padding、margin 給清空。 # reset css body, html { padding: 0,; margin: 0, } # html tag 常用設定 input { outline: none; } a:focus { text-decoration: none; } ### 2). Layout 每頁都會出現的元素(主要組件):header、footer 通常會使用 ID 選擇器 #header, #article, #footer { width: 960px; height: auto; } #article { border: solid #CCC; border-width: 1px 0 0; } ### 3). Module 兩頁以上會出現的元素(次要組件):form、navigation item 之類的 避免使用 ID 和元素選擇器,只使用 class,每個組件內可能都會有個別的元素,當內部有多個元素,推薦使用各自的class <div class="fld"> <span class="fld-name">Folder Name</span> <span class="fld-items">(32 items)</span> <span class="fld-items">(32 items)</span> </div> <style> .fld { padding-left: 20px; background: url(icon.png); } .fld-name { font-size: 24px; color: orange; } .fld-item { font-size: 14px; color: rgb(var(--r-link-color)); } </style> ### 4). State 元素的狀態 1. 可使用 is 前綴符 2. 使用 JavaScript DOM 事件來為元素加上 class 3. 允許使用 !important,因為作者認為一個元素同時不會存在兩個狀態。 ### 5). Theme 根據不同主題單獨抽離樣式的設計方法,以下範例可以看到,有三個 css 檔案, all.css:主要管理主題間共同的樣式 theme-morning.css: 定義 morning 主題的樣式 theme-night.css: 定義 night 主題的樣式 此架構可以讓主題可以切開來,按照需求引入主題檔案 morning 主題:引入 all.css 與 theme-morning.css night 主題:引入 all.css 與 theme-night.css ### all.css .mod { border: solid 1px } ### theme-morning.css .mod { border-color: white } ### theme-night.css .mod { border-color: black } ## 3. BEM > Block(區塊)-Element(元素)-Modifier(修飾子) > Element 使用雙底線做分隔,Modifier 使用雙 dash 做分隔。 menu 是區塊,menu__item 是 menu 的元素,active 是 menu__item 的一種狀態。 ❌ <ul class="menu"> <li class="item"></li> <li class="item active"></li> <li class="item"></li> </ul> ✔️ <ul class="menu"> <li class="menu__item"></li> <li class="menu__item menu__item--active"></li> <li class="menu__item"></li> </ul> ## 4. CSS in JS >隨著前端框架的出現,前端的開發逐漸 component 化,一個頁面的個別元素可以切分 component + 像是Vue的style scope,就可以將元件的樣式、事件、結構都封裝在此檔案中。 > 特別講一下,style 中的 scope 代表 Vue 會對該元件生成一個隨機的屬性(Attribute),透過 CSS Attribute selector 的方式來做到 CSS 的切分,這樣在不同的元件中的 div 樣式就不會互相干擾囉 + 此外,還有React使用的styled-component,可將css控制在檔案內 ## 5. 原子化樣式(Atomic CSS) >Thierry Koblentz (Yahoo!)在 2013 年挑戰 CSS 最佳實踐中首次使用,將樣式的名稱指向每個單獨的 class ,並把名稱縮小化,將結構 html 與樣式 css 結合,當按鈕的樣式需要修改的時候,我們修改的是 HTML 而不是 CSS。 >我個人的理解是像是OOCSS中的Sperate Structure & Skin,並且將class名稱修改成自己格式的縮寫 .fw-14 { font-weight: 14px; } .pl-6 { padding-left: 6px; } #### 後來誕生的 CSS 框架 tailwindcss 提出了一個命名規範,並可以自行擴充樣式。 ##### Tailwindcss 優缺點比較 優點 + 不需要去想 CSS 命名 + CSS 樣式的量通常不會變多,因為很少在撰寫 CSS 檔案了,共用性高 + 修改樣式只需要修改 HTML + 沒有使用到的 CSS 將會在生產環境編譯時清除,達到輕巧化 缺點 + 需要學習一個既定的命名約定 + HTML 會變得更加龐大 --- 最後感謝,諸多前輩整理的重點,我節錄了當中很多的內容 {%preview https://rock070.me/notes/css/2021-10-07-css-pattern#%E4%B8%80%E7%89%A9%E4%BB%B6%E5%B0%8E%E5%90%91-cssoocss-by-nicole-sullivan %}