BFC可以解决哪些问题

1,083 阅读3分钟

什么是BFC

BFC(Block formatting context)直译为"块级格式化上下文"。它是一个独立的渲染区域,只有块级元素参与, 它规定了内部的块级元素如何布局,并且与这个区域外部毫不相干。外部元素也不会影响这个渲染区域内的元素。

简单说:BFC就是页面上的一个隔离的独立渲染区域,区域里面的子元素不会影响到外面的元素。外面的元素也不会影响到区域里面的子元素。

CSS中最常见的渲染方式

盒子, 是CSS布局的对象和基本单位, 直观点说,就是一个页面是由很多个盒子区域组成。元素的类型和 display 属性,决定了这个盒子区域的类型。

  • 不同类型的盒子区域内的子元素, 会以不同的 Formatting Context(一个决定如何渲染文档的容器)方式渲染。
  • 块级元素盒子,display 属性为 block, list-item, table 的元素,会生成 块级元素渲染区域。并且以BFC( block fomatting context)方式渲染;
  • 行级元素盒子,display 属性为 inline, inline-block, inline-table 的元素,会生成 行级元素渲染区域。并且以IFC( inline formatting context)方式渲染;

所以,CSS中最常见的渲染方式有两大类:BFCIFC

如何创建BFC

  1. float的值不是none
  2. position的值不是static或者relative
  3. display的值是inline-block、table-cell、flex、table-caption或者inline-flex
  4. overflow的值不是visible

BFC可以解决哪些问题

1. 避免垂直方向margin合并

问题重现:

  • 垂直方向上,两个元素上下margin相遇时,两元素的间的总间距并不等于两个margin的和。而是等于最大的margin
  • 小的margin会被大的margin吞并。

image.png
解决:

  • 用一个外围块元素包裹下方元素
  • 设置新外层元素overflow:hidden;变成一个BFC方式的渲染区域。 结果:

下方元素的margin-top受到新外层元素BFC渲染区域的阻隔,不会影响外部上方的元素的margin-bottom了。同理,外部上方元素的margin-bottom,因为在BFC渲染区域之外,所以,也无法影响其内部元素的margin-top了。

2. 避免垂直方向margin溢出

问题重现:

  • 子元素设置margin-top,会超出父元素上边的范围,变成父元素的margin-top。
  • 而实际上,子元素与父元素之间,依然是没有margin-top

image.png

解决方法一:设置父元素overflow:hidden

  • 原理: 父元素变成BFC渲染区域,就必须包裹内层子元素的margin
  • 缺点: 万一有的子元素,即使溢出父元素,也希望显示呢?就会发生冲突。
    解决方法二:为父元素添加上边框,颜色设置为透明(transparent)
  • 原理: 这里不是bfc。而是因为边框本身可以阻隔margin溢出。
  • 缺点: 边框会增大父元素的实际大小,导致布局错乱。 解决方法三:用父元素的padding-top代替第一个子元素的margin-top
  • 原理: 这里也不是bfc。而是因为padding本身可以阻隔margin溢出。
  • 缺点:对父元素高度有影响。
  • 可以设置父元素box-sizing:border-box。 解决方法四:在父元素内第一个子元素之前添加一个空的table标签
  • 原理: tabledisplay属性默认相当于table,所以形成小的bfc渲染区域。其他元素的margin不能进入table范围内。就阻隔了margin向上溢出。
  • 优点: 空table元素没有大小,不占用父元素控件。
  • 缺点: 增加一个看不见的空元素,干扰查找元素 解决方法五:最好的解决:父元素::before{ content:""; display:table; }
  • 优点:既不隐藏内容,又不添加新元素,又不影响高度。
3. 自适应两栏布局:左固定,右自适应
    .left{ float:left; width:固定宽 }  
    .right{overflow:hidden; ...}

原理:变成BFC渲染区域,就不会与float:left的左侧元素发生重叠了

image.png