链接

格式上下文

页面上的所有东西都处在一个格式上下文中,这个格式上下文可以理解为一个固有结界,它依据规则规定如何摆放内容。

Block Formatting Context根据Block Layout rules来摆放它的子元素。

Flex Formatting Context把它的子元素按照flex items摆放。

html元素定义了最初的BFC,意味着html中的元素都依据Normal Flow的规则摆放。这个规则由css盒模型勾勒,定义了元素的marginborderpadding是如何和相邻的block元素交互的。

创建BFC

html元素不是唯一具有创建BFC能力的元素。新的BFC和document的效果类似,就好像在一个主布局中开辟了一个迷你布局。浮动和清除浮动只会应用在位于相同格式上下文中的元素,而margin也只会collapse在位于相同格式上下文中的元素。

除了html,下面这些情况也会创建BFC

  1. 浮动元素
  2. 绝对定位元素
  3. display:inline-block属性值的元素
  4. table cells或者是有display:table-cell属性值的元素
  5. table caption或者是有display:table-caption属性值的元素
  6. 块状元素的overflow属性的属性值是visible以外的值
  7. display: flow-root
  8. contain:layout,content或者strict的元素
  9. flex项目
  10. grid项目
  11. 多列容器
  12. column-span:all的元素

下面是几个脱离正常流的例子

浮动

浮动元素会脱离正常流,创建一个新的BFC。

这个浮动的例子

直接翻译这个例子下面的解释:你能看到紧随其后的段落的背景颜色穿过浮动元素。只有段落中的行盒子被压缩导致了文本环绕浮动元素的效果。段落的盒子依旧按照正常流的规则摆放,所以要使得浮动元素周围有空间,只能通过给浮动元素增加外边距的办法,给还处在正常流中的内容应用其他方法都做不到。

绝对定位

给一个元素赋值position: absolute或者position: fixed都会将它从正常流中移除,并且它占有的空间也会一同被夺走。

相对定位

给一个元素赋值position:relative表示他将会继续待在正常流中,然而你可以使用offset将它向四处推动。它在正常流中的空间依然会被保留。


继续创建BFC的话题

下面这个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
.box {
background-color: rgb(244, 206, 247);
border: 5px solid rebeccapurple;
overflow: auto;
}
.float {
float: left;
width: 200px;
height: 150px;
background-color: white;
border: 1px solid black;
padding: 10px;
}

1
2
3
4
<div class="box">
<div class="float">I am a floated box!</div>
<p>I am content inside the container.</p>
</div>

创建一个新的BFC会承载这个浮动元素。之前典型的做法是设置overflow: auto或者是设置其他非默认值overflow: visible。现在我们的div成为我们布局中的一个迷你布局了,任何子元素都将被它包含在其中

使用overflow来创建BFC的问题在于overflow属性是用来告知浏览器你想如何处理满溢的内容(也就是说虽然能达到效果但是不合语义)。仅使用这个方法,在某些情况下,还会出现导航条或是修剪阴影的副作用。除此之外,对于后面的开发者也会带来阅读理解的问题,他们可能意识不到你是出于这个目的设置了这个属性在此,如果这样做了,最好留下注释。

一个完美的解决办法是使用display: flow-root这个新属性来创建新的BFC,这个属性不会带来任何副作用(看名字就知道干嘛用哒)。在div上使用display: flow-root,其中的所有子元素都将是这个新BFC的参与者,就不会出现浮动元素戳破其父元素(父元素有内容)或者父元素高度为零(父元素没有内容)的情况了。

元素浮动父元素高度出现坍塌的原因:在计算页面排版的时候,如果没有设置父元素的高度,那么该父元素的高度是由他的子元素的高度撑开的。但是如果子元素是设置了浮动,脱离了文档流,那么父元素计算高度的时候就会忽略该子元素,就可能会出现父元素高度为零的情况。

新建BFC解决高度坍塌的原理:父元素在新建一个BFC的时候,其高度计算时,会把浮动子元素包进来。

inline formatting context

链接

IFC(为啥没有这种缩写?这里就用这个缩写了)存在于其他格式上下文中,可以被想成是一个段落的上下文。这个段落创建了一个IFC,其中比如strongaspan这些元素都是用在文本上的。

盒模型不会完全用在IFC中的内容上。在水平书写的一行文本中,水平方向上的paddingborders以及margin将会生效,将左右两侧的文本推开。margin在竖直方向上不会生效,boderpadding在竖直方向上会生效,但起不到推开上下内容的作用。

示例如下:

1
<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>
1
2
3
4
5
strong {
margin: 20px;
padding: 20px;
border: 5px solid rebeccapurple;
}

其他格式上下文

创建任何种类的格式上下文,都将改变位于其中的子元素的排布方式。