[Easy] 🏷️ Box Model
Default
Box Model 在 CSS 當中是被用來討論如何設計佈局的術語。他本身可以理解為一個包裹 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
}
如此一來,就會改採對內填充的形式,元素的寬高設計更為直覺,不必為了 padding 或 border 去增減數字。
對比例題
假設有以下相同的樣式設定:
.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-box 或 border-box,margin 都不會被計入元素的寬高,兩種模式只影響 padding 和 border 的計算方式。
.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-sizing 對 inline 元素不起作用,因為 inline 元素的 width 和 height 設定本身就無效。
span {
display: inline;
width: 100px; /* 無效 */
box-sizing: border-box; /* 也無效 */
}
4. min-width / max-width
min-width 和 max-width 同樣受到 box-sizing 影響:
.box {
box-sizing: border-box;
min-width: 100px; /* 包含 padding 和 border */
padding: 10px;
border: 5px solid;
}
/* content 最小寬度 = 100 - 20 - 10 = 70px */