CSS 播客 - 001:盒子模型
假设您有以下 HTML 代码:
<p>I am a paragraph of text that has a few words in it.</p>
然后,您为其编写以下 CSS:
p {
width: 100px;
height: 50px;
padding: 20px;
border: 1px solid;
}
最终内容宽度为 142 像素,而不是您指定的 100 像素,并且超出了元素范围。这是为什么?
盒子模型是 CSS 的核心基础。了解盒模型的运作方式、它如何受到 CSS 其他方面的影响,以及更重要的是,如何控制它,有助于您编写更可预测的 CSS。
请务必记住,CSS 显示的所有内容都是盒子,即使只是一些文字,或者具有使其看起来像圆形的 border-radius
也是如此。
内容和尺寸
盒子会根据其 display
值、设置的尺寸和包含的内容而表现出不同的行为。此内容可以是纯文本,也可以是子元素生成的更多框。无论哪种方式,内容都会默认影响盒子的大小。
您可以使用外在尺寸调整来控制此行为,也可以使用内在尺寸调整,让浏览器根据内容大小为您做出决定。
以下是一个基本演示,可说明两者之间的区别:
此演示在一个具有固定尺寸和粗边框的框中显示了“CSS is awesome”字样。由于该盒子具有指定的宽度,因此属于外在尺寸。
这意味着它会控制子内容的大小。不过,“awesome”一词对于该盒子来说过大,因此会溢出父盒子的边框盒子(稍后会详细介绍)。防止此溢出的一种方法是不设置宽度,或者在本例中将 width
设置为 min-content
,从而让盒子具有固有的尺寸。min-content
关键字表示该盒子应仅与内容(即“awesome”一词)的固有最小宽度一样宽。这样,方框就能完美贴合文字。
下面是一个更复杂的示例,展示了不同尺寸对实际内容的影响:
开启和关闭固有尺寸调整,看看外在尺寸调整如何让您更好地控制尺寸,以及固有尺寸调整如何让内容更好地控制尺寸。如需查看效果,请向卡片添加几句文字。 当此元素具有外部尺寸时,您可添加的内容量会受到限制,超出限制就会发生溢出,但如果切换到内部尺寸,就不会发生这种情况。
默认情况下,此元素具有一组 width
和 height
,每组包含 400px
个元素。这些维度为元素内的所有内容设置了严格的边界,除非内容过大而无法放入框中,否则这些边界都会得到遵守。您可以将花朵图片下方的字幕更改为超出方框高度的内容,从而查看此效果。
关键术语:当内容对于其所在的框过大时,就会发生溢出。您可以使用 overflow
属性管理元素处理溢出内容的方式。
切换到固有尺寸调整后,浏览器会根据盒子的内容尺寸为您做出决定。这样一来,溢出的可能性就会大大降低,因为盒子会随内容调整大小。
请务必记住,固有尺寸是浏览器的默认行为,通常比外在尺寸更灵活。
盒子模型的各个区域
盒子由不同的盒子模型区域组成,每个区域都执行特定的任务。
内容框是内容所在的区域。内容可以控制其父级的大小,因此这通常是大小变化最大的区域。
内边距框围绕着内容框,是由 padding
属性创建的空间。由于内边距位于盒子内部,因此盒子背景在内边距创建的空间中可见。
如果框设置了溢出规则(例如 overflow: auto
或 overflow: scroll
),滚动条也会占用此空间。
边框围绕内边距框,其空间由 border
值定义,该值会为元素创建视觉框架。元素的边框边缘是您可以看到的界限。
最后一个区域是边距框,即框周围的空间,由框的 margin
规则定义。outline
和 box-shadow
等属性也会占用此空间,因为它们绘制在元素顶部,不会影响框的大小。更改盒子 200px
中 outline-width
的盒子不会更改边框边缘内的任何内容。
一个有用的类比
盒子模型很难理解,因此我们来打个比方,帮助您理解目前所学的内容。

在此图中,您可以看到三个相框并排安装在墙上。带框图片的元素与盒子模型对应关系如下:
- 内容框是艺术作品。
- 衬垫是框架与艺术品之间的白色安装板。
- 边框是框架,为艺术作品提供实际的边框。
- 边距框是帧之间的空间。
- 阴影占据的空间与边距框相同。
调试盒子模型
浏览器开发者工具可直观呈现所选框的盒模型计算结果,这有助于您了解盒模型的工作原理以及它对您正在处理的网站的影响。
如需在 Chrome 中尝试此功能,请执行以下操作:
控制盒子模型
若要了解如何控制盒子模型,您首先需要了解浏览器中会发生什么情况。
每个浏览器都会将用户代理样式表应用于 HTML 文档。样式表定义了元素在未获得已定义的 CSS 时应如何显示和运行。用户代理样式表中的 CSS 因浏览器而异,但每个浏览器都有默认设置,可让内容更易于阅读。
用户代理样式表会为采用 display
的元素设置默认值。例如,<div>
元素的默认 display
值为 block
,<li>
的默认 display
值为 list-item
,<span>
的默认 display
值为 inline
。
inline
元素具有块边距,但其他元素不遵循该边距。
使用 inline-block
时,其他元素会遵循块边距,但第一个元素会保留其作为 inline
元素时的大部分相同行为。block
元素默认会填充可用的内联空间,而 inline
和 inline-block
元素的大小仅与其内容一样大。
用户代理样式表还为 box-sizing
设置了默认值,该属性用于告知盒子如何计算其大小。默认情况下,所有元素的 box-sizing: content-box;
均设置为 0。这意味着,当您设置 width
和 height
等维度时,这些维度会应用于内容框。如果您随后设置 padding
和 border
,这些值会添加到内容框的大小中。
检验您的掌握情况
测试您对影响盒子模型大小的属性的了解程度。
.my-box { width: 200px; border: 10px solid; padding: 20px; }
您认为 .my-box
的宽度是多少?
box-sizing: border-box
,则 200px
是正确的。
此框的实际宽度为 260 像素。
由于 CSS 使用默认的 box-sizing: content-box
,因此应用的宽度是内容的宽度,并在此基础上添加了两侧的 padding
和 border
。200 像素的内容宽度 + 40 像素的内边距 + 20 像素的边框,总共构成 260 像素的可见宽度。
您可以通过指定 border-box
大小来更改此设置:
.my-box {
box-sizing: border-box;
width: 200px;
border: 10px solid;
padding: 20px;
}
此替代框模型会告知 CSS 将 width
应用于边框框,而不是内容框。这意味着我们的 border
和 padding
会被推入,因此当您将 .my-box
设置为 200px
宽度时,它实际上会以 200px
宽度进行渲染。
在以下互动式演示中,了解此功能的运作方式。当您切换 box-sizing
值时,蓝色区域会显示框内正在应用的 CSS。
*,
*::before,
*::after {
box-sizing: border-box;
}
此 CSS 规则会选择文档中的每个元素以及每个 ::before
和 ::after
伪元素,并应用 box-sizing: border-box
。这意味着,现在每个元素都使用此替代盒模型。
由于替代框模型的可预测性更高,因此开发者通常会将此规则添加到重置和规范化器中,例如此规则。