常规流之块级格式化上下文(Block Formating Context)

  在css2.1中,常规流包括块框(block boxes)的块格式化(block formatting),行内框(inline boxes)的行内格式化(inline formatting),块级框(block-level-boxes)或行内级框(inline-level-boxes)的相对定位。常规流中的框属于一个格式化上下文,可能是块或者是行内,但不能同时都是。块级框参与块级格式化上下文,行内级框参与行内级格式化上下文。今天我们先来说说块级格式化上下文,也就是我们常说的BFC。

一.形成块级格式化上下文

  • 绝对定位元素(fixed其实是absolute的一个子集)
  • display为inline-block,table-cell,table-caption,flex,inline-flex(这里有一点要注意的,display-table本身不会形成BFC,但是它会产生匿名框,其中包含的dispaly:table-cell元素会形成BFC)
  • overflow不为visible
  • 根元素
  • float属性不为none

  这里要说明的是这些是形成块格式化上下文,而不是说是参与块级格式化上下文,这两个概念很容易弄混,大家可以仔细体会下。块格式化上下文是一个独立的渲染区域,而且只会有块级框(block-level box)来参与,它规定内部的块级框如何布局,与这个区域的外部毫不相干。

二.块格式化上下文中的特性

    在块格式化上下文中,框会一个接一个的被垂直放置,他们的起点是一个包含块的顶部。

  两个兄弟框之间的垂直距离取决于margin属性。在BFC中相邻的块级元素的垂直边距会折叠。

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

  计算BFC高度的时候,浮动子元素也会参与计算。

  BFC的区域不会与float box重叠。

三.块级格式化上下文的作用

  我们之所以要了解一些东西,无非是需要有现实的意义和作用,不然谁管它(笑)。

  那么BFC有什么作用呢,那就得从BFC的特性说起了。下面,我们会根据一些具体的例子来一个个说明。

  1.清除浮动

  我们上面说了,计算BFC高度的时候,浮动子元素也会参与计算,而浮动子元素造成的塌陷想必大家也都非常了解,那么如果父元素形成了BFC,是不是就可以包含浮动子元素了呢?直接看例子(为了直观我就不贴可运行代码了):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>BFC清除浮动</title>
    <style>
        *{margin:0; padding: 0;}
        .wrap-wrap{ height: 150px;}
        .wrap{ width: 300px; background-color :#fcc; color: #fff;}
        .son1,.son2{ float: left; width: 100px; height: 100px; background-color:red;}
        .son2{ background-color:blue; }
        .wrap-bfc{ overflow: hidden;}
    </style>
</head>
<body>
<div class="wrap-wrap">
    <div class="wrap">
        wrap
        <div class="son1">son1</div>
        <div class="son2">son2</div>
    </div>
</div>
<div class="wrap wrap-bfc">
        wrap
    <div class="son1">son1</div>
    <div class="son2">son2</div>
</div>
</body>
</html>

  运行结果如下:

  我们通过一个overflow:hidden使下面的wrap形成了BFC,它高度的计算中浮动子元素也会参与,自然就包含了浮动元素,从而达到了清除浮动的目的。当然,不止overflow:hidden可以清除浮动,各位可以自行试试其他属性。

  2.防止垂直margin重叠

  在同一BFC中相邻的块级元素的垂直边距会折叠。那么如果这两个元素不在一个BFC中了会发生什么呢,继续看例子:

  

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>防止边距折叠</title>
    <style>
        *{margin:0; padding: 0;}
        .wrap,.wrap1,.wrap2{ width: 200px; height: 100px; background-color :#fcc; color: #fff;}
        .son1,.son2{ width: 50px; height: 20px; margin: 10px; background-color:red;}
        .son2{ background-color:blue; }
        .wrap1{ overflow: hidden; background-color:lime; }
        .wrap2{ overflow: hidden; background-color:lime; }
        .new-wrap{ overflow: hidden;}
    </style>

</head>
<body>
    <div class="wrap">
        <div class="son1">son1</div>
        <div class="son2">son2</div>
        wrap
    </div>
    <p>——————分割符————</p>
    <div class="wrap1">
        <div class="son1">son1</div>
        <div class="son2">son2</div>
        wrap1
    </div>
    <p>——————分割符————</p>
    <div class="wrap2">
        <div class="son1">son1</div>
        <div class="new-wrap">
            <div class="son2">son2</div>
        </div>
        wrap2
    </div>
</body>
</html>

  运行结果如下:

  这里有两点要说。

  1).wrap1与son1的margin折叠

  我们先看wrap,son1是有个margin-top,但是图中给我们的感觉是没有,反而是它的父元素wrap有一个margin-top。为什么呢,这个就要看magrin折叠的说明了,这个也是标准中的内容:

  In this specification, the expression collapsing margins means that adjoining margins (no non-empty content, padding or border areas or clearance separate them) of two or more boxes (which may be next to one another or nested) combine to form a single margin. 所有毗邻的两个或更多盒元素的margin将会合并为一个margin共享之。毗邻的定义为:同级或者嵌套的盒元素,并且它们之间没有非空内容、Padding或Border分隔。 

  可知嵌套的盒元素也会Collapsing Margins,就不难知道为什么会这样了。而在wrap1中,同样的结构,也没有非空内容、Padding或Border分隔,为什么又不折叠了呢?这里就要知道什么叫毗邻了:

 Two margins are adjoining if and only if:

  • both belong to in-flow block-level boxes that participate in the same block formatting context
  • no line boxes, no clearance, no padding and no border separate them (Note that certain zero-height line boxes (see 9.4.2) are ignored for this purpose.)
  • both belong to vertically-adjacent box edges, i.e. form one of the following pairs:
    • top margin of a box and top margin of its first in-flow child
    • bottom margin of box and top margin of its next in-flow following sibling
    • bottom margin of a last in-flow child and bottom margin of its parent if the parent has ‘auto‘ computed height
    • top and bottom margins of a box that does not establish a new block formatting context and that has zero computed ‘min-height‘, zero or ‘auto‘ computed ‘height‘, and no in-flow children

  我就不一个个翻译了,就看第一条,这些margin都处于普通流中,并在同一个BFC中。我自己的理解是下面这样的,不一定正确,如果知道的同学还请指正:

  wrap1的overflow:hidden属性形成了一个新的BFC,son1就参与了这个新的BFC。而wrap1本身是在根元素形成的BFC种,由此两个就不在同一个BFC中了,也就不是毗邻的了,自然margin不会折叠。

  2).son1与son2的边距折叠。

  根据上面一点说的,son1和son2是满足margin折叠的条件的,那么如果我们给son2包裹个new-wrap,并让它形成BFC,自然就没有边距折叠了。

  3.自适应两栏布局。

  这个直接上代码吧,根据例子来说,比较直观

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>自适应布局</title>
    <style>
        *{margin:0; padding: 0;}
        body {
            position: relative;
            color: #fff;
        }
        .aside {
            width: 100px;
            height: 150px;
            float: left;
            background: #f66;
        }

        .main {
            height: 200px;
            background: #fcc;
        }
    </style>
</head>
<body>
    <div class="aside">float aside</div>
    <div class="main">main</div>
</body>
</html>

  运行结果:

  

  这里首先要说的是main的位置问题。在BFC中,每一个元素的左外边(left margin边界)与包含块的左边相接触(对于从右到左的格式化,右边距接触包含块右边),这里虽然有float的aside,但是main的左边依然与包含块的左边接触。

  而如果我们对main设置这样的样式:main:overflow:hidden,结果如下:

 

  当触发main生成BFC后,这个新的BFC不会与浮动的aside重叠。因此会根据包含块的宽度,和aside的宽度,自动变窄。为什么呢:

  BFC的区域不会与float box重叠。

  

四.总结

  今天我们主要分析了什么是BFC、怎么形成BFC以及BFC的作用。其中有一些我总结个人的理解,希望对大家有帮助。另外,在css3的草案中,对这个概念做了改动,将Block formatting context 叫做 flow root,触发方式也发生了变化:The value of ‘position‘ is neither "static" nor "relative".fixed作为absolute的一个子类也会形成flow root,有兴趣的同学可以自己去了解下。好了,就这么多了,我写东西都是准备好了然后一口气,后面再一点点修改,初成文难免会有错漏,还请大家多多指正。下一章会分析下行内级格式化上下文的相关。

参考:

  1.KB010: 常规流( Normal flow )

  2.w3c盒模型

  3.w3c常规流

  4.前端精选文摘:BFC 神奇背后的原理

  

时间: 2024-10-13 05:16:05

常规流之块级格式化上下文(Block Formating Context)的相关文章

块级格式化上下文(block formatting context)、浮动和绝对定位的工作原理详解

CSS的可视化格式模型中具有一个非常重要地位的概念——定位方案.定位方案用以控制元素的布局,在CSS2.1中,有三种定位方案——普通流.浮动和绝对定位: 普通流:元素按照先后位置自上而下布局,inline元素水平排列,直到行被占满后换行,block元素则被渲染为完整的一行,除非指定,所有元素默认为普通流定位. 浮动:浮动布局中,元素首先按照普通流位置出现,然后根据浮动方向尽可能向左或右偏移,效果与文本环绕相似. 绝对定位:元素会脱离普通流,因此绝对定位元素不会对其兄弟元素产生影响(与float不

块级格式化上下文(block formatting context)

在CSS2.1中,有三种定位方案--普通流.浮动和绝对定位: 普通流:元素按照先后位置自上而下布局,inline元素水平排列,直到行被占满后换行,block元素则被渲染为完整的一行,除非指定,所有元素默认为普通流定位. 浮动:浮动布局中,元素首先按照普通流位置出现,然后根据浮动方向尽可能向左或右偏移,效果与文本环绕相似. 绝对定位:元素会脱离普通流,因此绝对定位元素不会对其兄弟元素产生影响(与float不同),元素的具体位置由坐标位置决定. BFC是属于普通流,因此它对兄弟元素也不产生影响. 一

关于块级格式化上下文(Block formatting context)

不是谁都像你一样只向着前方就能活下去了,你就抛弃那些没用的同伴前行就好了,你注定是要成为海贼王的男人吧,而我就算没有远大的目标也可以.——<one piece>     Block formatting context(以下简写为BFC)又称做块级格式化上下文,源自CSS2.1 规范中的Visual formatting model,Visual fomatting model定义了视觉媒体该怎样处理文档内容,BFC属于Normal flow(正常流),它与其他正常流元素并没有本质的区别,BF

块级格式化上下文

初识块级格式化上下文(Block Formatting Contexts) 前言 html文档中元素的定位有3种方式(普通流.绝对定位.浮动),除普通流以外,浮动与绝对定位都会导致元素脱离普通流,按照各自的方式进行定位. 带有BFC属性的容器属于普通流的一种. 块级格式化上下文 (BFC) 块格式化上下文是页面 CSS 视觉渲染的一部分.它是用于决定块盒子的布局及浮动相互影响范围的一个区域. BFC是元素在拥有某些特定属性才显示的一种属性,有BFC特性的元素和其他普通流中的元素在样式上没有区别.

Block Formatting Contexts (块级格式化上下文) 详解

     最近在学习BootStrap框架,发现里面清除浮动的类 .clearfix 跟平时自己用的不太一样.它的样式是这样的: .clearfix:before { content: " "; display: table; } .clearfix:after { content: " "; display: table; clear: both; } 用:befor和:after伪元素清除浮动是我熟悉的,不过一般我使用display:block而非display

块级格式化上下文(Block Formatting Context)

前言 在 CSS 2.1 中,有三种定位方案——普通流 (Normal Flow) .浮动 (Floats) 和绝对定位 (Absolute Positioning) ,下面分别对这三种布局简略说明一下. 普通流(Normal Flow) 在普通流中,元素按照其在 HTML 中的先后位置至上而下布局,在这个过程中,行内元素水平排列,直到当行被占满然后换行,块级元素则会被渲染为完整的一个新行, 除非另外指定,否则所有元素默认都是普通流定位,也可以说,普通流中元素的位置由该元素在 HTML 文档中的

详说 Block Formatting Contexts (块级格式化上下文)

在上文<详说清除浮动>中,Kayo 较为详细地介绍了 BFC ,也就是本文的主角 Block Formatting Contexts (块级格式化上下文),本文会基于上文关于 BFC 的部分进行拓展,进一步说明 BFC 的特性. 但在进一步说明 BFC 特性之前,Kayo 首先要介绍另一个在 CSS 的可视化格式模型 (Visual Formatting Model) 中具有非常重要地位的概念——定位方案.定位方案是控制元素的布局,在 CSS 2.1 中,有三种定位方案——普通流 (Norma

块级格式化上下文( Block formatting contexts)

那么如何触发BFC呢? float 除了none以外的值 overflow 除了visible 以外的值(hidden,auto,scroll ) display (table-cell,table-caption,inline-block) position(absolute,fixed) fieldset元素 BFC的特性: 1)块级格式化上下文会阻止外边距叠加 当两个相邻的块框在同一个块级格式化上下文中时,它们之间垂直方向的外边距会发生叠加.换句话说,如果这两个相邻的块框不属于同一个块级格

Block formatting contexts (块级格式化上下文)简称 BFC 的特性

如何触发BFC呢? float 除了none以外的值 overflow 除了visible 以外的值(hidden,auto,scroll ) display (table-cell,table-caption,inline-block) position(absolute,fixed) fieldset元素 需要注意的是,display:table 本身并不会创建BFC,但是它会产生匿名框(anonymous boxes),而匿名框中的display:table-cell可以创建新的BFC,换