CSS 盒模型是什么?box-sizing 有什么作用?

基础高频原理约 5 分钟读完

一句话回答

每个元素在布局时都被看成一个矩形盒子,从内到外依次是 content、padding、border、margin。box-sizing 决定 width、height 指的是哪一层:默认的 content-box 只算内容区,padding 和 border 会往外撑大;border-box 把 padding 和 border 算在 width 里,内容区自动缩小。项目里通常全局设成 border-box,写尺寸更直观。

详细解析

盒子的四层

层 作用 是否有背景
content 放文字、图片等内容 有
padding 内容和边框之间的留白 有,背景默认延伸到 padding
border 边框 背景默认也画到边框下面,虚线、半透明边框时能看出来
margin 和其他盒子之间的距离 没有,永远透明

margin 可以是负值,padding 不行。相邻块级元素的垂直 margin 还会合并,这一点放在 BFC 里讲。

content-box 和 border-box 的宽度计算

同样一段样式:

CSS
.box {
  width: 200px;
  padding: 20px;
  border: 5px solid #333;
  margin: 10px;
}
content-box(默认) border-box
内容区宽度 200px 200 - 20×2 - 5×2 = 150px
元素可见宽度(含边框) 200 + 40 + 10 = 250px 200px
占据的水平空间(含 margin) 270px 220px

两种模式下 margin 都不算进 width。border-box 只是把 padding 和 border "收"进去,margin 永远在外面。

为什么项目里常全局设 border-box

  • 尺寸符合直觉:设计稿上一个按钮宽 120px,就写 width: 120px,加 padding 不用再心算减法
  • 百分比布局不溢出:两栏各 width: 50% 再加 padding,content-box 下会超过 100% 导致换行,border-box 不会
  • 很多 CSS 重置库和 UI 框架都默认这样做

常见写法是让所有元素继承根元素的设置,第三方组件需要 content-box 时可以在局部改回来:

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

行内元素的盒模型

span、a 这类行内非替换元素也有四层,但表现不同:

  • width、height 不生效,尺寸由内容决定
  • 水平方向的 padding、border、margin 正常生效,会推开左右的内容
  • 垂直方向的 margin 完全不生效;垂直的 padding 和 border 会画出来(背景会变高),但不影响行高,不会把上下行推开,可能和相邻行重叠

想让行内元素的垂直方向尺寸参与布局,改成 display: inline-block。img 这类替换元素,以及 input、button 等表单控件,虽然也是行内级元素,但宽高和垂直 margin 都生效,会把所在的行撑高。

代码示例

HTML
<p style="line-height: 20px">
  第一行文字
  <span style="padding: 10px; margin: 10px; background: #fde68a">行内元素</span>
  第一行文字
  <br />
  第二行文字:上一行 span 的黄色背景会向上下溢出,但这一行的位置没有被推开
</p>

面试官可能追问

怎么用 JS 拿到元素的各种尺寸?

offsetWidth 是 content + padding + border;clientWidth 是 content + padding,不含边框和滚动条;scrollWidth 是内容实际宽度,包括溢出部分。getBoundingClientRect().width 和 offsetWidth 接近,但它会计入 transform 缩放、并且返回小数。这几个都不包含 margin。

padding 和 margin 设成百分比时参照什么?

参照包含块的宽度,上下方向也一样参照宽度,不是高度。利用这一点,以前常用 padding-top: 56.25% 做 16:9 的固定比例容器。现在直接用 aspect-ratio: 16 / 9 更清晰。

box-sizing: border-box 时,padding 比 width 还大会怎样?

内容区宽度不会变成负数,最小为 0。这时元素的实际宽度是 padding + border 的总和,超过了设定的 width。

易错点

  • border-box 不包括 margin,margin 在两种模式下都在 width 之外
  • 背景默认会画到 border 下面(background-clip 默认值是 border-box),不是只画在 content 区
  • 给行内元素设垂直 margin 没效果,设垂直 padding 只是看起来变大,不会撑开行

AI 模拟面试官

用自己的话回答,AI 对照参考答案打分、指出遗漏,再追问,最多 3 轮

登录后就可以和 AI 面试官对练,面试记录也会保存下来。登录

这道题你掌握了吗?

选一个最接近的状态,没掌握的题会出现在"我的进度 · 待复习"里。

学习记录暂存在本机浏览器。登录后自动同步到账号,换设备也能看到。