CSS中的BFC详解

最近在前端群上面看到有人提出了一个概念:BFC,没听懂是什么意思,于是找了一些资料来看看。

 

  Formatting Context:指页面中的一个渲染区域,并且拥有一套渲染规则,他决定了其子元素如何定位,以及与其他元素的相互关系和作用。

首先来讲解一些常用的概念:

1.普通流

普通流就是元素按照其出现的顺序至上而下进行布局,行内元素水平排列,至到本行已经排满了就再续在下一行进行排列。而块级元素则会自己出现新的一行。也就是说,普通流是按照其出现的顺序而决定它的位置的。

 

当position为static或relative,并且没有设置float或float为none的时候会触发普通流。

相对于静态定位,position:static,盒的位置是普通流布局里面的位置。

相对于相对定位,position:relative,盒偏移位置由top\bottom\left\right来定义,仍然保留原有的位置,其他普通流的元素不能占用这个偏移的位置。

 

 

 

2.float

设置了float的元素,首先按照普通流的位置进行布局,然后根据float的方向进行向左或者向右进行偏移。会导致普通流环绕在它的周边,除非设置clear属性。

ok这里我又疑惑了,到底float脱不脱离文档流,既然脱离,为什么普通流会环绕在它周边?也就是说它为什么还占有普通流的空间?

float是半脱离,在文档流中会占有一定的位置,使用float脱离文档流时,其他盒子会无视这个元素,但其他盒子内的文本仍然会为这个元素让出位置,环绕在周边,

CSS中的BFC详解

可以见到其他元素在布局的时候,是占有了float的位置的,但是!其他元素内部的元素是会给他让出一个位置的!!除非设置了clear,这样其他元素就会在下一行进行布局。

 

 

 

 

3.绝对定位设置了绝对定位的元素,它就不在普通流的位置,而是自己在另一层。

它的定位相对于它的包含块。元素定位将相对于最近的一个relative、fixed或absolute的父元素,如果没有则相对于body;

 

 

 

那么什么是BFC,BFC就是block formatting contexts(块级格式化上下文),怎么理解这句话呢?

具有 BFC 特性的元素可以看作是隔离了的独立容器,容器里面的元素不会在布局上影响到外面的元素,并且 BFC 具有普通容器所没有的一些特性。

也就是说,只要设定为BFC的元素,那么它无论怎么变化都不会影响普通流上面的元素。

所以怎么样设置就是BFC呢?

具有以下特性的元素就是BFC

  • body的根元素(就是body元素)

  • 浮动元素

  • 绝对定位元素(position值为absolute或者fixed)

  • 行内块(display为inline-block)

  • 表格单元格(display:table-cell)或者表格里面的单元格

  • overflow除了visible以外的值。

  • 弹性盒(flex ,display:flex)

 

一个BFC包含创建该上下文元素的所有子元素,但不包括创建了新BFC的子元素的内部元素。

<div id='div_1' class='BFC'> 

    <div id='div_2'> 

        <div id='div_3'></div> 

        <div id='div_4'></div> 

    </div>

     <div id='div_5' class='BFC'>

         <div id='div_6'></div> 

        <div id='div_7'></div>

     </div>

 </div>

 

在上面的代码中,div1创建了一个bfc,那么其所有的子元素都是bfc,但是,因为div5又创建了新的bfc,所以div6,div7是属于div5的bfc。

也就是说,div1,2,3,4,5是一个bfc,67是一个bfc

也就是说一个元素不能同时存在于两个bfc中。

BFC的一个最重要的效果是,让处于BFC内部的元素与外部的元素相互隔离,使内外元素的定位不会相互影响。这是利用BFC清除浮动所利用的特性,关于清除浮动将在后面讲述。

 

BFC元素的一些特点

1.同一个BFC下,外边距会发生重叠

CSS中的BFC详解

打开浏览器可以看到,上面的div的下边距和下面div的上边距重叠在一起了。

CSS中的BFC详解

 

如果不想像上面那样,边距重叠在一起,可以将其放在不同的 BFC 容器中如

CSS中的BFC详解

 

CSS中的BFC详解

 

 

2.BFC元素可以包含浮动元素(清除浮动)

因为浮动元素是会脱离普通文档流,所以如果在一个普通流里面包含一个浮动流,那么这个浮动流的高度是不在普通流里面的,例如

 

<div style="border: 1px solid #000;">

 

<div style="width: 100px;height: 100px;background: #eee;float: left;"></div>

 

</div>

 

 

CSS中的BFC详解

可以看到外层div元素它的高度只是border的高度,并不包含float元素所设置的高度。

但是如果将这个外层元素设置为BFC,可以看到,浮动元素就会被包含进去了。

<div style="border: 1px solid #000; overflow: hidden">

    <div style="width: 100px;height: 100px;background: #eee;float: left;"></div>

</div>

CSS中的BFC详解

 

 

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

CSS中的BFC详解

可以看到此时第一个元素将第二个元素所覆盖流,此时将第二个元素设置为BFC元素就会变成两个独立的块元素。

CSS中的BFC详解

 

 

 

那么,BFC是如何进行布局的呢?

1. 内部的Box会在垂直方向上一个接一个的放置

2. 垂直方向上的距离由margin决定。(完整的说法是:属于同一个BFC的两个相邻Box的margin会发生重叠,与方向无关。)

3. 每个元素的左外边距与包含块的左边界相接触(从左向右),即使浮动元素也是如此。(这说明BFC中子元素不会超出他的包含块,而position为absolute的元素可以超出他的包含块边界)

4. BFC的区域不会与float的元素区域重叠

5. 计算BFC的高度时,浮动子元素也参与计算

6. BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面元素,反之亦然