Bootstrap 設計模式 - OOCSS

前言

說到 OOCSS 設計模式,最具代表的應用就是 Bootstrap 了!

你可能會想,自己有需要學這個嗎?了解設計模式可以幹嘛呢?我自己在學習前端一陣子後已經能順利刻出想要的版型,也熟悉標籤的使用、了解語意化的重要,但是面對 CSS 卻一直沒有在進步的感覺,同樣的 CSS 會在不經意中重複使用好幾次、沒有一個規劃,後來因為接觸了不同的設計模式我才慢慢理解良好的設計模式可以幫助程式碼更容易維護甚至擴充,寫起來也會更順手,所以如果你也跟我一樣,可以一起來認識 OOCSS!

如果你不清楚自己目前情況,可以透過範例來了解是否需要學習

範例一

  • 想要給 card li 樣式時會用 .content .card li {...} 而不是 .card li {...}

1
2
3
4
5
6
<div class="content">
<ul class="card">
<li>...</li>
<li>...</li>
</ul>
</div>

應該很多人都有使用過這樣的寫法,覺得 .content .card li 權重分數較高,階層也不會過多,會用這種寫法其實很合理

範例二

  • 會把一個東西的 CSS 都全塞在一個 class 裡面

1
<a class="btn">123</a>

1
2
3
4
5
6
7
8
9
10
.btn {
display: block;
color: white;
background-color: blue;
padding: 10px 20px;
text-decoration:none;
text-align:center;
border-radius: 2px;
cursor: pointer;
}

如果以上兩種都是你目前使用的撰寫方式,那恭喜你可以繼續看下去了XD


OOCSS

OOCSS 是 Object Oriented CSS 的縮寫,是 CSS 的架構方法,在這個原則下撰寫的 CSS 具有以下特點:

  • 容器與內容分離
  • 結構與樣式分離

容器與內容分離

容器與內容分離,圖片來自六角學院

簡單來說, 內容 就是你的元件,而 容器 就是包住元件或其他內容的外層

當容器與內容分離時,容器的重用性就會變高、變彈性而不會受到命名的限制,例如:

header 區塊

1
2
3
4
5
6
7
8
9
10
<div class="header">
<ul class="menu">
<li>...</li>
<li>...</li>
</ul>
</div>

<style>
.header .menu li {...}
</style>

footer 區塊

1
2
3
4
5
6
7
8
9
10
<div class="footer">
<ul class="menu">
<li>...</li>
<li>...</li>
</ul>
</div>

<style>
.footer .menu li {...}
</style>

明明是同樣的內容,卻因為外層從 header 換成 footer 所以需要再寫一次 CSS
於是我們利用容器和內容分離的概念,再重寫一次

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<div class="container">

<!--header-->
<div class="row">
<div class="col-12">
<ul class="menu">
<li>...</li>
<li>...</li>
</ul>
</div>
</div>
...
<!--footer-->
<div class="row">
<div class="col-12">
<ul class="menu">
<li>...</li>
<li>...</li>
</ul>
</div>
</div>

</div>

<style>
.menu li {...}
</style>

可以發現改成分離的設計方式後

  • CSS 的部分是可以共用的
  • CSS 不再受到原本命名的限制,可以寫成 .menu li 而不是 .col-12 .menu li

綜合以上兩點,這時再回顧範例一的問題,你會寫 .content .card li {…} 還是 .card li {…} 呢?

1
2
3
4
5
6
<div class="content">
<ul class="card">
<li>...</li>
<li>...</li>
</ul>
</div>

聰明的你理解過後就知道 .card li {…} 才是我們會選擇的,原因在於 content 是容器,所以不會去使用容器當命名的開頭,就像我們不會拿 .col 當開頭一樣

講完容器與內容分離的原理,我們來看 Bootstrap 是如何應用在元件上


Bootstrap 元件也可以分為容器與內容(容器可以包內容)

  • 容器型元件:如 GridCardFormsModal
  • 內容型元件:如 AlertsBadgeBreadcrumbButtons
  1. Card 卡片:Card 是 容器 ,而 Button 屬於 內容

    Card + Button

    1
    2
    3
    4
    5
    6
    7
    8
    <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>

  2. List 列表:Card 是 容器 ,而 List 屬於 內容

    List + Card

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <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>
    </div>
    <ul class="list-group list-group-flush">
    <li class="list-group-item">Cras justo odio</li>
    <li class="list-group-item">Dapibus ac facilisis in</li>
    <li class="list-group-item">Vestibulum at eros</li>
    </ul>
    </div>

看完容器與內容的部分,我們來拆解 Bootstrap 的元件 class 設計吧!

結構與樣式分離

使用 Iphone 的人應該有玩過或是看過 Animoji,他可以透過選擇臉部的器官來打造出自己的角色

Animoji

你可以把原本所有器官的預設樣式想像成「結構」(左圖),結構是一個元件的基底(base)像是:寬度、圓角、字體大小等等

而你也可以選擇頭髮顏色、皮膚顏色等等的就是所謂的「樣式」(右圖),在 Bootstrap 按鈕元件中就是以顏色區分(包含字體顏色、背景顏色)

這時我們再回到一開頭的範例二

1
<a class="btn">123</a>

1
2
3
4
5
6
7
8
9
10
.btn {
display: block;
color: white;
background-color: blue;
padding: 10px 20px;
text-decoration:none;
text-align:center;
border-radius: 2px;
cursor: pointer;
}

利用結構與樣式分離的概念,我們再重寫一次

1
<a class="btn btn-primary">123</a>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
.btn {
display: block;
padding: 10px 20px;
text-decoration:none;
text-align:center;
border-radius: 2px;
cursor: pointer;
}

.btn-primary{
color: white;
background-color: blue;
border: lightblue;
}

應該有看到在 class 的部分多拆出了 btn-primary

他的優點是

  • 按鈕需要換一個顏色,不需要先去找到那顆按鈕的 CSS 然後改掉顏色
  • 當想要寫第二顆按鈕在他旁邊時,不再需要重複寫一堆類似的 CSS,而是把不一樣的部分抽離出來管理,一樣的部分就保留起來不會去動它

總結

2020春季網頁切版直播班-八週全記錄 Flex 修煉時光屋

評論

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×