[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 */