跳至主要內容

[Easy] 🏷️ Box Model

Default

Box ModelCSS 當中是被用來討論如何設計佈局的術語。他本身可以理解為一個包裹 HTML 元素的盒子,中間有四個主要的屬性 :

  • content : 主要用於顯示元素的內容,譬如文字。
  • padding : 元素的內容和元素邊界的距離
  • margin : 元素對外其他元素的距離
  • border : 元素本身的邊線

box-sizing

決定 Box Model 使用的類型,會透過 box-sizing 這個語法。

意思是指,當元素計算寬度和高度時,padding, border 這兩個屬性是採用對內填充還是對外擴充。

其預設值為 content-box,採用對外擴充,在這個條件下,除了元素自己的寬高外,額外的 padding, border 都要加入計算。如下 :

div {
width: 100px;
padding: 10px;
border: 1px solid #000;
}

這個 div 的寬度計算是 100px(width) + 20px(左右 padding) + 2px(左右 border) = 122px

border-box

顯然上述這種方式並不可靠,會使前端開發時,被迫需要一直計算元素寬高,為了改善開發體驗,自然得改採另一模式,即 border-box

如下例,在樣式初始化時將全體元素 box-sizing 的值設為 border-box :

* {
box-sizing: border-box; // global style
}

如此一來,就會改採對內填充的形式,元素的寬高設計更為直覺,不必為了 paddingborder 去增減數字。

對比例題

假設有以下相同的樣式設定:

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

content-box(預設值)

  • 實際佔用寬度 = 100px(width) + 20px(左右 padding) + 10px(左右 border) = 130px
  • 實際佔用高度 = 100px(height) + 20px(上下 padding) + 10px(上下 border) = 130px
  • content 區域 = 100px × 100px
  • 注意margin 不計入元素寬度,但會影響與其他元素的距離

border-box

  • 實際佔用寬度 = 100px(padding 和 border 向內擠壓)
  • 實際佔用高度 = 100px
  • content 區域 = 100px - 20px(左右 padding) - 10px(左右 border) = 70px × 70px
  • 注意margin 同樣不計入元素寬度

視覺化對比

content-box:
┌─────────── margin (20px) ───────────┐
│ ┌──────── border (5px) ──────────┐ │
│ │ ┌──── padding (10px) ──────┐ │ │
│ │ │ │ │ │
│ │ │ content (100×100) │ │ │
│ │ │ │ │ │
│ │ └───────────────────────────┘ │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────┘
總寬度:130px(不含 margin)

border-box:
┌─────────── margin (20px) ───────────┐
│ ┌──────── border (5px) ──────────┐ │
│ │ ┌──── padding (10px) ──────┐ │ │
│ │ │ │ │ │
│ │ │ content (70×70) │ │ │
│ │ │ │ │ │
│ │ └───────────────────────────┘ │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────┘
總寬度:100px(不含 margin)

常見陷阱

1. margin 的處理

無論是 content-boxborder-boxmargin 都不會被計入元素的寬高,兩種模式只影響 paddingborder 的計算方式。

.box {
box-sizing: border-box;
width: 100px;
padding: 10px;
border: 5px solid;
margin: 20px; /* 不計入 width */
}
/* 元素實際佔用寬度仍是 100px,但與其他元素的距離會多 20px */

2. 百分比寬度

當使用百分比寬度時,計算方式也會受到 box-sizing 影響:

.parent {
width: 200px;
}

.child {
width: 50%; /* 繼承父元素的 50% = 100px */
padding: 10px;
border: 5px solid;
}

/* content-box: 實際佔用 130px(可能超出父元素) */
/* border-box: 實際佔用 100px(剛好是父元素的 50%) */

3. inline 元素

box-sizinginline 元素不起作用,因為 inline 元素的 widthheight 設定本身就無效。

span {
display: inline;
width: 100px; /* 無效 */
box-sizing: border-box; /* 也無效 */
}

4. min-width / max-width

min-widthmax-width 同樣受到 box-sizing 影響:

.box {
box-sizing: border-box;
min-width: 100px; /* 包含 padding 和 border */
padding: 10px;
border: 5px solid;
}
/* content 最小寬度 = 100 - 20 - 10 = 70px */

Reference