盒模型
CSS 盒模型把元素占用空间拆成 content、padding、border、margin 四层,并由 box-sizing 决定声明的 width/height 对应 content box 还是 border box。
#frontend
#css
#concept
#evergreen
[!info] related notes
- 所属 MOC: CSS MOC, CSS 盒模型与布局 MOC
- 相关概念: box-sizing 尺寸口径, CSS BFC(块级格式化上下文), Flex 布局, Grid 布局
盒模型
一句话定义
浏览器布局中的元素可以看成一个矩形盒子:
margin
└─ border
└─ padding
└─ content
盒模型回答的是:一个元素声明的尺寸、内部留白、边框和外部间距如何共同形成最终占用空间。
四层分别是什么
- content:文本、图片等实际内容区域;
- padding:内容与边框之间的内边距;
- border:盒子的边框;
- margin:盒子与外部其他盒子之间的外边距。
margin 不属于盒子自身的背景绘制区域,也不会被 box-sizing 纳入 width / height。
content-box
默认情况下:
box-sizing: content-box;
width: 100px;
padding: 10px;
border: 5px solid;
这里 width: 100px 只描述 content width。
因此横向 border box 尺寸是:
100 + 10×2 + 5×2 = 130px
如果再有左右 margin,元素在普通布局中与周围元素需要考虑的外部间距还会继续增加。
border-box
box-sizing: border-box;
width: 100px;
padding: 10px;
border: 5px solid;
此时声明的 width: 100px 已经包含:
content + padding + border
因此 content 可用宽度会被 padding 和 border 挤小。
这也是工程里经常统一:
*, *::before, *::after {
box-sizing: border-box;
}
的原因:组件声明尺寸时更容易直接理解为可见 border box 的尺寸。
尺寸推导
遇到“为什么这个元素比 width 更宽”时,不要凭视觉猜:
- 先看
box-sizing; - 再看 width/height;
- 再加 padding;
- 再加 border;
- 最后单独考虑 margin 和父容器布局规则。
盒模型本身只解释尺寸组成;Flex、Grid、普通文档流如何分配空间,是更上一层布局问题。
与 BFC 的边界
BFC 是格式化上下文,解决块级布局、浮动包含、margin collapse 等问题;盒模型则描述单个盒子的尺寸组成。
所以:
Box Model
= 一个盒子由哪些区域组成、尺寸怎么算
BFC
= 一组块级盒子在一个格式化上下文中怎样参与布局
BFC 不是盒模型的一部分,也不应把“触发 BFC”当作 box-sizing 的功能。
常见误区
width: 100px不一定代表 content 永远是 100px,要先看box-sizing。- margin 不会被
border-box吞进去。 box-sizing不决定元素是 block、inline、flex 还是 grid。- BFC、margin collapse 属于格式化上下文问题,不等同于盒模型。
学习检查
不看正文回答:
- content、padding、border、margin 四层分别承担什么?
content-box与border-box对width的解释有什么差异?- 一个
width: 200px; padding: 20px; border: 2px的 content-box 元素,border box 宽度是多少? - 同样配置改为 border-box 后,content 区宽度是多少?
- 为什么 margin 不应被算进
box-sizing? - “父元素包不住浮动子元素”为什么应该去看 BFC,而不是继续研究 box-sizing?
- 给一个布局超宽案例,按 box-sizing → width → padding → border → margin 的顺序完成排查。