细说CSS中的BFC

做者:滴滴公共前端团队 - 邱莲css

BFC是什么?

BFC(Block Formatting Context)直译为“块级格式化范围”。html

是 W3C CSS 2.1 规范中的一个概念,它决定了元素如何对其内容进行定位,以及与其余元素的关系和相互做用。当涉及到可视化布局的时候,Block Formatting Context提供了一个环境,HTML元素在这个环境中按照必定规则进行布局。一个环境中的元素不会影响到其它环境中的布局。前端

好比浮动元素会造成 BFC,浮动元素内部子元素的主要受该浮动元素影响,两个浮动元素之间是互不影响的。这里有点相似一个 BFC 就是一个独立的行政单位的意思。git

也能够说 BFC 就是一个做用范围。能够把它理解成是一个独立的容器,而且这个容器的里box的布局,与这个容器外的绝不相干。github

BFC 的特征:

  • 内部的Box会在垂直方向,一个接一个地放置。api

  • Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠浏览器

  • 每一个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,不然相反)。即便存在浮动也是如此。微信

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

  • BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。flex

  • 计算BFC的高度时,浮动元素也参与计算

BFC 的应用场景有哪些?如何触发 BFC?

知足下列条件中至少一项,便可触发 BFC:

  1. float 的值不为none。

  2. position 的值不为static或者relative。

  3. display的值为 table-cell, table-caption, inline-block, flex, 或者 inline-flex中的其中一个。

  4. overflow的值不为visible。

BFC 的应用场景:

1.解决 margin 叠加问题:

<div class="first-block"></div>
<div class="second-block">
    <h2>DDFE</h2>
</div>复制代码
.first-block {
    background: #F44336;
    width: 200px;
    height: 200px;
}
.second-block {
    background: #00BCD4;
    width: 200px;
    height: 200px;
}复制代码

很简单是吧,浏览器中的效果是这样的:

为何 first-block 和 second-block 之间会有这么宽的间距?

缘由是:外边距折叠,这个间距是 h2 的上外边距引发的

CSS 里面关于折叠的条件:

两个块元素要产生折叠现象,必须知足一个必备条件:这两个元素的 margin 必须是 相邻 的;那么若是定义相邻呢,w3c 规范,两个 margin 是邻接的必须知足如下条件:

  • 必须是处于常规文档流(非float和绝对定位)的块级盒子,而且处于同一个 BFC 当中。

  • 没有inline盒子,没有空隙,没有 padding 和 border 将他们分隔开。

  • 都属于垂直方向上相邻的外边距,能够是下面任意一种状况:

那么咱们就能够经过给元素叫边框或者边距来解决啦,我是否是狠聪明呢?

解决办法 1:

折叠问题解决了,可是因为有1px的边框,second-block 看起来会比 first-block 宽一点,不要紧,添加 box-sizing: border-box 属性能够解决这个问题:再加一句:box-sizing:border-box ;

解决办法 2:

经过把 overflow 把 second-block 元素造成一个 BFC,完美解决!

2.用于布局

杯布局和双飞翼布局,他们的都要求三列布局,中间宽度自适应,两边定宽,这样作的优点是重要的东西放在文档流前面能够优先渲染。
样子,就长这样:


老规矩先贴上代码:
html部分:

css部分:

  1. html代码中,middle部分首先要放在container的最前部分,而后是left,right 。
  2. 将三者都设置 float:left, position:relative
  3. middle设置 width:100% 占满一行 。
  4. 此时middle占满一行,因此要把left拉到middle所在行的最左边,使用 margin-left:-100%
  5. 这时left拉回到middle所在行的最左边,但会覆盖middle内容的左端,要把middle内容拉出来,因此在外围container加上 padding:0 200px
  6. middle内容拉出来了,但left也跟着出来了,因此要还原,就对left使用相对定位 left:-200px
  7. 同理,right要拉到middle所在行的最右边,使用 margin-left:-200pxright:-200px

其实除了圣杯布局还有一个双飞翼布局,双飞翼布局是对圣杯布局的一种改良,多一个div就能够不用相对布局了,只用到了浮动和负边距。

DOM结构:container内层增长了一个div

样式:去掉了左右栏的相对定位,去掉包裹层padding,以中间栏新增div的margin代替。

是否是很简单?

3.用于清除浮动,计算BFC高度

举个例子:

咱们想象中应该是这样的:

但实际是倒是这样的:

div 标签没有包住 ul 标签,缘由很简单:container 下的子元素浮动了,所以div的高度就塌陷了。
要解决塌陷,就得清除浮动。

清除浮动就两种方式:

1)利用 clear 属性清除浮动。

2)使父容器造成 BFC

给父元素 .container 加一句 overflow:hidden 触发 bfc。


欢迎关注DDFE
GITHUB:github.com/DDFE
微信公众号:微信搜索公众号“DDFE”或扫描下面的二维码

相关文章
相关标签/搜索