The box model

 

CSS中的所有内容周围都有一个框,了解这些框是能够使用CSS创建布局或将项目与其他项目对齐的关键. 在本课程中,我们将对CSS Box Model进行适当的了解,以便您可以在理解CSS的工作原理以及与之相关的术语的基础上,构建更复杂的布局任务.

Prerequisites: 基本的计算机知识, 已安装的基本软件使用文件的基本知识,HTML基础(研究HTML简介 )以及CSS的工作原理(研究CSS第一步) .
Objective: 要了解CSS盒子模型,盒子模型的组成以及如何切换到替代模型.

Block and inline boxes

在CSS中,我们大致有两种类型的框- 块框嵌入式框 . 这些特征指的是框在页面流方面的行为方式,以及与页面上其他框的关系:

如果将框定义为块,它将以以下方式运行:

  • 该框将沿内联方向延伸以填充其容器中的可用空间. 在大多数情况下,这意味着盒子将变得和容器一样宽,将占据100%的可用空间.
  • 该框将换行.
  • 注意widthheight属性.
  • 填充,边距和边框将导致其他元素被推离盒子

除非我们决定将显示类型更改为嵌入式显示,否则默认情况下,标题(例如<h1> )和<p>类的元素都将block作为其外部显示类型.

如果框的外部显示类型为inline ,则:

  • 该框将不会换行.
  • widthheight属性将不适用.
  • 填充,边距和边界将适用,但不会导致其他嵌入式框从框移开.

用于链接的<a>元素<span><em><strong>都是默认情况下将内联显示的元素的所有示例.

应用于元素的框的类型由display属性值(例如blockinline ,并且与display外部值有关.

Aside: Inner and outer display types

在这一点上,我们最好还要解释内部外部显示类型. 如上所述,CSS中的框具有外部显示类型,该类型详细说明了框是内嵌还是内嵌.

框还具有内部显示类型,但是,该类型指示框内元素的布局方式. 默认情况下,框内的元素以正常流程进行布局,这意味着它们的行为与任何其他block和inline元素一样(如上所述).

但是,我们可以通过使用诸如flex display值来更改内部显示类型. 如果设置display: flex; 在元素上,外部显示类型为block ,但内部显示类型更改为flex . 此框的任何直接子级都将成为flex项目,并将根据Flexbox规范中列出的规则进行布局,稍后您将学习.

注意 :要了解有关display值的更多信息以及框在块和行内布局中的工作方式,请查看MDN的" 块和行内布局"指南.

当您继续详细了解CSS Layout时,您会遇到flex以及盒子可以具有的其他各种内部值,例如grid .

但是,块和内联布局是Web上的行为的默认方式-如上所述,有时将其称为正常流程 ,因为在没有任何其他说明的情况下,我们的框布局为块或内联框.

Examples of different display types

让我们继续看一些示例. 下面我们有三个不同的HTML元素,所有这些元素都有一个外部显示类型的block . 第一个是段落,在CSS中添加了边框. 浏览器将其呈现为一个方框框,因此该段落以新行开始,并扩展为可用的整个宽度.

第二个是列表,使用display: flex布局. 这将为容器内的项目建立灵活的布局,但是,列表本身是一个阻止框,并且像该段落一样,扩展到整个容器的宽度并换行.

在此之下,我们有一个块级段落,其中有两个<span>元素. 这些元素通常是inline ,但是其中一个元素具有一类的block,我们将其设置为display: block .

 

在下一个示例中,我们可以看到inline元素的行为. 默认情况下,第一段中的<span>元素是内联的,因此不要强制换行.

我们还有一个<ul>元素,该元素设置为display: inline-flex ,在一些flex项目周围创建一个内联框.

最后,我们将两个段落都设置为display: inline . 内联flex容器和段落都在一行上一起运行,而不是像显示为块级元素那样将它们换成新行.

在示例中,您可以将display: inline更改为display: blockdisplay: inline-flex更改为display: flex在这些显示模式之间切换.

 

在这些课程的后面,您将遇到诸如flex layout之类的事情. 现在要记住的关键是更改display属性的值可以更改框的外部显示类型是块显示还是嵌入式显示,这会更改其与布局中其他元素一起显示的方式.

在本课程的其余部分中,我们将专注于外部显示类型.

What is the CSS box model?

完整的CSS盒模型适用于块盒,内联盒仅使用盒模型中定义的某些行为. 该模型定义了框的不同部分(边距,边框,填充和内容)如何共同创建一个可以在页面上看到的框. 为了增加一些其他的复杂性,有一个标准的和备用的盒子模型.

Parts of a box

在CSS中制作一个方块,我们有:

  • 内容框 :显示内容的区域,可以使用widthheight类的属性来调整其大小.
  • 填充框 :填充物围绕内容位于空白处; 可以使用padding和相关属性来控制其大小.
  • 边框 :边框用于包装内容和任何填充. 可以使用border和相关属性来控制其大小和样式.
  • 边距框 :边距是最外层,将内容,填充和边框包装为此框与其他元素之间的空白. 可以使用margin和相关属性来控制其大小.

下图显示了这些层:

Diagram of the box model

The standard CSS box model

在标准框模型中,如果为框指定widthheight属性,则这将定义内容框的宽度和高度. 然后,将任何填充和边框添加到该宽度和高度,以获取框占用的总大小. 如下图所示.

如果我们假设此框具有定义widthheightmarginborderpadding的以下CSS:

.box {
  width: 350px;
  height: 150px;
  margin: 10px;
  padding: 25px;
  border: 5px solid black;
}

我们的盒子使用标准盒子模型占用的空间实际上将为410px(350 + 25 + 25 + 5 + 5),高度为210px(150 + 25 + 25 + 5 + 5),因为填充和边框为添加到用于内容框的宽度.

Showing the size of the box when the standard box model is being used.

注意 :页边距不计入框的实际大小-当然,它会影响框在页面上所占的总空间,而仅影响框外的空间. 框的区域在边界处停止-不会延伸到边缘.

The alternative CSS box model

您可能会认为必须加边框和内边距来获得盒子的实际大小是很不方便的,您是对的! 因此,CSS在标准盒模型之后的一段时间推出了另一种盒模型. 使用此模型,任何宽度都是页面上可见框的宽度,因此内容区域的宽度是该宽度减去填充和边框的宽度. 与上面使用的相同CSS将产生以下结果(宽度= 350px,高度= 150px).

Showing the size of the box when the alternate box model is being used.

默认情况下,浏览器使用标准盒模型. 如果要为元素打开替代模型,可以通过在其上设置box-sizing: border-box来实现. 通过这样做,您告诉浏览器将边框作为由您设置的任何大小定义的区域.

.box { 
  box-sizing: border-box; 
} 

如果您希望所有元素都使用替代框模型,这是开发人员的常见选择,请在<html>元素上设置box-sizing属性,然后将所有其他元素设置为继承该值,如下面的代码段. 如果您想了解其背后的想法,请参阅关于box-sizing的CSS Tricks文章 .

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

注意 :一段有趣的历史记录-Internet Explorer过去默认使用替代盒型,没有可用的切换机制.

Playing with box models

在下面的示例中,您可以看到两个框. 两者都具有.box类,因此它们具有相同的widthheightmarginborderpadding . 唯一的区别是第二个盒子已设置为使用替代盒子模型.

您可以更改第二个框的大小(通过将CSS添加到.alternate类中)以使其与第一个框的宽度和高度匹配吗?

 

注意 :您可以在此处找到此任务的解决方案.

Use browser DevTools to view the box model

您的浏览器开发人员工具可以使了解盒子模型变得更加容易. 如果您在Firefox的DevTools中检查某个元素,则可以看到该元素的大小以及其边距,边距和边框. 以这种方式检查元素是一种很好的方法,可以确定您的盒子是否真的像您认为的那样大!

Inspecting the box model of an element using Firefox DevTools

Margins, padding, and borders

在上面的示例中,您已经看到了marginpaddingborder属性的工作. 该示例中使用的属性是简写形式 ,使我们可以立即设置框的所有四个侧面. 这些速记也具有等效的速记属性,可分别控制盒子的不同侧面.

Let's explore these properties in more detail.

Margin

边距是盒子周围的不可见空间. 它将其他元素推离盒子. 边距可以具有正值或负值. 在框的一侧设置负页边距会导致其与页面上的其他内容重叠. 无论您使用的是标准框模型还是备用框模型,都始终在计算可见框的大小之后添加边距.

我们可以使用margin属性一次控制元素的所有边距,或者使用等效的longhand属性分别控制每一边:

在下面的示例中,尝试更改页边距值,以查看由于该页边距在此元素和包含元素之间创建或删除了空间(如果为负页边距)而导致框被推入的情况.

 

Margin collapsing

了解保证金的关键是保证金崩溃的概念. 如果您有两个边距相接的元素,且两个边距均为正,则这些边距将合并为一个边距,即最大单个边距的大小. 如果一个或两个边距均为负数,则负值的数量将从总数中减去.

在下面的示例中,我们有两个段落. 最上段margin-bottom为50像素. 第二段的页margin-top为30像素. 边距已合拢,因此框之间的实际边距为50像素,而不是两个边距的总和.

您可以通过将第二段的页margin-top设置为0进行测试.两段之间的可见页边距将保持不变-它保留在第一段的bottom-margin中设置的50个像素. 如果将其设置为-10像素,则会看到整体边距变为40像素-从50像素减去.

 

There are a number of rules that dictate when margins do and do not collapse. For further information see the detailed page on mastering margin collapsing. The main thing to remember for now is that margin collapsing is a thing that happens. If you are creating space with margins and don't get the space you expect, this is probably what is happening.

Borders

在框的边距和填充之间绘制边框. 如果使用标准盒子模型,则边框的大小会添加到盒子的widthheight中. 如果使用的是备用框模型,则边框的大小会使内容框变小,因为它占用了一些可用的widthheight .

对于边框样式,有大量的属性-有四个边框,每个边框都有我们可能要操纵的样式,宽度和颜色.

您可以使用border属性同时设置所有四个边框的宽度,样式或颜色.

要分别设置每侧的属性,可以使用:

若要设置所有边的宽度,样式或颜色,请使用以下命令:

要设置单面的宽度,样式或颜色,可以使用最精细的一手属性:

在下面的示例中,我们使用了各种速记和速记来创建边框. 尝试一下不同的属性,以检查您是否了解它们的工作原理. 边框属性的MDN页面为您提供有关可以选择的不同边框样式的信息.

 

Padding

填充位于边框和内容区域之间. 与边距不同,您不能有负的填充量,因此该值必须为0或正值. 应用于元素的任何背景将显示在填充的后面,通常用于将内容推离边框.

我们可以使用padding属性单独控制元素每一侧的padding ,也可以使用等效的longhand属性分别控制元素每一侧的padding

如果在下面的示例中更改类.box上的padding值,则可以看到这会更改文本相对于box的开始位置.

您还可以更改类.container,上的填充.container,这将在容器和盒子之间.container,出空间. 填充可以在任何元素上进行更改,并且会在其边框和元素内部的内容之间留出空间.

 

The box model and inline boxes

All of the above applies fully to block boxes. Some of the properties can apply to inline boxes too, such as those created by a <span> element.

在下面的示例中,我们在一个段落内有一个<span> ,并对其应用了widthheightmarginborderpadding . 您可以看到宽度和高度被忽略. 边距,边距和边框均得到尊重,但它们不会更改其他内容与我们的内联框的关系,因此,边距,边框与段落中的其他字词重叠.

 

Using display: inline-block

有一个特殊的值display ,其提供之间的中间地带inlineblock . 这在您不希望某项分解到新行,但希望它尊重widthheight并避免上面看到的重叠的情况下很有用.

具有display: inline-block的元素执行我们已经了解的块内容的子集:

  • 注意widthheight属性.
  • paddingmarginborder会导致其他元素被推离盒子.

但是,它不会换行,只有显式添加widthheight属性时,它的大小才会大于其内容.

在下一个示例中,我们在<span>元素中添加了display: inline-block . 尝试将其更改为display: block完全display: block或移去该行以查看显示模型的差异.

 

当您想通过添加padding链接到较大的点击区域时,这很有用. <a>是内联元素,例如<span> ; 您可以使用display: inline-block来设置填充,以便用户单击链接.

You see this fairly frequently in navigation bars. The navigation below is displayed in a row using flexbox and we have added padding to the <a> element as we want to be able to change the background-color when the <a> is hovered. The padding appears to overlap the border on the <ul> element. This is because the <a> is an inline element.

添加display: inline-block使用.links-list a选择器将规则display: inline-block到规则中,您将看到它如何通过引起其他元素尊重填充来解决此问题.

 

Test your skills!

我们在本文中介绍了很多内容,但是您能记住最重要的信息吗? 在继续之前,您可以找到一些进一步的测试来验证您是否保留了此信息—请参阅测试您的技能:盒子模型 .

Summary

这是您需要了解的关于盒子模型的大部分内容. 如果您对版式中的大包装盒感到困惑,则可能希望在将来重读本课.

在下一课中,我们将研究如何使用背景和边框使普通框看起来更有趣.

In this module

  1. Cascade and inheritance
  2. CSS selectors
  3. The box model
  4. Backgrounds and borders
  5. Handling different text directions
  6. Overflowing content
  7. Values and units
  8. Sizing items in CSS
  9. Images, media, and form elements
  10. Styling tables
  11. Debugging CSS
  12. Organizing your CSS