这是我找到讲解 格式化上下文 (Block Formatting Context, BFC)
最棒的文章之一(下文统称 BFC
),因为 BFC
困扰我良久,但愿这篇翻译能让 BFC
再也不困扰你们。css
翻译是机翻 + 修改,会有删减,另外强烈推荐阅读原文。html
原文地址:www.smashingmagazine.com/2017/12/und…web
你可能从没听过“块格式化上下文”,可是若是你曾经用CSS作过布局,你可能就知道它是什么。本文将会讲述如何建立块格式化上下文,以及为何它在CSS布局中很重要,并向展现建立块格式化上下文的新方法。浏览器
有些概念一旦理解会确确实实增长你的CSS技能熟练度,而理解 BFC
以及知道如何建立 BFC
很是有用,能够帮助加深对CSS布局的理解。这篇文章会有丰富且常见的例子帮助你理解 BFC
,并解释为何你须要 BFC
。安全
只要经过一个简单的浮动布局的例子就能够理解 BFC
的行为。在下面的示例中,有一个 div
,div
里包含一个 向左浮动的div
和 一些文本
。若是文本足够多,就会环绕浮动元素,而后环绕整个区域。ide
<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;
}
复制代码
若是删除一些文本内容,那么就没有足够的内容来包围浮动元素,并且因为浮动是脱离文档流的,因此边框高度会变矮,只有到包含到文本的高度。即高度坍塌。布局
这是由于当咱们浮动一个元素时,文本所在的框的宽度保持不变,为了给浮动元素腾出空间而缩短的是文本的空间。ui
咱们一般有两种方法来解决这个布局问题。一种方法是使用 clearfix hack
(即清除浮动),它的做用是在文本和图像下面插入一个元素,并将其设置为 clear: both;
。另外一种方法是使用 overflow
属性,将其值改成 visible
之外的便可。spa
.outer {
overflow: auto;
}
复制代码
overflow: auto
令外部的div包含浮动元素另外,能够在CODEPEN中查看效果:codepen.io/rachelandre…翻译
overflow
以这种方式工做的缘由是,使用 除visible初值之外
的任何值都会建立一个 BFC
,而 BFC
的特性之一就是它能够包裹浮动元素。
译者注:重点之一, BFC
能够包裹浮动元素。即让浮动元素 看起来没有脱离文档流同样
,占据着其宽高大小的位置。
能够把 BFC
想象成页面内的迷你布局。一旦一个元素建立了一个 BFC ,全部的东西都包含在它里面。
正如咱们所看到的,包括浮动元素,它们再也不从盒子的底部伸出。 BFC
也会有一些其余有用的行为。
理解边距坍塌是另外一个被低估的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的页边距之间没有任何内容,这两个元素将折叠起来,所以段落最终与框的顶部和底部齐平。咱们在段落的上面和下面没有看到灰色背景。
若是咱们为外部div元素建立一个 BFC
,它就会包含段落和它们的边距,这样它们就不会折叠,咱们能够看到边距后面容器的灰色背景。
.outer {
background-color: #ccc;
margin: 0 0 40px 0;
overflow: auto; /* 建立BFC,参考:https://developer.mozilla.org/zh-CN/docs/Web/Guide/CSS/Block_formatting_context */
}
复制代码
在CODEPEN中查看代码:codepen.io/rachelandre…
(译者注:在理解BFC以前,我都是在外部元素里设置padding实现一样的效果!)
再次说明, BFC
的工做是把东西装在盒子里,而且防止它们从盒子里跑出来。
BFC
可让内容再也不包裹浮动元素。您还将熟悉 BFC
的这种行为,由于使用浮动的任何列类型布局都是这样工做的。
若是一个项建立了一个 BFC
,那么该项目将不会包裹任何浮动元素。在下面的例子中,有这样的标记:
<div class="outer">
<div class="float">I am a floated element.</div>
<div class="text">I am text</div>
</div>
复制代码
带有 float类
的项会向左浮动,所以div中的文本在它环绕 float
以后。
咱们能够经过将包裹文本的div设置为BFC来防止这种环绕行为。
.text {
overflow: auto;
}
复制代码
text
类的div如今是 BFC
,所以文本不会换行这实际上就是建立多个列浮动布局的方法。浮动项还为该项建立了一个BFC,所以,就算右边的列比左边的列高,各个列也不会相互环绕。
在CODEPEN中查看代码:codepen.io/rachelandre…
除了使用 overflow
建立 BFC
外,其余一些CSS属性还建立 BFC
。正如咱们所看到的,浮动元素建立了 BFC
。你的浮动项将包含它里面的任何东西。
在元素中使用position: absolute
或者 position: fixed
使用 display: inline-block
、 display: table-cell
或 display: table- title
。表单元格和表标题是这些HTML元素的默认设置,所以,若是有一个 table
,每一个单元格都将建立一个 BFC
。
使用 column-span: all
,用于跨多列布局的列。 Flex
和 Grid
的项还建立了相似于 BFC
的东西,只不过它们分别被描述为 Flex格式化上下文(Flex Formatting Context, FFC)
和 网格格式化上下文(Grid Formatting Context, GFC)
。这反映了每一个项参与的布局类型。 块格式化上下文BFC
表示项正在参与块布局,而 Flex格式化上下文
表示项正在参与Flex布局。在实际中,结果是相同的,浮动也能够被包含而且元素的 margin
边界不会坍塌。
使用 overflow
或其余方法建立 BFC
有两个问题。首先,这些方法的反作用是基于它们真正的设计目的。 overflow
方法建立一个 BFC
并包含浮动元素,可是在某些状况下,你会发现你获得了一个不须要的滚动条,或者阴影被剪切了。这是由于设计 overflow
属性的目的是让您告诉浏览器在溢出的状况下应该作什么——致使滚动条或剪切内容。浏览器正在作你让它作的事情!
即便在没有任何不想要的反作用的状况下,使用 overflow
也可能会让其余开发人员感到困惑。为何 overflow
设置为自动或滚动?最初的开发者的意图是什么?他们想要这个组件上的滚动条吗?
另外一个很是有用的建立 BFC
的方法是令其是惰性的,除了建立那个小布局和在其中安全地发生事情的能力以外,不会致使其余行为。该方法不会引发任何意外的问题,而且容许清楚地说明开发人员的意图。CSS工做组认为这可能也很是方便,所以咱们有了 display
属性的一个新值—— flow-root
。
若是您有一个支持 display: flow-root
(如最新的Firefox或Chrome)的浏览器,您能够在下面的代码页中看到全部这些。
CODEPEN代码页面:codepen.io/rachelandre…
display: flow-root
的浏览器支持状况浏览器对这个属性的支持是有限的,但支持还在增长,若是你认为它会很方便,必定要去给它投票。可是,即便你如今不能在代码中使用方便的 flow-root
特性,你如今也了解了什么是 BFC
,以及当你使用 overflow
或其余方法来包裹浮动元素时能够清楚的知道你在作什么。
你已经了解了关于浏览器如何布局web页面的一些很是基本的知识。虽然它们自己看起来可有可无,但正是这些小知识能够加快建立和调试CSS布局所需的时间。