CSS中BFC的理解(css bfc ifc)

1 BFC是什么

Block Formatting Context (块格式化上下文)是 W3C CSS 2.1 规范中的一个概念,在CSS3中被修改为flow root。格式化则表明了在这个环境中,元素处于此环境中应当被初始化,即元素在此环境中应当如何布局等。元素如果创建了BFC,那么BFC决定了如何对其内容进行定位,以及它与其他元素的关系和相互作用。创建了BFC的元素会按照如下的方式对其子元素进行排列:

元素的子元素会一个接一个地放置。垂直方向上他们的起点是一个包含块的顶部,两个相邻的元素之间的垂直距离取决于 margin 特性。在 BFC中相邻的块级元素的垂直边距会折叠(collapse)。

元素的子元素中,每一个子元素左外边与包含块的左边相接触(对于从右到左的格式化,右外边接触右边), 即使存在浮动也是如此(尽管一个子元素的内容区域会由于浮动而压缩),除非这个子元素也创建了一个新的BFC,如它自身也是一个浮动。

如对于如下的HTML页面:

<!DOCTYPE html PUBliC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <style type="text/css">
        body {
            margin: 15px;
            font-family: Arial;
            font-size: 12px;
        }
        .father{
        	background-color:ffff99;
        	border:1px solid 111111;
        	padding:5px;
        	}
        .father div {
            padding: 10px;
            margin: 15px;
            border: 1px dashed 111111;
            background-color: 90baff;
        }
        .father p{
        	border:1px dashed 111111;
        	background-color:ff90ba;
        	}
    </style>
</head>
<body>
<div class="father" style="overflow:hidden;width:300px">
    <div style="float:left;width:100px">abcd</div>
    <div style="float:right;width:50px">abcd</div>
    <p style="">time to go out of the day,big money,fire out ,fire off,go go go go go go go go go go go go go</p>
    <p style="">测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试</p>
</div>
</body>
</html>

class="father"的div为创建了新的BFC的容器,它的两个子元素的起始都是从容器的最左边开始的,尽管第一个div为浮动,且占据了它的部分空间。如红色背景色为p的区域。而第二个子div,由于其的浮动设为向右浮动,因此它也创建了一个BFC

CSS中BFC的理解(css bfc ifc)

2 什么情况下会创建BFC

CSS 规范说明了在下列这些情况下会创建新的 block formatting context:

浮动元素(float: left | right);

绝对定位元素(position: absolute | fixed);

行内块元素(display: inline-block);

表格的单元格(display: table-cells,TD、TH);

表格的标题(display: table-captions,CAPTION);

overflow 特性不为 visible 的元素(除非该值已经传播到viewport?);

表格元素创建的 "匿名框"

注意,"display:table" 本身并不产生 "block formatting contexts"。但是,它可以产生匿名框 6, 其中包含 "display:table-cell" 的框会产生块格式化上下文。 总之,对于 "display:table" 的元素,产生块格式化上下文的是匿名框而不是 "display:table"

注意,是这些元素创建了块格式化上下文,它们本身不是块格式化上下文。

3 BFC的主要特性

BFC的主要用处是清除浮动,以及实现多栏布局

3.1 创建了 BFC 的元素中,子浮动元素也会参与高度的计算,即不会发生高度‘塌陷’,可以利用这个特性来实现清除浮动的功能

<div style="width:300px;">
    <div id="Container" style="background:silver;overflow:hidden;">
        <span id="SPAN1" style="background:gray;">simple text</span>
        <div id="DIV1" style="width:150px; height:50px; background:dimgray;">in flow</div>
        <div id="DIV2" style="float:left; background:gold;">float:left</div>
    </div>
</div>

Container 的高度值为 auto,并且 overflow 的值为hidden;即Container 创建 block formatting context。

SPAN1 是一个行内元素, DIV1 是一个处于普通流中的块元素;

DIV2 是一个浮动的块级元素。

CSS中BFC的理解(css bfc ifc)

而如果去掉Container的overflow:hidden,即恢复其默认值为overflow:visible,它变为普通流,则显示如下:

CSS中BFC的理解(css bfc ifc)

根据 CSS2.1 规范第 10.6.3 部分的高度计算规则,在进行普通流中的块级非替换元素的高度计算时,浮动子元素不参与计算。

3.2 与浮动元素相邻的、创建了BFC的元素,都不能与浮动元素相互覆盖。利用该特行,可以实现多栏布局

In a block formatting context, each boxs left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch)。

<div id="Container" style="border:2px solid gold; width:300px; height:150px; background:url("grid2a.png") repeat;">
    <div id="DIV1" style="background-color:gold; width:100px; height:100px; float:left; filter:alpha(opacity=50); opacity: 0.5;">
        Float Block
    </div>
    <div id="DIV2" style="background-color:green; overflow:hidden;">
        If I had a single flower for every time I think about you, I could walk forever in my garden.
    </div>
</div>

其中,grid2a.png 背景是 100px * 100px 的图片:

CSS中BFC的理解(css bfc ifc)

DIV1 是一个浮动元素,背景是50%的透明

DIV2 的 overflow:hidden;,即创建了BFC

根据 CSS 2.1 9.5 Floats 中的描述,创建了 Block Formatting Context 的元素不能与浮动元素重叠, 所以,DIV2 应该有一部分被 DIV1 覆盖。

CSS中BFC的理解(css bfc ifc)

而如果去掉’overflow:hidden’,则根据 CSS 2.1 9.5 Floats 中的描述,浮动元素会覆盖普通流中的块容器。所以,DIV2 应该有一部分会被 DIV1 覆盖。

CSS中BFC的理解(css bfc ifc)

3.3 创建了BFC的元素不会与它们的子元素发生外边距折叠

<div id="Container" style="width:300px; border:1px solid gold;">
    <div id="DIV1" style="overflow:hidden; background:darkgray;">
        <div id="DIV2" style="margin:30px 0; width:60px;">content</div>
    </div>
</div>

Container 是宽度为300px,含有 border 的块元素,根据标准,它不会与子元素的 margin 发生空白边折叠。

DIV1 的宽度没有设置,所以宽度等于 Container 的宽度。

DIV1 的高度也没有设置,所以其高度取决于其内容的高度。

DIV1 设置了 overflow:hidden,创建了BFC

根据 CSS 2.1 8.3.1 Collapsing margins 第三条,生成BFC的元素不会和其子元素发生空白边折叠。

CSS中BFC的理解(css bfc ifc)

而如果去掉overflow:hidden,则根据 CSS 2.1 8.3.1 Collapsing margins 第一条,两个相邻(兄弟或者父子)的普通流中的块框在垂直位置的空白边会发生折叠现象。显示如下:

CSS中BFC的理解(css bfc ifc)

3.4 IE8-浏览器的特殊处理

在 IE6 IE7 IE8(Q) 中只有hasLayout 特性,而没有BFC的概念。IE6-7使用布局的概念来控制元素的尺寸和定位,那些拥有布局(has layout)的元素负责本身及其子元素的尺寸设置和定位。如果一个元素的 hasLayout 为false,那么它的尺寸和位置由最近拥有布局的祖先元素控制。

IE中的hasLayout和标准的BFC的区别和联系:

3.4.1 区别

在 IE8(S) 之前的版本中,没有规范中提及的 block formatting context 和 Inline formatting context 概念,而是用 hasLayout 来达到相似的目的。

在 IE 中可通过设置 width、height、min-width、min-height、max-width、max-height、 zoom、writing-mode 来触发 hasLayout,而这些特性值的设置不能够使元素创建标准的block formatting context。

在 IE 中很多元素默认就是拥有布局hasLayout的,如 IPUNT, BUTTON, SELECT, TEXTAREA 等,但是这些元素在标准中会形成 Inline formatting context

3.4.2 共同点

两者都是决定了对内容如何定位及大小计算的规则。

两者都决定了与其他元素的相互作用的规则。

table-cell 和 table-caption 既是 hasLayout 的元素,又是可以创建 block formatting context 的元素。

浮动元素,绝对定位元素,inline-block 元素以及除 visible 外任意值的 overflow(IE7) 在 IE 中可以触发 hasLayout,同时在标准中,又可以创建 block formatting context。

3.4.3 解决方案,即各个浏览器的兼容性

如果为了兼容IE8-,必须要么同时启动BFC和hasLayout,要么都不启动:

1. 使元素即生成了 block formatting context,又触发了 hasLayout

对于触发 hasLayout 的元素,如input元素,通过 CSS 设置,使它产生 block formatting context;

生成 block formatting context 但是没有触发 hasLayout 的元素,通过设置 zoom:1,使其触发 hasLayout。

2. 使元素即没有触发 hasLayout,又没有创建 block formatting context。

3.5 BFC 的宽度大于 "容器的剩余空间宽度" 时,在各浏览器之间可能会触发兼容性问题

参考《参考文档2》

4 参考文档

1. How does the CSS Block Formatting Context work?

2. BFC宽度大于容器剩余宽度,导致各浏览器中BFC 显示的位置有差异

3. RM8002: 不能同时在 IE6 IE7 IE8(Q) 中触发 hasLayout 并在其他浏览器中创建 Block Formatting Context 的元素在各浏览器中的表现会有差异

4. KB010: 常规流( Normal flow )

版权声明:网站导航 发表于 2022年8月11日 上午12:34。
转载请注明:CSS中BFC的理解(css bfc ifc) | 网站导航

相关文章