作者:走走看看1971 | 来源:互联网 | 2020-11-22 01:52
本文是关于块格式化上下文(BFC)的。你可能从未听说过这个术语,但是如果你曾经用CSS做过布局,你可能知道它是什么,理解什么是BFC,怎么工作以及如何创建BFC非常有用,这些可以帮助你理解CSS中的布局是如何工作的。
CSS布局中有一些概念,一旦你理解了它们,就能真正提高你的 CSS 布局能力。本文是关于块格式化上下文(BFC)的。你可能从未听说过这个术语,但是如果你曾经用CSS做过布局,你可能知道它是什么,理解什么是 BFC,怎么工作以及如何创建 BFC 非常有用,这些可以帮助你理解CSS中的布局是如何工作的。
(推荐教程:CSS教程)
在本文中,通过熟悉的示例来解释什么是 BFC。然后说明 display
的一个新值,只有当你理解了什么是 BFC
以及为什么需要它时,它才有意义。
什么是 BFC
在一个Web页面的CSS渲染中,块级格式化上下文 (Block Fromatting Context)是按照块级盒子布局的。W3C对BFC的定义如下:
浮动元素和绝对定位元素,非块级盒子的块级容器(例如 inline-blocks, table-cells, 和 table-captions),以及overflow值不为“visiable”的块级盒子,都会为他们的内容创建新的BFC(块级格式上下文)。
BFC是一个独立的布局环境,其中的元素布局是不受外界的影响,并且在一个 BFC 中,块盒与行盒(行盒由一行中所有的内联元素所组成)都会垂直的沿着其父元素的边框排列。
块格式化上下文(BFC)的行为通过一个简单的float
示例很容易理解。在下面的示例中,我有一个框,其中包含向左浮动的图像和一些文本。如果我们有足够多的文本,它会环绕浮动的图像和边框,然后环绕整个区域。
// html
I am a floated element.
I am text inside the outer box.
// css
.outer {
border: 5px dotted rgb(214,129,137);
border-radius: 5px;
width: 450px;
padding: 10px;
margin-bottom: 40px;
}
.float {
padding: 10px;
border: 5px solid rgba(214,129,137,.4);
border-radius: 5px;
background-color: rgba(233,78,119,.4);
color: #fff;
float: left;
width: 200px;
margin: 0 20px 0 0;
}
这是因为当我们浮动一个元素时,文本所在的框的宽度保持不变,为给浮动元素腾出空间而缩短的是文本的行框。这就是为什么背景和边框会出现在浮动后面的原因。
我们通常有两种方法来解决这个布局问题。一种方法是使用 clearfix hack,它的作用是在文本和图像下面插入一个元素,并将其设置为 clear:both
。另一种方法是使用 overflow
属性,其值不是缺省值 visible
。
.outer {
overflow: auto;
}
查看演示:https://codepen.io/anon/embed/XzYWZj?height=500&theme-id=0&slug-hash=XzYWZj&user=&default-tab=
overflow
以这种方式工作的原因是,使用 visible
的初值以外的任何值都会创建一个块格式化上下文,而 BFC 的一个特性是它包含浮动。
BFC 是布局中的一个迷你布局
你可以将 BFC 看作是页面内的一个迷你布局。一旦一个元素创建了一个 BFC,它就包含了所有的内容。正如我们所看到的,这包括浮动的元素,它们不再从盒子底部伸出来。BFC 还会导致一些其他有用的行为。
BFC 可以防止 margin 折叠
了解边距合并是另一个被低估的 CSS 技能。在下一个示例中,假设有一个背景颜色为灰色的 p
。
这个 p
包含两个标签 p
。外部 p 元素的 margin-bottom
为 40 像素,标签 p
的顶部和底部 margin
都是 20 像素。
// html
I am paragraph one and I have a margin top and bottom of 20px;
I am paragraph one and I have a margin top and bottom of 20px;
// css
.outer {
background-color: #ccc;
margin: 0 0 40px 0;
}
p {
padding: 0;
margin: 20px 0 20px 0;
background-color: rgb(233,78,119);
color: #fff;
}
因为 p
元素的 margin 和外部 p
上的 margin 之间没有任何东西,所以两个会折叠,因此 p
最终与 p
的顶部和底部齐平。 我们在 p
的上方和下方看不到任何灰色。
在CSS当中,相邻的两个盒子(可能是兄弟关系也可能是祖先关系)的外边距可以结合成一个单独的外边距。这种合并外边距的方式被称为折叠,并且因而所结合成的外边距称为折叠外边距。折叠的结果按照如下规则计算:
- 两个相邻的外边距都是正数时,折叠结果是它们两者之间较大的值。
- 两个相邻的外边距都是负数时,折叠结果是两者绝对值的较大值。
- 两个外边距一正一负时,折叠结果是两者的相加的和。
产生折叠的必备条件:margin必须是邻接的!
如果我们把盒子设为 BFC,它现在包含了标签 p
和它们的边距,这样它们就不会折叠,我们可以看到边距后面容器的灰色背景。
.outer {
background-color: #ccc;
margin: 0 0 40px 0;
overflow: auto;
}
查看演示:https://codepen.io/anon/embed/YEvzRv?height=500&theme-id=0&slug-hash=YEvzRv&user=&default-tab=
再一次,BFC 的工作是把东西装在盒子里,防止它们从盒子里跑出来。
BFC 可以阻止元素被浮动元素覆盖
你将熟悉 BFC 的这种行为,因为使用浮动的任何列类型布局都是这样工作的。如果一个项目创建了一个 BFC,那么该项目将不会包裹任何浮动元素。在下面的例子中,有如下 html 结构:
I am a floated element.
I am text
带有 float 类的项被向左浮动,因此 p
中的文本在它环绕 float
之后。
我可以通过将包裹文本的 p
设置为 BFC 来防止这种包裹行为。
.text {
overflow: auto;
}
这实际上是我们创建具有多个列的浮动布局的方法。浮动项还为该项创建了一个 BFC,因此,如果右边的列比左边的列高,那么我们的列就不会相互环绕。
查看演示:https://codepen.io/anon/embed/qVKEpJ?height=500&theme-id=0&slug-hash=qVKEpJ&user=&default-tab=
在多列布局中使用 BFC
如果我们创建一个占满整个容器宽度的多列布局,在某些浏览器中最后一列有时候会掉到下一行。这可能是因为浏览器四舍五入了列宽从而所有列的总宽度会超出容器。但如果我们在多列布局中的最后一列里创建一个新的BFC,它将总是占据其他列先占位完毕后剩下的空间。
例如:
column 1
column 2
column 3
对应的CSS:
.column {
width: 31.33%;
background-color: green;
float: left;
margin: 0 1%;
}
.column:last-child {
float: none;
}
未创建 BFC 之前:
添加以下样式创建一个 BFC:
.column:last-child {
float: none;
overflow: hidden;
}
浏览器对该属性的支持目前还是有限的,如果你觉得这个属性值很方便,请投票去让Edge也支持它。不过无论如何,你现在应该已经理解了什么是 BFC,以及如何使用 overflow 或其他方法来包裹浮动,以及知道了 BFC 可以阻止元素去环绕浮动元素,如果你想使用弹性或网格布局可以在一些不支持他们的浏览器中使用 BFC 的这些特性做降级处理。
理解浏览器如何布置网页是非常基础的。 虽然有时看起来无关紧要,但是这些小知识可以加快创建和调试 CSS 布局所需的时间。
以上就是深入浅析CSS 布局和 BFC的详细内容,更多请关注 第一PHP社区 其它相关文章!