什么是BFC机制,如何触发BFC(消除浮动带来的父元素塌陷、垂直方向margin重叠、嵌套块级元素父元素margin塌陷)

BFC机制

BFC(Block Formatting Context):块格式化上下文

BFC是 W3C CSS 2.1 规范中的一个概念,它决定了元素如何对其内容进行定位,以及与其余元素的关系和相互做用。当涉及到可视化布局的时候,Block Formatting Context提供了一个环境,HTML元素在这个环境中按照必定规则进行布局。一个环境中的元素不会影响到其它环境中的布局。好比浮动元素会造成BFC,浮动元素内部子元素的主要受该浮动元素影响,两个浮动元素之间是互不影响的。这里有点相似一个BFC就是一个独立的行政单位的意思。也能够说BFC就是一个做用范围。能够把它理解成是一个独立的容器,而且这个容器的里box的布局,与这个容器外的绝不相干。
引自:http://www.javashuo.com/article/p-rytdiolz-w.html

简单来说,BFC提供了一个独立的布局环境,BFC中的元素布局不受外部元素的影响,也不会影响到外部元素。

※触发BFC的几种方式

1、给元素设置浮动 float: left | right

2、给元素设置脱离文档流的定位 position: absolute | fixed

3、给元素设置内容溢出 overflow: hidden | scroll |auto

4、给元素设置 display: flex | inline-block | table-cell

※几种常见问题

1、父级外边距折叠塌陷问题

嵌套的块级元素,父子元素紧贴的那一边会合并,作用在父元素上。所以给子元素设置margin-top时,父子元素会一起下移。

例:
嵌套的父子div块级元素,给子元素设置margin
在这里插入图片描述
父元素也受到了margin-top的影响
在这里插入图片描述

解决方案一、给父级1px的边框

.father{
    
    
    border: 1px solid transparent; /*transparent:设置边框透明*/
}
.son{
    
    
    margin-top: 50px;
}

解决方案二、给父级1px内边距

.father{
    
    
    padding-top:1px;
}
.son{
    
    
    margin-top: 50px;
}

解决方案三、不用margin-top,改用父级内边距padding

.father{
    
    
    padding-top: 50px;
    /*可能会撑大父元素,所以设置盒子宽高为算进边框的宽高,固定盒子大小*/
    box-sizing: boder-box;
}

解决方案四、给父元素设置overflow:hidden; (触发bfc)

父元素会变成独立的空间

.father{
    
    
    overflow: hidden;
}
.son{
    
    
    margin-top: 50px;
}

解决方案五、将子元素转换为行内块元素

.son{
    
    
    display: inline-block; /*嵌套的块级元素会塌陷,所以转化为行内块*/
    margin-top: 50px;
}

解决方案六、有浮动、固定、绝对定位的盒子不存在塌陷问题(触发bfc)

relative也会发生塌陷

/*加给父元素或子元素都可以*/
.father{
    
    
    float: left;  /*设置浮动*/
    margin-top: 50px;
}

.father{
    
    
    position: absolute;  /*绝对定位*/
    margin-top: 50px;
}

.father{
    
    
    position: fixed;  /*固定定位*/
    margin-top: 50px;
}

在这里插入图片描述

2、margin 纵向重叠及合并解决

两个盒子,上面的盒子margin-bottom: 50px; 下面的盒子margin-top: 100px; 则两个盒子纵向距离为100px。
例:

<style>
        .first{
      
      
            width: 200px;
            height: 200px;
            background-color: aqua;
            margin-bottom: 50px;
        }
        .second{
      
      
            width: 200px;
            height: 200px;
            background-color: coral;
            margin-top: 100px;
        }
</style>

<div class="first"></div>
<div class="second"></div>

在这里插入图片描述

想要纵向边距为两者之和的方法:

解决方案一、直接给其中一个盒子的外边距设为两者之和

<style>
        .second{
    
    
            width: 200px;
            height: 200px;
            background-color: coral;
            margin-top: 150px;
        }
</style>

解决方案二、触发bfc,分别给两个盒子套一个父元素,为父元素设置overflow: hidden;

    <style>
        .father{
      
      
            overflow:hidden;
        }
        .first{
      
      
            width: 200px;
            height: 200px;
            background-color: aqua;
            margin-bottom: 50px;       
        }
        .second{
      
      
            width: 200px;
            height: 200px;
            background-color: coral;
            margin-top: 100px;
        }
    </style>
    <div class="father">
        <div class="first"></div>
    </div>
    <div class="father">
        <div class="second"></div>
    </div>

在这里插入图片描述

3、清除浮动带来的父元素塌陷

当设置子元素为浮动时,子元素脱标,不占有原位置,父元素会塌陷,不再具有原来的宽高,会改变布局。
例:
正常嵌套的父子元素:

<style>
        .father{
      
      
            width: 400px;
            /* 未设置高度,高度由子元素撑起来 */
            background-color: aqua;
            padding: 20px;
        }
        .son{
      
      
            width: 100px;
            height: 100px;
            background-color: lightcoral;
        }
    </style>
    <div class="father">
        <div class="son"></div>
    </div>

在这里插入图片描述
当设置子元素为float:left
在这里插入图片描述

解决方案一、父元素固定宽高
设置父元素的高度,就不必由子元素撑起来,不会受子元素脱标影响

优点:简单代码量少,没有兼容问题

缺点:内部元素高度不确定的情况下无法使用

解决方案二、添加新元素

clear:left:清除float:left对元素造成的影响

clear:right:清除float:right对元素造成的影响

clear:both:清除float:leftfloat:right对元素造成的影响

.clear_element{
    
    
    clear: both;
}
<div class="father">
    ...
    <div class="clear_element"></div>
</div>

添加一个新元素div,设置属性清除浮动clear: both;

缺点:添加了无语义的html元素,不便后期维护

解决方案三、添加伪元素(需设置为块级元素)

.father::after{
    
    
    content: "";   /*内容为空*/
    display:block; /*::after默认添加行内元素,需设置为块元素*/
    clear: both;   /*清除浮动*/
}

解决方案四、触发父元素bfc

.father{
    
    
    overflow: hidden; /*可以设置为 hidden  auto scroll*/
}

优点:仅用css实现,代码少,浏览器支持好;

缺点:可能会使超出的部分无法显示

猜你喜欢

转载自blog.csdn.net/qq_40261601/article/details/129213461