您可能从未听说过BFC(块格式设置上下文)一词,但是如果您使用CSS进行布局,则您可能已经知道它的作用。在本文中,我将解释创建块格式上下文的现有方法,以及为什么它在CSS布局中很重要,并向您展示一种新的创建方法。
一旦了解了CSS布局中的一些概念,它们便可以真正增强CSS的功能。本文是关于块格式化上下文(BFC)的。您可能从未听说过该术语,但是如果您曾经使用CSS进行过布局,则可能知道它是什么。了解BFC是什么,它为什么起作用以及如何创建BFC很有用,并且可以帮助您了解CSS中布局的工作原理。
在本文中,我将通过您熟悉的示例来说明BFC是什么。然后,我将向您展示display的新价值,只有在您了解BFC是什么以及为什么需要BFC之后,它才有意义。
什么是BFC?
通过一个简单的float示例,最容易理解块格式化上下文(BFC)的行为。在下面的示例中,我有一个框,其中包含一个向左浮动的图像和一些文本。
<div class="outer">
<div class="float">I am a floated element.</div>
I am text inside the outer box.
</div>
.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;
}
如果我们有大量的文字,它会围绕浮动的图片,然后边框会围绕整个图片。
如果我删除了一些文本,则表示图像周围没有足够的内容,并且由于float
已从文档流中移出,因此边框会上升并在图像下方延伸到文本的高度。
发生这种情况的原因是,当我们浮动一个元素时,文本所在的框保持相同的宽度,为浮动元素留出空间的缩写是文本的线框。这就是为什么背景和边框会出现在浮动框后面的原因。
通常,有两种方法可以解决此布局问题。一种方法是使用clearfix hack,其作用是在文本和图像下方插入一个元素并将其设置为同时清除两者。另一种方法是使用溢出属性,其值不同于默认值visible。
.outer {
overflow: auto;
}
overflow
以这种方式工作的原因是,使用除初始值之外的任何值visible
都会创建一个BFC
,并且BFC
的功能之一就是它包含float
。
BFC是布局中的迷你布局
您可以将BFC视为页面内的迷你布局。一旦元素创建了BFC,所有内容都将包含在其中。如我们所见,这包括float
,这些元素不再从边框的底部溢出来。BFC还导致其他一些有用的行为。
BFC防止margin
塌陷
了解margin
塌陷是另一项被低估的CSS技能。在下一个示例中,我有一个div,背景色为灰色。
这个div内部有两个段落。外部div元素的底边距为40像素;这些段落的顶部和底部边距也为20像素。
.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元素的边距和外部div的边距之间没有任何关系,因此两者将折叠,因此段落最终与框的顶部和底部齐平。我们在段落的上方和下方均看不到任何灰色。
但是,如果我们将框设为BFC,则现在包含段落及其边距,因此它们不会折叠,并且可以看到边距后面的容器的灰色背景。
.outer {
background-color: #ccc;
margin: 0 0 40px 0;
overflow: auto;
}
BFC再一次完成了将子元素包含在其中的工作,阻止它们溢出。
BFC阻止content包裹float
。
您还将熟悉BFC的这种行为,因为它是使用float
的任何列类型布局的工作方式。如果某个元素创建了BFC,则该元素将不会包装任何float
。在以下示例中,我做了如下标记:
<div class="outer">
<div class="float">I am a floated element.</div>
<div class="text">I am text</div>
</div>
具有float的元素向左浮动,因此div中紧随其后的文本将环绕浮动。
我可以通过将包装文本的div设置为BFC来防止这种包装行为。
.text {
overflow: auto;
}
本质上,这是我们可以创建具有多列的float布局的方法。浮动项目也会为该项目创建一个BFC,因此,如果右边的一个比左边的一个高,那么我们的列就不会试图彼此环绕。
还有什么创造了BFC?
除了用于overflow创建BFC之外,其他一些CSS属性还会创建BFC。如我们所见,float
元素会创建BFC。因此,您的浮动元素中将包含任何子元素。
在元素上使用position: absolute
或position: fixed
。
使用display: inline-block
,display: table-cell
或display: table-caption
。table-cell
和table-captions
为HTML元素的默认属性,他们为每个element将创建一个BFC。
using column-span: all
,用于跨多列布局的列。除了将Flex和Grid项分别描述为Flex格式设置上下文和Grid格式设置上下文之外,Flex和Grid项还创建类似于BFC的内容。这反映了每个人都参与的布局类型。“块格式化上下文”表示该项目正在参与“块布局”,“ Flex格式化上下文”表示该项目正在参与“ Flex布局”。实际上,结果是相同的,包含float且边距不会崩溃。
创建BFC的新方法
使用overflow
或使用其他方法创建BFC有两个问题。
首先,这些方法基于实际设计的目的会产生副作用。溢出方法会创建一个BFC并包含float,但是在某些情况下,您可能会发现不想要的滚动条或阴影被修剪了。这是由于事实,溢出属性旨在允许您告诉浏览器在溢出情况下该怎么做-导致滚动条或剪辑内容。浏览器完全按照您的指示执行操作!
即使在没有任何不良副作用的情况下,使用overflow也可能会使其他开发人员感到困惑。为什么将溢出设置为自动或滚动?原始开发者的意图是什么?他们是否需要此组件上的滚动条?
有用的是创建一种懒加载的BFC的方法,该BFC不会造成其他行为,只能创建该mini layout,并且能够安全地在其中进行操作。该方法不会引起任何意外的问题,并且还可以使开发人员明确其意图。CSS委员会认为这也可能非常方便,因此我们有了display
属性的新值: flow-root
。
您可以display: flow-root
在本文中的任何情况下使用创建新的BFC都是有利的-包含float,防止边距崩溃或防止项目包装float。
如果您的浏览器支持display: flow-root
最新的Firefox或Chrome浏览器,则可以在CodePen中查看所有这些信息。
浏览器对display: flow-root
的支持
浏览器对flow-root
的支持是有限的,但是会增加,即使您现在无法在代码中使用方便的flow-root
功能,您现在也可以了解BFC是什么,以及在使用overflow
或其他方法包含float
的操作。例如,如果要在不支持的浏览器中为flex或grid布局创建后备,了解BFC将停止包裹float的项目这一事实非常有用。
您还了解一些关于浏览器如何布局网页的基本知识。尽管它们本身似乎无关紧要,但这些知识点可以缩短创建和调试CSS布局所需的时间。