格式化上下文简介

本文介绍了格式化上下文的概念,它有多种类型,包括块级格式化上下文、行内格式化上下文和弹性格式化上下文。文章还介绍了它们的基本行为以及如何利用这些行为。

页面上的每个元素都属于一个格式化上下文,或者一个被定义为以特定方式布局内容的区域。一个块级格式化上下文(BFC)将根据块级布局规则来布局其子元素,一个弹性格式化上下文将将其子元素布局为弹性项目,等等。每个格式化上下文都有关于布局在该上下文中如何表现的特定规则。

块级格式化上下文

文档中使用块级布局规则的最外层元素建立了第一个,即初始块级格式化上下文。这意味着<html>元素块内的所有元素都按照正常流布局,遵循块级和行内布局的规则。参与BFC的元素使用CSS盒模型中概述的规则,该模型定义了元素的边距、边框和内边距如何与同一上下文中的其他块进行交互。

创建新的块级格式化上下文

<html>元素并不是唯一能够创建块级格式化上下文的元素。通过应用某些CSS属性,任何块级元素都可以被创建为一个BFC。

在以下情况下会创建一个新的BFC:

  • 使用float浮动的元素
  • 绝对定位的元素
  • 带有display: inline-block的元素
  • 表格单元格或带有display: table-cell的元素,包括使用display: table-*属性时创建的匿名表格单元格
  • 表格标题或带有display: table-caption的元素
  • overflow值不为visible的块级元素
  • 带有display: flow-rootdisplay: flow-root list-item的元素
  • 带有contain: layout, contentstrict 的元素
  • 弹性项目
  • 网格项目
  • 多列容器
  • column-span设置为all的元素

这很有用,因为新的BFC将表现得像最外层文档一样,它成为主布局中的一个迷你布局。一个BFC包含它内部的所有内容,floatclear只适用于同一格式化上下文中的项目,并且边距只在同一格式化上下文中的元素之间折叠。

BFC创建示例

让我们看几个例子,以了解创建新BFC的效果。

在下面的例子中,我们有一个浮动元素在一个带有边框的<div>内部。该<div>的内容与浮动元素并排浮动。由于浮动元素的内容比其旁边内容高,所以<div>的边框现在穿过了浮动元素。正如流内和流外元素指南中所解释的,浮动元素已被移出流,因此div的背景和边框只包含内容,而不包含浮动元素。

html
<div class="box">
  <div class="float">I am a floated box!</div>
  <p>I am content inside the container.</p>
</div>
css
body {
  font: 1.2em sans-serif;
}

.box {
  background-color: rgb(224 206 247);
  border: 5px solid rebeccapurple;
}

.float {
  float: left;
  width: 200px;
  height: 100px;
  background-color: white;
  border: 1px solid black;
  padding: 10px;
}

创建一个新的BFC将包含浮动元素。过去常用的方法是将overflow: auto或将overflow: visible的初始值设置为其他值。

css
body {
  font: 1.2em sans-serif;
}
.box {
  background-color: rgb(224 206 247);
  border: 5px solid rebeccapurple;
  overflow: auto;
}

.float {
  float: left;
  width: 200px;
  height: 150px;
  background-color: white;
  border: 1px solid black;
  padding: 10px;
}

设置overflow: auto创建了一个包含浮动元素的新BFC。我们的<div>现在成为我们布局中的一个迷你布局。任何子元素都将被包含在其中。

使用overflow创建新BFC的问题是,overflow属性旨在告诉浏览器如何处理溢出内容。在某些情况下,当您纯粹为了创建BFC而使用此属性时,您会发现出现不需要的滚动条或剪裁的阴影。此外,对于未来的开发人员来说,它的可读性可能不高,因为您使用overflow的目的可能不明显。如果您这样做,最好在代码中添加注释进行解释。

使用display: flow-root显式创建BFC

在包含块上使用display: flow-root(或display: flow-root list-item)将创建一个新的BFC,而不会产生任何其他潜在的问题副作用。

css
body {
  font: 1.2em sans-serif;
}
.box {
  background-color: rgb(224 206 247);
  border: 5px solid rebeccapurple;
  display: flow-root;
}

<div>上设置display: flow-root后,该容器内的所有内容都将参与该容器的块级格式化上下文,浮动元素不会从元素底部溢出。

flow-root关键字的名称指的是您正在创建的本质上类似于一个新的根元素(就像<html>所做的那样),考虑到新上下文的创建方式及其流布局功能。

行内格式化上下文

行内格式化上下文存在于其他格式化上下文内部,可以被认为是段落的上下文。段落创建了一个行内格式化上下文,在该上下文中,诸如<strong><a><span>元素用于文本。

盒模型不完全适用于参与行内格式化上下文的项目。在水平书写模式的行中,水平内边距、边框和外边距将应用于元素并向左右推开文本。但是,元素上方和下方的外边距将不会被应用。垂直内边距和边框将被应用,但可能会与上方和下方的内容重叠,因为在行内格式化上下文中,行框不会被内边距和边框推开。

html
<p>
  Before that night—<strong>a memorable night</strong>, as it was to
  prove—hundreds of millions of people had watched the rising smoke-wreaths of
  their fires without drawing any special inspiration from the fact.
</p>
css
body {
  font: 1.2em sans-serif;
}
p {
  margin-top: 2em;
}
strong {
  margin: 20px;
  padding: 20px;
  border: 5px solid rebeccapurple;
}

其他格式化上下文

本指南涵盖流布局,因此不涉及其他可能的格式化上下文。因此,了解创建任何类型的格式化上下文都会改变该格式化上下文内部元素行为的方式非常有用。这种行为始终在规范和MDN上进行描述。

总结

在本指南中,我们更详细地研究了块级和行内格式化上下文以及创建块级格式化上下文(BFC)的重要主题。在下一个指南中,我们将了解正常流如何与不同的书写模式交互

另见