[CSS Notes] - 談談CSS模組化

RexHung
10 min readMay 30, 2019

--

關於 CSS

Introduction & 前言

記得剛接觸 CSS 的時候覺得就是替東西加上屬性,沒有什麼特別的困難,因為都是一頁式的頁面,只要一支 all.css 就搞定,所以愛怎麼取名字愛怎麼給屬性就寫,慢慢的頁面多了,all.css 慢慢開始千行起跳了 ( 誤…,這時候開始思考 CSS 是否也能有自己的架構。

為什麼要模組化?

一個有規劃有邏輯的專案,不管是一頁式或是大型專案,都需要有自己個規則還有規範,其中好處之一是自己過了一陣子回來看 Code 亦或是其他人接手案子後也能馬上清楚明白整體的架構及方便改寫,另外就是對於網頁的效能上或多或少都能有所幫助,除此之外還能減少你的工程時間。

Summary & 摘要

因為一直對於 CSS 算是一知半解,加上曾經被說過 CSS 命名跟管理很糟糕,最近在自己亂玩 Webpack 時就胡亂爬文學習 Sass 了,用了一陣子剛好碰上六角學院的 Sass 課程在特價(點我選購XD),瞥見課程說明 懂得設計出一手好 CSS 命名 二話不說就買了,剛好課程內提到模組化,深深覺得很有幫助,就索性紀錄下來,偶爾在 CSS 上碰到難處還能回來看看文章。( 所以有寫錯的地方還請大神們手下留情…

在這邊將會主要提到三個架構,你可以都不用,也可以只用其中一個,重點還是看你自己怎麼樣覺得方便。

  1. SMACSS — 偏向整個專案架構的分類及模組化你的 CSS
  2. OOCSS — 使用物件導向方式管理 CSS Style。
  3. BEM — 關於 Class 的命名方式。

不管哪一個類別,其實其中他們都有相似的地方,因為其中某些觀念都是相似的,所以有重疊的地方是正常的,如果你有自己的規範也能試著使用自己的方式,主要還是自己方便且好維護為主,主要記得四大要點

  1. 可預測性( Predictable )
  2. 可重複使用性( Reusable )
  3. 易維護性( Maintainable )
  4. 可擴充性( Scalable )
SMACSS — 易擴展及模組化

首先談談 SMACSS

全名為( Scalable and Modular Architecture for CSS ) ,顧名思義是可模組化且具結構分類有命名規則的方式,其中的精神就是容易擴展及模組化

官方網站的介紹是免費的,傳送門在此 ( 建議詳讀

基本上的結構分為 Base、Layout、Module、State、Theme

Base — 網頁基本樣式,還有 CSS Reset。

Layout — 像是網頁的 hader、footer、sidebar,如果是唯一的區塊可以使用 id 取名;如果是重複出現一樣使用 Class。

Module — 類似 component ,或是常常出現的區塊內容,比如 .list-li

State — 元件的狀態,例如 .list-li active 最後的 active。

Theme — 樣式,例如 bootstrap 裡的 btn-dark 。

看完結構後,就能知道怎麼命名,命名規則是在前面加上前綴,透過命名我們可以快速找到 CSS 是什麼類別,並且在大型專案中可以迅速找到在哪個文件中。例如 layout 使用 l- 為開頭,State 的部分則使用 is- 作為前綴,Module 則沒有主要的命名規則,因為 Module 名字太長, SMACSS 建議直接使用 Module 的名稱去命名。

講了這麼多架構,你其實只需要明白兩個步驟。

  1. 把你需要常用到的樣式給一個初始值,這邊用 btn 舉例。
.btn {
background-color:white;
border: 2px solid black;
border-radius: 20px;
font-size: 20px;
}

2. 之後其他地方需要用到 button 時,可以再給他第二層的客製樣式。

.btn-danger {
background-color:red;
color: white;
}
.btn-lg {
font-size: 30px;
}

需要用到客製化的地方在加上後面的 .btn-danger class。

這樣一來能有效管理你的 css 命名之外,也不會造成 css 檔案過肥。

子模組

但是在 SMACSS 上還是有許多模糊的界線在,其實善用子模組,能讓你的 Class 清楚且少了重複命名的機率產生。

更詳細的介紹可以參考此網站:傳送門

結構、樣式、容器、內容 — 層層分離

再來談談 OOCSS

( Object Oriented CSS )有兩項基本的原則,結構與樣式分離,容器與內容分離。

OOCSS官方網站:傳送門

其實基本上跟 SMASS 很相近,最好的範例就是 bootstrap 或是 960 Grid。OOCSS 的基本概念在盡量把樣式( CSS )從結構( ul、li、span… )中抽離出來,在把容器( body、container… )跟內容( list-group、page-box… )分開。主要要讓你的 CSS 重複使用性拉高,減少網頁效能上過度渲染造成的速度緩慢後果。

結構與樣式分離

結構與樣式分離

假設我們有一個表單,一般我們給予 span css 的方法會這樣下。但是有一個問題是,今天如果我們要在另一個區塊的 span 導入一樣的 css , 勢必要在下一次 css ,亦或者今天結構變動,我不要 li 了,css 勢必會吃不到。

.content > div > span{
color:blue;
}
把樣式抽離出來 盡量不使用到 HTML Tag

如果我們把這個樣式抽離出來,並且取個名字,盡量不去使用 HTML Tag 這樣就是結構與樣式分離

容器與內容分離

容器與內容分離

這個就比較好懂了,也是盡量避免使用 .left-bar .list-group li span 去命名,除了會造成網頁在渲染時造成效能問題外,如我網頁結構需要變動,那真的是傷透腦筋。

按造上面的取名方法,假如今天 right-bar 需要使用到一樣的 css 我只需要幫他們的 class 加上對應的 css 就好了。

Block、Element、Modifier

最後來談談 BEM

這是我覺得最有用也最讓人一目瞭然的方式,你可以不嘗試 SMACSS 可以不嘗試 OOCSS ,但你一定要試看看 BEMBlock( 區塊 )、Element( 元素 )、Modifier( 修飾符 )

BEM 理念上強調完全使用 Class Selector 並且以功能導向命名。

BEM官方網站:傳送門

Block — 通常表示可獨立的元件,也可以存在於其他 Block 當中。

介紹圖

Element — 這是存在於 Block 之中的小元件,並且不可單獨分離出來,命名也是功能導向,在自己的前方跟 Block 銜接的地方用兩個下底線分開,在自己的名稱斷點使用一個分隔號隔開。

--> Block-name__Element-name // 命名規則--> list-from__content // 範例

Element 可以存在於 Element 裡面,但是必須依賴在 Block 之下。

Element
<form class="list-from">
// 必須依附在 list-from 這個 Block 之下
<div class="list-from__content">
// 可以存在 content 這個 Element 之下
<input class="list-from__input" />
</div>
</form>
Modifier

Modifier — 這是表述組建的狀態或行為,命名規則上以單底線_或兩橫線- - 。

<form class="list-from">
<div class="list-from__content">
<input class="list-from__input" />
<span class="list-from__span">
<span class="list-from__span--active">
<span class="list-from__span--pink">
</div>
</form>

關於 BEM 官方有一套 CSS 分類方式,每一個 Block 都會有自己的資料夾路徑,並且裡面有這個 Block 的專屬 CSSJS。裡面還會有這個 Block 下方 Element 的資料夾,並且開頭為 __ 。

list-from/  list-from.css
list-from.js
__content/ list-from__content.css
list-from__content.js
__input/ list-from__input.css
list-from__input.js
__span/ list-from__span.css
list-from__span.js
_theme/

list-from__span--active.css
list-from__span--pink.css

詳細可以拜讀此篇文章:傳送門

幾個重點整理:
1. Block 對應一個資料夾,命名相同,每個 Block 資料夾下面都有獨立的 JS CSS 檔案。

2. Element 的資料夾命名採雙底線開頭,但是檔案命名一樣要加上Block名稱。

3. Modifier 採單底線,並且 Modifier 下通常只有 CSS 檔案。

學習小筆記

Conclusion & 結論

在學 Code 時矇懞懂懂,一開始也不知道有什麼規範規則,這次拜六角學院課程所賜,索性研究了一下關於 CSS 的架構,在之後的練習及專案都會試著導入 SMACSS OOCSS BEM 等等的架構,並且試著找尋最適合自己的方式。

還是那句老話『沒有最好,只有最適合』,希望在成長的這一路上或多或少能幫助到某些在困惑的人,也照著自己最初寫 Blog 的初衷,用 Blog 紀錄自己的成長及缺點,再一段時間之後再回來檢討自己,也希望成長後的我,能幫助到剛開始成長的你。

從最剛開始的六角地下城開始,慢慢的練習 JS Vue.js ,誤打誤撞研究 Webpack 之後現在慢慢學習 Sass ,近期內的目標就是能用所學的這些,做出一個類似電商的網站,期許自己的成長,衝吧!

( 會在努力吸取新知更新 CSS 系列的

最後這邊提供一個自己練習照著 SMACSS OOCSS BEM 架構練習的 Source Code ,因為是自己第一次練習寫,還能希望有大神能不吝嗇指教。

傳送門在此

參考網站

Segmentfault — CSS设计模式:OOCSS 和 SMACSS
Summer。桑莫。夏天 — CSS 的模組化方法:OOCSS、SMACSS、BEM、CSS Modules、CSS in JS
W3C — BEM的定义
六角學院 —Sass 實戰全攻略 — 成為前 1% 的 CSS 頂尖好手

--

--

RexHung

菜雞學Code之路,期許自己哪天能成長茁壯。