css查漏补缺之一-格式上下文
/ / 点击 / 阅读耗时 10 分钟格式上下文
页面上的所有东西都处在一个格式上下文中,这个格式上下文可以理解为一个固有结界,它依据规则规定如何摆放内容。
Block Formatting Context
根据Block Layout rules
来摆放它的子元素。
Flex Formatting Context
把它的子元素按照flex items
摆放。
html
元素定义了最初的BFC
,意味着html
中的元素都依据Normal Flow
的规则摆放。这个规则由css盒模型
勾勒,定义了元素的margin
,border
, padding
是如何和相邻的block元素交互的。
创建BFC
html
元素不是唯一具有创建BFC能力的元素。新的BFC和document的效果类似,就好像在一个主布局中开辟了一个迷你布局。浮动和清除浮动只会应用在位于相同格式上下文中的元素,而margin也只会collapse在位于相同格式上下文中的元素。
除了html,下面这些情况也会创建BFC
- 浮动元素
- 绝对定位元素
- 有
display:inline-block
属性值的元素 - table cells或者是有
display:table-cell
属性值的元素 - table caption或者是有
display:table-caption
属性值的元素 - 块状元素的
overflow
属性的属性值是visible
以外的值 display: flow-root
- 有
contain:layout,content或者strict
的元素 - flex项目
- grid项目
- 多列容器
- 有
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 | <div class="box"> |
创建一个新的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,其中比如strong
,a
,span
这些元素都是用在文本上的。
盒模型不会完全用在IFC中的内容上。在水平书写的一行文本中,水平方向上的padding
,borders
以及margin
将会生效,将左右两侧的文本推开。margin
在竖直方向上不会生效,boder
和padding
在竖直方向上会生效,但起不到推开上下内容的作用。
示例如下:
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 | strong { |
其他格式上下文
创建任何种类的格式上下文,都将改变位于其中的子元素的排布方式。