在上文《详说清除浮动》中,Kayo 较为详细地介绍了 BFC ,也就是本文的主角 Block Formatting Contexts (块级格式化上下文),本文会基于上文关于 BFC 的部分进行拓展,进一步说明 BFC 的特性。

但在进一步说明 BFC 特性之前,Kayo 首先要介绍另一个在 CSS 的可视化格式模型 (Visual Formatting Model) 中具有非常重要地位的概念——定位方案。定位方案是控制元素的布局,在 CSS 2.1 中,有三种定位方案——普通流 (Normal Flow) 、浮动 (Floats) 和绝对定位 (Absolute Positioning) ,下面分别对这三种布局简略说明一下。

普通流(Normal Flow)

在普通流中,元素按照其在 HTML 中的先后位置至上而下布局,在这个过程中,行内元素水平排列,直到当行被占满然后换行,块级元素则会被渲染为完整的一个新行, 除非另外指定,否则所有元素默认都是普通流定位,也可以说,普通流中元素的位置由该元素在 HTML 文档中的位置决定。

浮动 (Floats)

在浮动布局中,元素首先按照普通流的位置出现,然后根据浮动的方向尽可能的向左边或右边偏移,其效果与印刷排版中的文本环绕相似。

绝对定位 (Absolute Positioning)

在绝对定位布局中,元素会整体脱离普通流,因此绝对定位元素不会对其兄弟元素造成影响(如果看了上文的童鞋,会发现这点与浮动元素会影响兄弟元素是不同的),而元素具体的位置由绝对定位的坐标决定。

BFC 正是属于普通流的,因此它对兄弟元素也不会造成什么影响。

一. BFC 是什么?

有了上面的基础后,可以正式介绍 BFC 了。从样式上看,具有 BFC 的元素与普通的容器没有什么区别,但是从功能上,具有 BFC 的元素可以看作是隔离了的独立容器,容器里面的元素不会在布局上影响到外面的元素,并且 BFC 具有普通容器没有的一些特性,例如可以包含浮动元素,上文中的第二类清除浮动的方法(如 overflow 方法)就是触发了浮动元素的父元素的 BFC ,使到它可以包含浮动元素,从而防止出现高度塌陷的问题。

简单来说,BFC 就是一种属性,这种属性会影响着元素的定位以及与其兄弟元素之间的相互作用。

二.如何触发 BFC

上面介绍了 BFC 的定义,那么如何触发 BFC 呢?

满足下面任一条件的元素,会触发为 BFC :

  • 浮动元素,float 除 none 以外的值
  • 绝对定位元素,position(absolute,fixed)
  • display 为以下其中之一的值 inline-blocks,table-cells,table-captions
  • overflow 除了 visible 以外的值(hidden,auto,scroll)

但是,"display:table" 本身并不产生 BFC,而是由它产生匿名框,匿名框中包含 "display:table-cell" 的框会产 BFC。 总之,对于 "display:table" 的元素,产生 BFC 的是匿名框而不是 "display:table"。

在 CSS3 中,BFC 叫做 Flow Root,并增加了一些触发条件:

  • display 的 table-caption 值
  • position 的 fixed 值,其实 fixed 是 absolute 的一个子类,因此在 CSS2.1 中使用这个值也会触发 BFC ,只是在 CSS3 中更加明确了这一点。

值得注意的是,在前面 Kayo 已经说明过了,BFC 并不是元素,而是某些元素带有的一些属性,因此,是上面这些元素产生了 BFC ,而它们本身并不是 BFC ,这个概念需要区分清楚。

三. BFC 的特性

从整体上看,BFC 是隔离了的容器,这个具体可以表现为三个特性:

1. BFC 会阻止外边距折叠

两个相连的 div 在垂直上的外边距会发生叠加,有些书籍会把这个情况列作 bug ,这里 Kayo 并不同意,这种折叠虽然会给不熟悉 CSS 布局的开发者带来一些不便,但实际上它具有完整且具体的折叠规则,并且在主流浏览器中都存在,因此 Kayo 更认为这应该是 CSS 的特性。当然,在实际开发中,或许我们有时会不需要这种折叠,这时可以利用 BFC 的其中一个特性——阻止外边距叠加。

在举例说明 BFC 如何阻止外边距折叠之前,首先说明一下外边距折叠的规则:仅当两个块级元素相邻并且在同一个块级格式化上下文时,它们垂直方向之间的外边距才会叠加。也就是说,即便两个块级元素相邻,但当它们不在同一个块级格式化上下文时它们的边距也不会折叠。因此,阻止外边距折叠只需产生新的 BFC 。

效果如图:

也可以看 Demo 。

如上图的例子,三个 div 各包含一个 p 元素,三个 div 及其包含的 p 元素都有顶部和底部的外边距,但只有第三个 div 的边距没有与它的子元素 p 的外边距折叠。这是因为第三个 div 创建了新的 BFC ,由此可见:创建了 BFC 的元素,不和它的子元素发生外边距折叠。

2. BFC 可以包含浮动的元素

这也正是使用 overflow: hidden 与 overflow: auto 方法闭合浮动的原理,使用 overflow: hidden 或 overflow: auto 触发浮动元素的父元素的 BFC 特性,从而可以包含浮动元素,闭合浮动。

W3C 的原文是“'Auto' heights for block formatting context roots”,也就是 BFC 会根据子元素的情况自动适应高度,即使其子元素中包括浮动元素。

效果如图:

也可以看 Demo 。

上面的例子中,有两个 div ,它们各包含一个设置了浮动的 p 元素,但第一个 div 出现了“高度塌陷”,这是因为内部的浮动元素脱离了普通流,因此该 div 相当于一个空标签,没有高度和宽度,即高度为 0 ,上下边框也重叠在一起。而第二个 div 使用 overflow: hidden 触发了 BFC ,可以包含浮动元素,因此能正确表现出高度,其边框位置也正常了。

3. BFC 可以阻止元素被浮动元素覆盖

如上文所说,浮动元素的块级兄弟元素会无视浮动元素的位置,尽量占满一整行,这样就会被浮动元素覆盖,为该兄弟元素触发 BFC 后可以阻止这种情况的发生。

效果如图:

也可以看 Demo 。

如上图的例子,蓝色背景的 div 使用 overflow: hidden 触发了 BFC ,它并不会被它的兄弟浮动元素覆盖,而是处于它的旁边。值得注意的是,以上的情况仅仅是元素宽度之和没有超出父元素宽度的情况,假设浮动元素宽度和它的非浮动兄弟元素宽度都没有超过父元素宽度,但两个元素的宽度加起来超出了父元素宽度的时候,非浮动元素会下降到下一行,即处于浮动元素下方,效果如下图:

也可以看 Demo 。

四. BFC 与 hasLayout

细心的童鞋会发现,在上面的例子中,除了使用 overflow: hidden 触发 BFC 外,还使用了一个 *zomm: 1 的属性,这是 IEhack ,因为 IE6-7 并不支持 W3C 的 BFC ,而是使用私有属性 hasLayout 。从表现上来说,hasLayout 跟 BFC 很相似,只是 hasLayout 自身存在很多问题,导致了 IE6-7 中一系列的 bug 。触发 hasLayout 的条件与触发 BFC 有些相似,具体情况 Kayo 会另写文章介绍。这里 Kayo 推荐为元素设置 IE 特有的 CSS 属性 zoom: 1 触发 hasLayout ,zoom 用于设置或检索元素的缩放比例,值为“1”即使用元素的实际尺寸,使用 zoom: 1 既可以触发 hasLayout 又不会对元素造成其他影响,相对来说会更为方便。

这时我们需要注意一个问题:既然 hasLayout 有着跟 BFC 相似的功能,那么在实际开发中,就要为需要触发 BFC 的元素同时触发 hasLayout ,这样 BFC 和 hasLayout 具有的一些特殊性质可以在现代浏览器和 IE 中同时产生,避免一个元素在不同浏览器间的表现因为 BFC 或 hasLayout 出现差异。事实上,在实际开发中很多莫名其妙的问题其实都是因此而产生的。当然同样地,如果一个元素没有触发 BFC ,也要尽量保证它没有触发 hasLayout 。

本文由 Kayo Lee 发表,本文链接:http://kayosite.com/block-formatting-contexts-in-detail.html

 

详说 Block Formatting Contexts (块级格式化上下文)的更多相关文章

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

    定位方案是控制元素的布局,在 CSS 2.1 中,有三种定位方案——普通流 (Normal Flow) .浮动 (Floats) 和绝对定位 (Absolute Positioning) ,下面分别对 ...

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

         最近在学习BootStrap框架,发现里面清除浮动的类 .clearfix 跟平时自己用的不太一样.它的样式是这样的: .clearfix:before { content: " ...

  3. Block Formatting Contexts (块级格式化上下文) 使用参考

    转自:http://kayosite.com/block-formatting-contexts-in-detail.html 在上文<详说清除浮动>中,Kayo 较为详细地介绍了 BFC ...

  4. BFC --- Block Formatting Context --- 块级格式化上下文

    虽然知道块级格式化上下文是什么东西,但要我把这个东西给说清楚,还真的不是一件容易的事儿,所以这篇文章我就要说说清楚到底什么使传说中的BFC,即块级格式化上下文. 一.BFC的通俗理解 通俗的理解 -- ...

  5. Block formatting context(块级格式化上下文)

    今天看到豆瓣面试官的一篇文章,讲到关于CSS中的一个知识点:Block formatting context  ,感觉这个确实挺有用,同时我也挺赞同作者的一些观点的,这里就不展开谈我的感受了, 此文只 ...

  6. BFC(Box,Formatting,Context) —— 块级格式化上下文

    Box:CSS布局的基本单位 Formatting context是页面中的一块渲染区域,最常见的是BFC和IFC,CSS3增加了GFC和FFC BFC定义:块级格式化上下文,它是一个独立的渲染区域, ...

  7. css中margin重叠和一些相关概念(包含块containing block、块级格式化上下文BFC、不可替换元素 non-replaced element、匿名盒Anonymous boxes )

    平时在工作中,总是有一些元素之间的边距与设定的边距好像不一致的情况,一直没明白为什么,最近仔细研究了一下,发现里面有学问:垂直元素之间的margin有有互相重叠的情况:新建一个BFC后,会阻止元素与外 ...

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

    CSS的可视化格式模型中具有一个非常重要地位的概念——定位方案.定位方案用以控制元素的布局,在CSS2.1中,有三种定位方案——普通流.浮动和绝对定位: 普通流:元素按照先后位置自上而下布局,inli ...

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

    那么如何触发BFC呢? float 除了none以外的值 overflow 除了visible 以外的值(hidden,auto,scroll ) display (table-cell,table- ...

随机推荐

  1. 「LOJ 556 Antileaf's Round」咱们去烧菜吧

    「LOJ 556 Antileaf's Round」咱们去烧菜吧 最近在看 jcvb 的生成函数课件,顺便切一切上面讲到的内容的板子题,这个题和课件上举例的背包计数基本一样. 解题思路 首先列出答案的 ...

  2. 8.9 正睿暑期集训营 Day6

    目录 2018.8.9 正睿暑期集训营 Day6 A 萌新拆塔(状压DP) B 奇迹暖暖 C 风花雪月(DP) 考试代码 A B C 2018.8.9 正睿暑期集训营 Day6 时间:2.5h(实际) ...

  3. Educational Codeforces Round 14 A. Fashion in Berland 水题

    A. Fashion in Berland 题目连接: http://www.codeforces.com/contest/691/problem/A Description According to ...

  4. Sed&awk笔记之awk篇(转)

    Awk是什么 Awk.sed与grep,俗称Linux下的三剑客,它们之间有很多相似点,但是同样也各有各的特色,相似的地方是它们都可以匹配文本,其中sed和awk还可以用于文本编辑,而grep则不具备 ...

  5. STM32F4 Timer simplified block diagram

    Timers TIM1 and TIM8 use 16-bit counters and are the most complex timers of all timers included in t ...

  6. 使用jqprint插件完成页面打印

    使用jqprint插件完成页面打印 jqprint是一个基于jQuery编写的页面打印的一个小插件,但是不得不承认这个插件确实很厉害,最近的项目中帮了我的大忙,在Web打印的方面,前端的打印基本是靠w ...

  7. WIN8系统中 任务管理器 性能栏 显示CPU利用率(已暂停)怎么回事?

    解决办法: 点上方的 查看--更新速度--普通

  8. 统计代码执行时间,使用Stopwatch和UserProcessorTime的区别

    当我们需要统计一段代码的执行时间,首先想到的可能是Stopwatch类.在这里,先暂不使用Stopwatch,自定义一个统计代码执行时间的类,大致需要考虑到: 1.确保统计的是当前进程.当前线程中代码 ...

  9. 关于Maven项目build时出现No compiler is provided in this environment的处理(转)

    本文转自https://blog.csdn.net/lslk9898/article/details/73836745 近日有同事遇到在编译Maven项目时出现[ERROR] No compiler ...

  10. 咏南中间件新增MORMOT移动端演示

    咏南中间件新增MORMOT移动端演示 基于FMX,支持安卓.IOS移动端. 1)使用INDY 的HTTP控件进行查询: procedure TForm1.查询1Click(Sender: TObjec ...