# 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 %}