[前端日记]0.x.5/CSS不可不知:BFC

碎碎念


上一篇讨论浮动与清除浮动的博客中,最后提到了BFC(Block Formatting Contexts)的概念。


我建议每个学前端的人都要把BFC理解透彻,这样在解决外边距堆叠,高度塌陷及各种定位、布局带来的负面影响时,都能了解原理,选择恰当的解决办法。


废话不多说了,开始:P

官方文档对BFC的解释


首先,我们来看看官方文档是如何描述BFC的,我把这段定义拆成三小段,分段描述:

Floats, absolutely positioned elements, block containers (such as inline-blocks, table-cells, and table-captions) that are not block boxes, and block boxes with 'overflow' other than 'visible' (except when that value has been propagated to the viewport) establish new block formatting contexts for their contents.

  • 浮动,绝对定位,不是块级盒的块级包含块(例如inline-block,table-cells和table-caption),及overflow值不为visible的块级盒子为他们的内容新的块级格式化上下文(BFC)


In a block formatting context, boxes are laid out one after the other, vertically, beginning at the top of a containing block. The vertical distance between two sibling boxes is determined by the 'margin' properties. Vertical margins between adjacent block-level boxes in a block formatting context collapse.

  • 在一个块级格式化上下文中,盒子是从包含块顶部开始,一个接一个的垂直排列。
  • 两个后代盒子的垂直距离由margin即外边距属性决定。
  • 在一个块级格式化上下文中,两个相邻的块级盒子外边距会折叠;


In a block formatting context, each box's left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch). This is true even in the presence of floats (although a box's line boxes may shrink due to the floats), unless the box establishes a new block formatting context (in which case the box itself may become narrower due to the floats).

  • 在一个块级格式化上下文中,每个盒子的外边距和其包含块的左边沿相接触(对于从右向左的格式则相反);
  • 即使在有浮动元素的存在,情况下也是如此(一个盒子的行盒会因为浮动而收缩),除非这个盒子建立了一个新的BFC(在某些情况下,这个盒子自身会变窄)

BFC的理解


  • BFC就是对B(Block)的FC(Formatting Contexts),简单说就是块级元素的排列规则,同样的还有IFC,即对行内元素的排列规则。
  • Formatting Contexts,是W3C CSS2.1引入的概念,可以理解为页面中的一块渲染区域,并且与外界相隔离,有一套自己的规则,它决定了在这块区域中其子元素ru和定位吗,排列以及和其他元素的关系和相互作用。
  • CSS2.1中增加了BFC和IFC,CSS3中还增加了GFC和FFC。
  • Box是CSS布局的基本单位,也就是说,一个页面实际上是由很多Box组合而成的。对Box声明不同的display类型,则生成不同类型的Box。不同类型的Box会参与不同的Formatting Contexts(一个决定如何渲染文档额的容器),因此Box内的元素会以不同的方式渲染。

BFC的特性


一个元素,声明了某种规则(后面会讲触发规则),触发了BFC后,便拥有了BFC特性,那什么是BFC特性呢?特性就是前一段所说的,其为拥有一套独立的渲染规则的区域,并且这块区域不受外界的影响,是相对隔离的区域(也有的地方说容器)。区域中的子元素不会在布局上影响外面的元素,反之亦然。同时,BFC仍然属于文档中的普通流。

  1. 内部的box会在垂直方向上一个接一个的排列;
  2. Box垂直方向上的距离由外边距决定。当两个相邻的容器在同一个BFC中时,他们的垂直方向会发生外边距叠加,换句话说,只要把两个元素分隔在不同的BFC,便可以消除影响,从而解决外边距合并问题;;
  3. 每个元素的左外边距与包含块的左边界相接触(从左到右),即使浮动元素也是如此。(这说明BFC中的子元素不会超出它的包含块,而position为absolute的元素可以超出它的包含块边界);
  4. BFC的区域不会与float box所占的区域重叠;
  5. 计算BFC的高度时,浮动子元素也参与计算;(顺带达到了撑开父容器,清除浮动的目的)

如何触发BFC


只要父容器上声明以下任一属性即可触发 BFC:

  • float 除了none以外的值
  • overflow除了visible以外的值(hidden,auto,scroll )
  • display (table-cell,table-caption,inline-block,flex,inline-flex)
  • position(absolute,fixed)
  • fieldset元素(实验性质)
  • 根元素

以上这些规则,均可以触发BFC,具体的选用要取决于场景,不同的属性会带来不同的作用效果;

BFC的应用


  • 解决外边距叠加,方法:使父容器添加触发BFC的元素;
  • 清除浮动:方法:利用计算BFC高度时,浮动元素也会参与计算的原理,所以为了闭合浮动,我们要对父容器触发BFC;
  • 用于布局:利用BFC不会与float box重叠的原理及元素的左/右外边距会触碰到包含块的边沿原理,创建两栏/三栏布局(左右浮动且定宽,中间创建BFC);

父容器使用overfolow: auto | hidden撑开高度的原理


初次看到overflow:hidden可以解决外边距叠加,清除浮动时,我是很困惑其原理的。直到后面,我尝试理解了BFC,知道其会触发BFC特性,生成一个新的渲染区域,有自己的规则,与外界隔离,也就是不受其他BFC影响了。

但回过头想,我们看下MDN对overflow属的描述:

The overflow CSS property is shorthand for the overflow-x and overflow-y properties, and specifies what to do when content is too large to fit in its block formatting context.

也就是说,overflow属性是用来处理当内容过于长以至于溢出块级容器时,CSS对文本的处理方式;overflow: hidden则是溢出的内容会被裁剪,且不可见。

可以这样理解,overflow:hidden是为了触发包含块计算内容高度,不计算高度overflow怎么裁剪多余部分并隐藏呢?

那怎么计算高度呢?声明了overflow:hidden后需要根据内容的高度来裁剪,浮动元素脱离了文档流,如果未申明高度或高度为auto,那么overflow的高度计算就无从算起,所以要将浮动元素的高度也计算在内,overflow才会起作用,由此,顺带达成了清除浮动的目标;

总结

很多人第一次接触BFC时经常有一个疑问,BFC概念太多了,资料越多往往更难理解。其实,对于BFC我们只需要知道使用一定的CSS声明可以触发BFC,浏览器对生成的BFC有一系列的渲染规则,利用这些渲染规则我们可以达到一定的布局效果,为了达到特定的布局效果我们让元素生成BFC。

我们要记住BFC是页面元素里一个独立存在作用块,它不影响它外面的布局,外面的元素也不会影响到BFC里面的布局,有时候对于页面一些异常效果我们往BFC的思路想想可能会得到解决。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,176评论 5 469
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,190评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,232评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,953评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,879评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,177评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,626评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,295评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,436评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,365评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,414评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,096评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,685评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,771评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,987评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,438评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,032评论 2 341

推荐阅读更多精彩内容

  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,722评论 1 92
  • 1.浮动元素有什么特征?对父容器、其他浮动元素、普通元素、文字分别有什么影响? 何谓浮动元素?有什么特征?所谓浮动...
    草鞋弟阅读 807评论 0 1
  • 先前在学习CSS float时,有同学提到了BFC这个词,作为求知好问的好学生,哪里不懂查哪里,那么今天就来研究一...
    这名字真不对阅读 6,530评论 3 19
  • relative:生成相对定位的元素,通过top,bottom,left,right的位置相对于其正常位置进行定位...
    zx9426阅读 927评论 0 2
  • 1.解决margin叠加问题 三P每个p之间的距离为50px,发生了外边距叠加。 要解决这个叠加问题即让每个P之间...
    岁月帮凶ds阅读 497评论 1 0