CSS 盒模型 (Box Model)

在 CSS 中,每個 HTML 元素都可以看作是一個「盒子」,盒模型 (box model) 描述了這個盒子的組成結構。理解盒模型是學習 CSS 排版的基礎。

盒模型結構

一個盒子由內到外包含四個部分:

+------------------------------------------+
|               margin (外距)               |
|  +------------------------------------+  |
|  |           border (邊框)             |  |
|  |  +------------------------------+  |  |
|  |  |        padding (內距)         |  |  |
|  |  |  +------------------------+  |  |  |
|  |  |  |                        |  |  |  |
|  |  |  |      content (內容)     |  |  |  |
|  |  |  |                        |  |  |  |
|  |  |  +------------------------+  |  |  |
|  |  +------------------------------+  |  |
|  +------------------------------------+  |
+------------------------------------------+
  • Content (內容):元素的實際內容,例如文字、圖片
  • Padding (內距):內容和邊框之間的空間
  • Border (邊框):包圍 padding 和 content 的邊框
  • Margin (外距):邊框外面的空間,用於和其他元素保持距離

範例

.box {
  width: 200px;
  height: 100px;
  padding: 20px;
  border: 5px solid black;
  margin: 10px;
}

元素實際大小

預設情況下,widthheight 只設定 content 的大小,元素的「實際寬度」要加上 padding 和 border:

實際寬度 = width + padding-left + padding-right + border-left + border-right
實際高度 = height + padding-top + padding-bottom + border-top + border-bottom

以上面的範例來說:

實際寬度 = 200 + 20 + 20 + 5 + 5 = 250px
實際高度 = 100 + 20 + 20 + 5 + 5 = 150px
margin 不算在元素的大小內,但會影響元素佔據的空間。

box-sizing 屬性

box-sizing 屬性可以改變盒模型的計算方式。

content-box(預設值)

widthheight 只包含 content,不包含 padding 和 border。

.box {
  box-sizing: content-box;  /* 預設值 */
  width: 200px;
  padding: 20px;
  border: 5px solid black;
}
/* 實際寬度 = 200 + 20 + 20 + 5 + 5 = 250px */

border-box

widthheight 包含 content、padding 和 border。

.box {
  box-sizing: border-box;
  width: 200px;
  padding: 20px;
  border: 5px solid black;
}
/* 實際寬度 = 200px(padding 和 border 包含在內) */

使用 border-box 讓設定寬高更直覺,設定 200px 就是 200px,不用自己計算 padding 和 border。

全域設定 border-box

許多開發者會在 CSS 最開頭加上這段,讓所有元素都使用 border-box

*, *::before, *::after {
  box-sizing: border-box;
}

各部分的設定

Padding(內距)

/* 四邊相同 */
padding: 20px;

/* 上下 | 左右 */
padding: 10px 20px;

/* 上 | 左右 | 下 */
padding: 10px 20px 30px;

/* 上 | 右 | 下 | 左(順時針) */
padding: 10px 20px 30px 40px;

/* 個別設定 */
padding-top: 10px;
padding-right: 20px;
padding-bottom: 30px;
padding-left: 40px;

Border(邊框)

/* 縮寫:寬度 樣式 顏色 */
border: 1px solid black;

/* 個別設定 */
border-width: 1px;
border-style: solid;
border-color: black;

/* 個別邊 */
border-top: 2px dashed red;
border-bottom: none;

Margin(外距)

/* 語法和 padding 相同 */
margin: 20px;
margin: 10px 20px;
margin: 10px 20px 30px 40px;

/* 個別設定 */
margin-top: 10px;
margin-right: 20px;
margin-bottom: 30px;
margin-left: 40px;

/* 水平置中(區塊元素) */
margin: 0 auto;

Margin Collapse(外距重疊)

當兩個垂直相鄰的元素的 margin 相遇時,它們會合併成一個 margin,取較大的值,這叫做 margin collapse。

.box1 {
  margin-bottom: 30px;
}

.box2 {
  margin-top: 20px;
}

/* 兩個 box 之間的距離是 30px,不是 50px */

Margin collapse 只發生在垂直方向(上下),水平方向(左右)不會發生。