CSS BFC Haslayout详解


原文链接: CSS BFC Haslayout详解

理解CSS中BFC_CSS, BFC 教程_w3cplus
BFC 深入理解 - 前端 - 掘金
深入理解BFC
IE中也有与BFC类似概念 haslayout

简单来说就是,触发了bfc的元素,在计算高度的时候包括浮动元素。那么结果就很明了了。如果我们要解决父元素高度塌陷问题我们只需要对父级元素触发bfc就好了

1. 为什么要使用BFC (BFC的应用场景)?

1.解决margin塌陷问题
给子元素加一个父元素,并设置父元素为BFC
(1)为父盒子设置border,为外层添加border后父子盒子就不是真正意义上的贴合。
(2)[BFC方式] 为父盒子添加overflow:hidden;
(3)为父盒子设定padding值。

2.侵占浮动元素的位置
    设置非浮动元素为 BFC

3.清除浮动
    设置父元素为BFC

2. 如何触发一个盒子的BFC

float: left|right|inherit
overflow: hidden|scroll|auto
position: absolute|fixed
display: inline-block|table-cell|table-caption

根元素
float 的值不为none
overflow 的值不为visible元素(可以为hidden,scroll,auto);
display 的值为inline-block,table-cell,table-caption,flex,inline-flex中的任何一个;
position 的值为absolute,fixed(不为static,relative中的任何一个);绝对定位元素
display:table也认为可以生成BFC,其实这里的主要原因在于table会默认生成一个匿名的table-cell,正是这个匿名的table-cell生成了BFC。

float

浮动元素产生浮动流,与之对应的是普通文档流
浮动元素会脱离文档流 并向左/向右浮动,直到碰到父元素或者另一个浮动元素
浮动会导致父元素高度坍塌

  1. float会脱离普通流,不占用空间,不能撑开父容器 (和 postion:absoulte 类似)
  2. 所有产生了浮动流的元素,块级元素看不到他们
  3. 触发了BFC后的元素,文本类元素(含有inline的元素) 都能看到浮动元素

如何清除浮动?

不要在浮动元素上清除浮动
给最后一个元素加上clear:both之后,最后一个元素的左右都没有挨着浮动元素,但是为什么高度还是坍塌了呢?机智的你可能发现了,由于最后一个元素是浮动元素,脱离了文档流,就算给第三个元素上下加了清除空间,也是没有任何意义的

清除浮动主要是两种方法,即使用clear属性 ,或者BFC清除浮动。
一句话,强烈推荐clearfix的方式清除浮动!
/* 全浏览器通用的clearfix方案【推荐】*/
/* 引入了zoom以支持IE6/7 */
/* 同时加入:before以解决现代浏览器上边距折叠的问题 */
.clearfix:before,
.clearfix:after {
    display: table;
    content: " ";
}
.clearfix:after {
    clear: both;
}
.clearfix{
    *zoom: 1; /*For IE 6/7 触发hasLayout*/
}

清除浮动指什么?

浮动元素会脱离文档的普通流,而其父容器在普通流中,则存在父元素高度坍塌问题,如果我们希望浮动元素在其父容器内部浮动,则需要清除浮动,而浮动元素的能够浮动,是因为包围它的行框缩短了,从而给浮动元素留下了空间,浮动原理简述,而清除浮动就是让包围浮动元素的行框恢复原长度,但浮动元素客观存在(虽然不在普通文档流中),占据了一定空间,为了恢复原长度,行框应该向下或向上移动,直到左右没有浮动元素为止(即给浮动元素上面或下面添加了足够的清除空间),这样也就恢复了原长度。 

BFC清除浮动-解决子元素 float 后,父级元素塌陷

<style>
 .parent {
    overflow: hidden;        //方式1 为父级元素添加bfc
    border: 5px solid #fcc;
    width: 300px;
 }
                             //方式2 为父级伪元素添加bfc,不影响布局
 .parent::after {
     content:"";
     clear:both;
     display:block;
 }

.child {
    float: left;
    border: 5px solid #f66;
    width: 100px;
    height: 100px;   
}
</style>
<body>
    <div class="parent">
        <div class="child"></div>
        <div class="child"></div>
    </div>
</body>

解决父子margin塌陷问题

给子元素加一个父元素,并设置父元素为BFC

父子元素的margin重叠解决方法:给父元素设置以下任意属性,触发BFC隐藏属性: overflow:hidden|auto|scroll 、 position:absolute、float:left|right、display:inline-block 或者给父元素设置padding或border属性。

防止垂直 margin 重叠--会更改框架结构,所有不要采用

属于同一个BFC的两个相邻Box的margin会发生重叠,我们可以在p外面包裹一层容器,并触发该容器生成一个BFC。那么两个P便不属于同一个BFC,就不会发生margin重叠了。
<style>
    .wrap {
        overflow: hidden;
    }
    p {
        color: #f55;
        background: #fcc;
        width: 200px;
        line-height: 100px;
        text-align: center;
        margin: 100px;
    }
</style>

<body>
    <p>Haha</p>
    <div class="wrap">
        <p>Hehe</p>
    </div>
</body>
`