Menu

CSS 盒模型:内容、内边距、边框、外边距

每个元素都是一个由四层组成的盒子:内容、内边距、边框和外边距。学习每一层如何计入尺寸,box-sizing: border-box 如何改变计算方式,并实时查看每一层的测量结果。

本页包含可运行的编辑器。编辑、运行,立即查看输出。

每个盒子的四层

页面上的每个元素都被画成一个矩形,由内到外分为四层:

  1. 内容:文字、图片或子元素,大小由 width 和 height 决定。
  2. 内边距(padding):盒子内部、内容与边框之间的空间。这里会显示元素的背景。
  3. 边框(border):包围内边距的线。
  4. 外边距(margin):边框之外的空间,用来把其他盒子推开。始终是透明的。

在这个例子中,每一层都有自己的颜色:蓝色是内容,绿色是内边距,深色是边框,盒子周围的琥珀色区域是外边距(由一个外层元素画出来,因为外边距本身是透明的)。

盒子下方那一行是浏览器测量出的结果:160 + 20 + 20 + 10 + 10 = 220px。外边距会在两侧各再加 24px,但它在盒子之外,所以不计入这 220px。

宽度计算:content-box 与 border-box

默认情况下(box-sizing: content-box),width 只设置内容的宽度。内边距和边框会额外加上去,所以盒子最终比你写的数字更宽。使用 box-sizing: border-box 时,width 就是整个盒子的宽度,内容会缩小,为内边距和边框腾出空间。

content-box(默认值)border-box
width 指的是内容内容 + 内边距 + 边框
width: 200px; padding: 20px; border: 5px宽 250px宽 200px
此时的内容区域200px150px
外边距在外面,不计入在外面,不计入

border-box 重置

因为 border-box 让尺寸计算更直观,几乎所有现代样式表都以这条规则开头:

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

它在使用百分比时最重要。在 content-box 下,两个带内边距的 width: 50% 列放不进同一行,因为每一列都是 50% 再加上它的内边距:

(HTML 注释去掉了 inline-block 列之间的空格,否则这些空格会额外占用几个像素。)

在开发者工具中查看盒模型

每个浏览器都会帮你画出盒模型。右键点击一个元素,选择“检查”,打开“计算样式”标签页(Firefox 中是“布局”):图示中间显示内容的尺寸,四周依次是内边距、边框和外边距的值。在元素面板中把鼠标悬停在某个元素上,页面也会着色:内容为蓝色,内边距为绿色,外边距为橙色。

行内盒子遵循不同的规则

上面介绍的盒模型描述的是 <div> 和 <p> 这样的块级盒子。<span>、<a> 和 <strong> 这样的行内元素在一行文字中换行排列,对垂直空间的处理方式也不同:

属性在行内元素上的表现
width、height被忽略
水平方向的内边距、边框、外边距生效,并把相邻内容向两侧推开
垂直方向的内边距和边框会画出来,但不会推开上下的行
垂直方向的外边距被忽略

display: inline-block 让行内的元素拥有完整的盒模型:它的宽度、高度、内边距和外边距都会占用空间。每一层的详细介绍见 CSS 内边距和 CSS 外边距。

常见错误

  • 给固定宽度的盒子加了内边距,却不明白它为什么变大了。 在 content-box 下,内边距和边框会加到 width 上。请使用 border-box。
  • 以为外边距会显示背景颜色。 外边距始终是透明的;需要有颜色的空白时,请使用内边距。
  • 给行内元素设置 height 或垂直外边距。 不会有任何效果;请使用 display: inline-block 或 block。
  • 计算时忘了边框。 在 content-box 下,给 width: 100% 的元素加上 1px 边框,它就会宽出 2px,可能导致出现水平滚动条。
  • 混淆外边距和内边距。 简单来说:内边距在边框里面,外边距在边框外面。margin 与 padding 页面把两者放在一起做了对比。

常见问题

CSS 盒模型是什么?

它是这样一条规则:每个元素都渲染为一个由四层组成的矩形盒子,分别是内容、包围内容的内边距、包围内边距的边框,以及边框之外的外边距。CSS 中的宽度、高度和间距都设置在这些层上。

box-sizing: border-box 有什么作用?

它让 width 和 height 包含内边距和边框。一个 width: 200px、padding: 20px、边框 5px 的盒子,宽度就正好是 200px,内容区域会缩小到 150px 来适应。默认值 content-box 则会把内边距和边框额外加上去,得到 250px。

元素的总宽度是怎么计算的?

使用默认的 content-box 时:width + 左右内边距 + 左右边框。使用 border-box 时:就是 width。两种情况下外边距都在盒子之外,所以它增加的是元素占据的空间,而不是元素本身的宽度。

外边距属于盒模型吗?

属于,它是最外面的一层,但它始终是透明的,也从不计入元素自身的宽度或背景。它只负责把相邻的盒子推开。

应该给所有元素都设置 box-sizing: border-box 吗?

大多数项目都会这样做,在样式表开头写上 *, *::before, *::after { box-sizing: border-box; }。这样百分比宽度和内边距加起来的结果就符合人们的预期,Bootstrap 和 Tailwind 等框架也自带同样的重置规则。

Coddy 编程语言插图

和 Coddy 一起学编程

开始