Learning Objectives
- 說明 CSS 框架是什麼、提供了哪些東西,以及在網頁裡引入 Bootstrap 的方式
- 用 container、row、col 與斷點前綴(sm、md、lg、xl、xxl)排出在不同寬度改變欄數的版面
- 套用按鈕、卡片、表單等常用元件的 class,以及間距、文字、顯示的工具類別
- 說明 Bootstrap 的格線就是 Flexbox 加上 min-width 媒體查詢,和自己寫 CSS 是同一套原理
- 判斷什麼時候適合用框架、什麼時候自己寫 CSS 比較好
框架是別人先寫好的一套 CSS
做過前面幾課的練習,你應該發現:每個網站都要寫按鈕、表單、導覽列、幾欄的版面, 而且每次都要處理手機版。這些東西長得都差不多,於是有人把它們整理成一套可以直接拿來用的 CSS, 這就是 CSS 框架(CSS framework)。
Bootstrap 是其中使用很廣的一套,最早是 Twitter 的一位設計師和一位工程師為公司內部工具做的,2011 年公開成為開放原始碼專案。它提供:
| 類別 | 內容 | 例子 |
|---|---|---|
| 格線系統(grid system) | 12 欄的響應式版面 | row、col-md-6 |
| 元件(components) | 先設計好的介面零件 | 按鈕、卡片、導覽列、表單 |
| 工具類別(utilities) | 一個 class 只做一件事 | mb-3(下外距)、text-center、d-none |
用法是在 HTML 的 class 裡寫上它定義好的名字,不必自己寫 CSS 規則。
例如 <button class="btn btn-primary"> 就會得到一顆藍色、圓角、有 hover 效果的按鈕。
使用框架的好處是快、樣式一致、已經處理好各種瀏覽器的差異與響應式; 代價是網站容易長得很像,而且你要先學會它的命名規則。這一課以 Bootstrap 5.3 版為準。
把 Bootstrap 引入網頁
Bootstrap 由一個 CSS 檔和一個 JavaScript 檔組成。CSS 放在 <head>,JavaScript 放在 </body> 前面:
<!doctype html>
<html lang="zh-Hant">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <!-- 第 21 課:響應式必備 -->
<link rel="stylesheet" href="/static/vendor/[email protected]/dist/css/bootstrap.min.css">
<title>程式設計社</title>
</head>
<body>
…
<script src="/static/vendor/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
檔案從哪裡來,常見三種方式:
| 方式 | 說明 |
|---|---|
| 從官方網站下載,放在自己的網站上(自託管) | 這個平台的做法:不依賴別人的伺服器,也不會讓第三方知道誰在看你的網頁 |
| 用 CDN 的網址 | 官方文件提供的快速做法,複製兩行就能用;要接受載入時連到外部伺服器 |
| 用套件管理工具(例如 npm)安裝 | 大型專案用,可以只挑需要的部分、自訂顏色 |
格線、按鈕、卡片、工具類別都只需要 CSS。 JavaScript 是給會「動」的元件用的,例如導覽列在手機上的收合選單、 下拉選單、對話框(modal)。這一課的練習只用到 CSS 的部分。
格線系統:container、row、col
Bootstrap 的版面由三層組成:
<div class="container"> <!-- 1. 容器:置中,並在左右留內距 -->
<div class="row"> <!-- 2. 列:裝欄位的外框 -->
<div class="col-md-8">主要內容</div> <!-- 3. 欄:一列分成 12 等份,這一欄佔 8 份 -->
<div class="col-md-4">側欄</div> <!-- 這一欄佔 4 份,8 + 4 = 12 剛好一列 -->
</div>
</div>
- 一列分成 12 欄,
col-4佔 4 欄(三分之一)、col-6佔一半、col-12佔滿一列。 - 一列加起來超過 12,多出來的欄會換到下一行。
- 只寫
col(不寫數字):同一列的幾個col平分寬度。 - 欄與欄之間的間距叫 gutter,用
g-0~g-5調整(gx-*只調左右、gy-*只調上下)。 container在每個斷點有固定的最大寬度;container-fluid永遠是 100% 寬。
斷點前綴決定這個欄寬「從多寬開始生效」:
| 斷點 | 前綴 | 從多寬開始 |
|---|---|---|
| Extra small | (不加) | 0(所有寬度) |
| Small | sm |
576px |
| Medium | md |
768px |
| Large | lg |
992px |
| Extra large | xl |
1200px |
| Extra extra large | xxl |
1400px |
col-md-4 的意思是「768px 以上佔 4 欄」。比 768px 窄的時候,這個 class 不生效,欄位就變成佔滿整列、上下疊起來。
可以同時寫好幾層:class="col-12 col-md-6 col-lg-4" 表示手機一欄、平板兩欄、筆電三欄。
每一層對它以上的寬度都有效,取符合條件的最大那一層。
格線背後就是 Flexbox 和媒體查詢
Bootstrap 沒有什麼神奇的地方,它的格線就是你在第 17~21 課學過的東西。簡化之後大概是這樣:
.row {
display: flex; /* 第 17 課:Flexbox */
flex-wrap: wrap; /* 超過一列就換行 */
}
.row > * {
width: 100%; /* 沒有指定欄寬時佔滿整列,所以手機上是一欄 */
}
.col-6 { flex: 0 0 auto; width: 50%; } /* 6 / 12 = 50% */
@media (min-width: 768px) { /* 第 21 課:行動優先的 min-width 媒體查詢 */
.col-md-4 { flex: 0 0 auto; width: 33.33333333%; }
}
所以:
- 行動優先:沒有前綴的 class 適用所有寬度,加前綴的 class 從那個寬度以上才生效,和你自己寫
min-width一樣。 - 換行:
flex-wrap: wrap讓加起來超過 100% 的欄位換到下一行。 - 斷點數字是 Bootstrap 選好的一組通用值;自己寫 CSS 時,斷點還是依你的內容決定(第 21 課)。
懂了原理,遇到框架做不到的版面,就知道可以自己補一段 CSS,而不是硬塞一堆 class。
小測驗:格線系統
<div class="col-md-6"> 在視窗寬 500px 時佔多寬?
一個 row 裡有三個 col-5,排出來會怎樣?
class="col-12 col-md-6 col-xl-3" 在視窗寬 1000px(lg)時佔幾欄?
常用元件與工具類別
元件:一組 class 組成一個介面零件。
| 元件 | 寫法 | 說明 |
|---|---|---|
| 按鈕 | <button class="btn btn-primary"> |
btn 是基本樣式,btn-primary、btn-secondary、btn-danger 決定顏色;btn-outline-primary 是外框樣式 |
| 卡片 | <div class="card"><div class="card-body"><h2 class="card-title">…</h2><p class="card-text">…</p></div></div> |
有邊框、圓角的區塊 |
| 表單 | <label class="form-label">+<input class="form-control"> |
輸入框變成滿寬、有一致的外觀與焦點樣式;下拉選單用 form-select |
| 導覽列 | <nav class="navbar navbar-expand-lg">…</nav> |
寬螢幕橫排、窄螢幕收進漢堡選單(收合要用到 Bootstrap 的 JavaScript) |
Bootstrap 只管外觀。語意與無障礙還是要你自己寫:按鈕要用 <button>、輸入框要有 <label>、圖片要有 alt。
把 class="btn" 加在 <div> 上,看起來像按鈕,但鍵盤按 Tab 移不過去(第 24 課)。
工具類別:一個 class 只設定一兩個屬性,直接寫在 HTML 上微調。
| 類別 | 寫法 | 意思 |
|---|---|---|
| 外距 margin | m-3、mt-2、mb-4、mx-auto |
m 外距;方向 t 上、b 下、s 開頭(左)、e 結尾(右)、x 左右、y 上下 |
| 內距 padding | p-3、py-2、px-4 |
p 內距,方向寫法同上 |
| 間距大小 | 0~5 |
0、0.25rem、0.5rem、1rem、1.5rem、3rem |
| 文字 | text-center、text-end、fw-bold、fs-5 |
對齊、粗細、字級 |
| 顯示 | d-none、d-flex、d-none d-lg-block |
display;最後一個是「lg 以上才顯示」 |
工具類別也能加斷點:mt-md-0 表示 768px 以上的上外距是 0。
左右用 s/e(start/end)而不是 l/r,是因為阿拉伯文、希伯來文這些由右往左寫的語言,「開頭」在右邊。
什麼時候不必用框架
框架不是一定要用。下面這張表可以幫你判斷:
| 比較適合用框架 | 自己寫 CSS 比較好 |
|---|---|
| 時間很趕、要快速做出能用的介面(課堂專題、內部工具、活動報名頁) | 只有一兩頁的小網頁:Flexbox、Grid 幾行就排好,不必載入整套框架 |
| 很多人一起做,需要一套共同的命名與外觀 | 需要獨特的視覺設計(作品集、品牌網站),不想和別的網站長得一樣 |
| 需要很多現成元件(表單、對話框、分頁) | 想把檔案大小壓到最小、載入最快 |
不管用不用框架,前面學的東西都不會白費:框架的 class 背後就是 Flexbox、Grid、媒體查詢、盒模型。 懂原理的人用框架,可以在框架不夠用時自己補;只會背 class 的人,遇到框架沒有的版面就卡住了。
也可以混著用:用框架的格線與表單,再自己寫一段 CSS 調整顏色與細節。 要改 Bootstrap 元件的顏色,可以覆寫元件用的 CSS 變數(例如在
.btn-primary上改--bs-btn-bg),或用它的原始碼重新編譯(進階用法)。
小測驗:元件、工具類別與選擇
<div class="d-none d-md-block">側欄</div> 在哪些寬度看得到?
class="mt-0 mb-3 px-2" 設定了什麼?
把 class="btn btn-primary" 加在 <div> 上當按鈕用,會有什麼問題?
要做一頁有獨特視覺風格的個人作品集,只有一頁、三個區塊。下面哪個說法最合理?
重點整理
- CSS 框架是先寫好的一套樣式;Bootstrap 提供格線系統、元件與工具類別,用法是在 class 寫上它定義的名字。
- 引入:CSS 放 head、JavaScript bundle 放
</body>前;格線、按鈕、表單、工具類別只需要 CSS。 - 格線:
container→row→col-*,一列 12 欄,超過就換行;g-*調整欄間距。 - 斷點前綴 sm 576、md 768、lg 992、xl 1200、xxl 1400:
col-md-4是「768px 以上佔 4 欄」,取符合的最大那一層。 - 工具類別:
m/p+ 方向(t、b、s、e、x、y)+ 大小 0~5;d-none d-lg-block控制顯示;text-center、fw-bold調文字。 - 框架只管外觀,語意與無障礙要自己寫。
- 格線就是 Flexbox 加 min-width 媒體查詢;小頁面、需要獨特設計時,自己寫 CSS 常常更合適。
下一課是最後一課:無障礙與綜合專題。你會檢查一頁網頁的對比、替代文字與鍵盤操作,再用這 24 課學到的東西做一頁自己的作品集。