Css設計心法教學-SMACSS、OOCSS、BEM
前言:
其實網路上已經有很多文章在介紹SMACS、OOCSS、BEM,而這篇文章存在的目的,就是以一個新手的角度來試著理解這三大架構如何幫助我們管理CSS。
OK,在開始介紹前,我們必須了解到這些設計方法存在的目的是為了方便管理Css所衍伸出來的。而所謂好的CSS撰寫該包含哪些特性呢?
良好Css架構應包含
1.預測-Predictable
2.複用-Reusable
3.維護-Maintainable
4.延展-Scalable
先記住這幾項原則後,我們來分別簡略介紹這三大設計法則
- OOCSS (Object OrIEnted CSS)
設計基本原則有兩大點:
- 結構與樣式分離(Reusable)
- 內容與容器分離(Scalable)
結構與樣式分離 參考卡斯柏老師圖解
說明:
結構可以看成button中的width、height、padding等基本結構;樣式則可以看成外觀表現上如:border、background-color
案例:
--從下面程式碼,我們可以發現button、box有部分css內容是重複的,這樣撰寫的話會造成日後若要調整顏色、外框粗細等樣式不便。此外,重複的css也造成檔案肥大。
#button {
width: 200px;
height: 50px;
padding: 10px;
border: solid 1px #ccc;
background: linear-gradient(#ccc, #222);
box-shadow: rgba(0, 0, 0, .5) 2px 2px 5px;
}
#box {
width: 400px;
overflow: hidden;
border: solid 1px #ccc;
background: linear-gradient(#ccc, #222);
box-shadow: rgba(0, 0, 0, .5) 2px 2px 5px;
}
因此,我們藉著套用結構與樣式分離原則,來試著改寫下面這段Css
//css程式碼的複用性就提高了
.button {
width: 200px;
height: 50px;
}
.box {
width: 400px;
overflow: hidden;
}
.style {
border: solid 1px #ccc;
background: linear-gradient(#ccc, #222);
box-shadow: rgba(0, 0, 0, .5) 2px 2px 5px;
}
內容與容器分離 卡斯柏老師講解
說明:將HTML結構與Css盡量切割開來,以可共用的css selector來設計css
案例:
我們先定義header下的h1的樣式
.header h1{
font-size:2rem;
color:#00cc99;
}
這時footer中若也要套用相同文字大小,但不同顏色的文字的話,你可能會這樣寫
.header h1,.footer h1{
font-size:2rem;
color:#00cc99 ;
}
.footer h1{
color:blue;
}
你會發現撰寫上,需要再針對顏色再多撰寫css,如此重複性撰寫未來在維護上是一種問題,因此我們可以這樣改寫
//html部分
<div class="header fontSize-l"></div>
<div class="footer fontSize-l"></div>
//css部分
.fontSize-l {
font-size: 2rem;
}
.header {
color: #00cc99
}
.footer {
color: blue;
}
- SMACSS (Scalable & Modular Architecture for CSS)
- Categorizing CSS Rules(為CSS分類)
- Naming Rules(命名規則)
- Minimizing the Depth of Applicability(最小化適配深度)
依結構來區分
--共分為五種:base、layout、module、state、theme
- Base:主要拿來設計全站基礎樣式,也包含CSS Reset。
命名方式:只會用element tag selector
例如:
html{
background: $bg-white;
}
h1,h2,h3{
margin: 1em 0;
}
參考:pure.css base 連結
- Layout
將網頁切成不同區塊,諸如header、sidebar、content。因為這些大型區塊在網頁上通常都是獨立出現,故命名上可以使用ID。但若遇到重複區塊,可以使用Class層疊特性,將屬性權重往上提升。
#article {
width: 80%;
float: left;
}
#sidebar {
width: 20%;
float: right;
}
// layout固定大小(compare to 滿版)
.l-fixed #sidebar {
width: 200px;
}
命名原則:
1.用l-或layout-這樣的前綴,例如:.l-header、.l-sidebar
2.減少語意化命名(目的:可以挪為其他專案使用如下)
.booklist{
padding: 10px;
}
// 調整成可通用
.list{
padding: 10px;
}
- Module
跟Layot相似,也是頁面上的區塊(較小的區塊內容如:navbar),這邊的區塊更為獨立,可以適用不同專案。
命名方式:只能用class selector命名,並且使用dash分隔。
如:modal-body、modal-img(子模組設計概念,基本上就是bootstrap設計概念)
禁止使用ID、element selector
// 用 dash 分隔 class (subclassing/submodule)
.modal-body {
width: 100%;
}
.modal-header {
height: 50px;
width: 100%;
}
- State
描述元件狀態,因此命名上,針對該狀態的描述越精準越好。State和Module最大差別在於:State可以覆蓋Module/Layout的Style、State通常會搭配JS做使用
命名方式:用is-前綴,例如:.is-active、.is-hidden
.tab {
background-color: purple;
color: white;
}
.is-tab-active {
background-color: white;
color: black;
}
- Theme
針對網站主視覺色彩、文字大小樣式做定義
命名方式:用theme-前綴,例如.theme-a-background、.theme-a-shadow。
// in module-name.css
.mod {
border: 1px solid;
}
// in theme.css
.mod {
border-color: blue;
}
優點:
根據其結構化管理CSS、可以增加專案協作可維護性(可重用性、可延展性)
缺點:
Css較為龐大
- BEM命名方式 BEM官網連結
通常會搭配Sass處理器一起執行~
說明:Bem就是由區塊(block)、元素(element)、修飾符(modifier)所組成
目的:幫助後續管理程式碼,了解區塊與元素之間是否有關係。讓你在瀏覽HTML CODE時,能夠透過觀察class,就能了解你的CSS架構,不用再回去追CSS Code才辨別得出哪些是Layout、Modifier
一、寫法介紹:
.block{} //區塊 (Block)
.block__element{} //元素 (Element)
.block--modifier{}//修飾符(Modifier)
- 區塊(Block)
--網頁上單獨可拿來複用的區塊,如Bootstrap中Components區塊設計概念。
舉個簡單例子:Card元件就是一個區塊元件
小結:
通常為頁面上獨立元件,可以被重複使用
- 元素 (Element)
我們由下面這張圖片來說明一下,可以發現元素是屬於區塊中底下。重點不能單獨拿出去別的區塊使用,專屬於這個Menu區塊。例如:
<div class="card" style="width: 18rem;">
<img src="..." class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
<a href="#" class="btn btn-primary">Go somewhere</a>
</div>
</div>
小結:
需配合block使用,主要用來描述目的
- 修飾符(Modifier)
當區塊或元素因為狀態而改變時,就在後面加上雙中線--來辨識它是修飾符,
像是下圖選單的部份,當被點選時為了要讓使用者了解該元素有被點選,
所以就會用javascript動態加入class為.menu__item--active
主要用來描述狀態 EX:顏色、大小
例如:
<li class="nav-item active">
<a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
</li>
2.1可以獨立成為一個class,具有複用性
當我們網站內容有個CSS設定時常會用到其他地方時,就會把他獨立成一個class名稱提升他的複用性。
EX:清除浮動 .clearfix{clear:both},
或者是置左功能.pull-left{float:left}。
2.2並不是所有的元素都要遵守BEM的規則
假設來說我.content裡面有個選單元素,
所以你就寫了.content__menu,但你必須去了解這個元素是否會在表尾、側欄其他地方出現,如果會的話,那就應該是從.menu當做一個區塊來向內延伸設計把它變成一個Module模組。(SMACSS設計規範)
3.搭配scss語法撰寫
.media{
width: 100px;
&__input{
width: 100px;
&--color{
background: green;
}
}
}
結論:
強烈建議讀完整篇文章後,一定要拿相關作品來設計,如此才能確實掌握設計精髓。
參考資料:
留言
張貼留言