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;
}
内容最终宽度为 142px,而不是您指定的 100px,并且超出了您的元素。这是为什么呢?
盒模型是 CSS 的核心基础。了解盒模型的工作原理、它如何受 CSS 其他方面的影响,以及重要的是,您如何控制它,可以帮助您编写更可预测的 CSS。
重要的是要记住,CSS 显示的所有内容都是一个框,即使它只是一些文本,或者具有使其看起来像圆形的 border-radius
。
内容和尺寸
框根据其 display
值、其设置的尺寸以及它们包含的内容而具有不同的行为。此内容可以是纯文本,也可以是子元素生成的更多框。无论哪种方式,默认情况下,内容都会影响框的大小。
您可以使用外在尺寸来控制这一点,或者您可以使用内在尺寸让浏览器根据内容大小为您做出决定。
这是一个基本的演示,解释了差异
该演示在一个具有固定尺寸和粗边框的框中包含单词“CSS is awesome”。由于该框具有指定的宽度,因此它是外在尺寸的。这意味着它控制其子内容的尺寸。但是,单词“awesome”对于该框来说太大了,因此它溢出了父框的边框框(稍后详细介绍)。防止此溢出的一种方法是让框成为内在尺寸的,方法是不设置宽度,或者在本例中,将 width
设置为 min-content
。min-content
关键字告诉框仅与其内容的内在最小宽度(单词“awesome”)一样宽。这使框可以完美地贴合文本周围。
这是一个更复杂的示例,展示了不同尺寸对真实内容的影响
切换内在尺寸的开启和关闭,以查看外在尺寸如何在具有外在尺寸的情况下为您提供更多控制,而内在尺寸如何在具有内在尺寸的情况下为内容提供更多控制。要查看效果,请向卡片添加几句话文本。当此元素具有外在尺寸时,您可以添加的内容量是有限制的,超过限制内容将溢出,但这在切换内在尺寸时不会发生。
默认情况下,此元素具有设置为 400px
的 width
和 height
。这些尺寸为元素内部的所有内容提供了严格的边界,除非内容对于框来说太大,否则这些边界都会被遵守。您可以通过将花朵图片下方的标题更改为超出框高度的内容来查看此操作。
关键术语:当内容对于其所在的框来说太大时,会发生溢出。您可以使用 overflow
属性管理元素如何处理溢出内容。
切换到内在尺寸使浏览器可以根据框的内容大小为您做出决定。这使得溢出不太可能发生,因为框会随其内容调整大小。
重要的是要记住,内在尺寸是浏览器的默认行为,并且它通常比外在尺寸提供更大的灵活性。
盒模型的区域
框由不同的盒模型区域组成,所有区域都执行特定的工作。
内容框是内容所在的区域。内容可以控制其父级的大小,因此这通常是尺寸变化最大的区域。
内边距框环绕内容框,是由 padding
属性创建的空间。由于内边距位于框内,因此框的背景在它创建的空间中可见。如果框设置了溢出规则,例如 overflow: auto
或 overflow: scroll
,则滚动条也占用此空间。
边框框环绕内边距框,其空间由 border
值定义,该值会为元素创建视觉框架。元素的边框边缘是您可以看到的极限。
最后一个区域,外边距框,是框周围的空间,由框的 margin
规则定义。诸如 outline
和 box-shadow
之类的属性也占用此空间,因为它们绘制在元素顶部,并且不影响框的大小。在框上更改框的 outline-width
为 200px
不会更改边框边缘内的任何内容。
有用的类比
盒模型很难理解,因此这里有一个关于您目前所学内容的类比。

在此图中,您有三个并排安装在墙上的相框。镶框图像的元素对应于盒模型,如下所示
- 内容框是艺术品。
- 内边距框是白色安装板,位于框架和艺术品之间。
- 边框框是框架,为艺术品提供字面意义上的边框。
- 外边距框是框架之间的空间。
- 阴影占用的空间与外边距框相同。
调试盒模型
浏览器开发者工具提供了所选框的盒模型计算的可视化,这可以帮助您了解盒模型的工作原理以及它如何影响您正在处理的网站。
在您自己的浏览器中尝试此操作
控制盒模型
要了解如何控制盒模型,您首先需要了解浏览器中发生的情况。
每个浏览器都将用户代理样式表应用于 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;
。这意味着当您设置诸如 width
和 height
之类的尺寸时,这些尺寸将应用于内容框。如果您随后设置 padding
和 border
,这些值将添加到内容框的大小中。
检查您的理解情况
测试您对影响盒模型大小的属性的知识。
.my-box { width: 200px; border: 10px solid; padding: 20px; }
您认为 .my-box
将有多宽?
box-sizing: border-box
,则 200px
将是正确的。此框的实际宽度为 260px。由于 CSS 使用默认的 box-sizing: content-box
,因此应用的宽度是内容的宽度,并且两侧的 padding
和 border
会添加到该宽度中。内容 200px + 内边距 40px + 边框 20px,总可见宽度为 260px。
您可以通过指定 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
。这意味着每个元素现在都使用此替代盒模型。
由于替代盒模型可能更可预测,因此开发人员通常会将此规则添加到重置和规范化器中,例如这个。