BFC概念和清除浮动解决margin塌陷/共享

一、BFC概念

BFC 即 Block Formatting Contexts (块级格式化上下文),是W3C CSS2.1规范中的一个概念,决定了元素如何对其内容进行定位,以及与其他元素的关系和相互作用。具有BFC特性的元素可以看做是隔离了的独立容器,容器里面的元素不会在布局上影响到外面的元素,并且BFC具有普通容器所没有的的一些特性

二、BFC生成条件

只要元素满足下面任一条件即可触发BFC特性:

  • body 根元素
  • 浮动元素:float 除 none 以外的值
  • 绝对定位元素:position (absolute、fixed)
  • display 为 inline-block、table-cells、flex
  • overflow 除了 visible 以外的值(hidden、auto、scroll)

三、BFC的约束规则

BFC的约束规则

浏览器对于BFC这块区域的约束规则如下:

  • 生成BFC元素的子元素会一个接一个的放置。垂直方向上他们的起点是一个包含块的顶部,俩个相邻子元素之间垂直距离取决于元素margin特性。在BFC中相邻的块级元素外边距会折叠。
  • 生成BFC元素的子元素中,每一个子元素的外边距和包含块的左边界相接触,(对于从右到左的格式化,右外边距和右边界相接触),除非这个子元素也创建了一个新的BFC(如它自身也是一个浮动元素)。
有朋友对它做了分解,我们直接拿来:
  • 内部的BOX会在垂直方向上一个接一个的放置;
  • 垂直方向上的距离有margin决定。(完整的说法是:属于同一个BFC的俩个相邻的BOX的margin会发生重叠,与方向无关。)
  • 每个元素的左外边距与包含块的左边界相接触(从左到右),即使浮动元素也是如此。(这说明BFC中的子元素不会超出它的包含块,而position为absolute的元素可以超出它的包含块边界)我的理解这解释了BFC是独立的容器,而position为absolute的元素不是独立的容器;
  • BFC的区域不会与float的元素区域重叠;
  • 计算BFC的高度时,浮动子元素也参与计算;
  • BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然;
CSS的几条规则:
  • Block元素会扩展到与父元素同宽,所以block元素会垂直排列;
  • 垂直方向上的俩个相邻DIV的margin会重叠,而水平方向不会(此规则并不完全正确);
  • 浮动元素会尽量往左上方(或右下方);
  • 为父元素设置overflow:hidden或浮动父元素,则会包含浮动元素;

如何创建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重叠

注意2解决嵌套的父子元素margin共享办法如下:

  • 使用BFC的约束规则
    • 父级或子元素使用浮动或者绝对定位absolute(浮动或绝对定位不参与margin的折叠)这里分别是使父级或子元素成为BFC元素,因为浮动或者绝对定位absolute恰好是BFC的生成条件之一。
    • 父级overflow:hidden;
  • 其他方法:
    • 父级设置padding(破坏非空白的折叠条件)
    • 父级设置border(破坏非空白的折叠条件)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>防止margin重叠</title>
</head>
<style>
    *{
        margin: 0;
        padding: 0;
    }
    p {
        color: #f55;
        background: yellow;
        width: 200px;
        line-height: 100px;
        text-align:center;
        margin: 30px;
    }
</style>
<body>
    <p>看看我的 margin是多少</p>
    <p>看看我的 margin是多少</p>
</body>
</html>

页面生成的效果就是这样的:

在这里插入图片描述

根据属于同一个BFC的两个相邻的Box会发生margin重叠,所以我们可以设置,两个不同的BFC,也就是我们可以让把第二个p用div包起来,然后激活它使其成为一个BFC

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>防止margin重叠</title>
</head>
<style>
    *{
        margin: 0;
        padding: 0;
    }
    p {
        color: #f55;
        background: yellow;
        width: 200px;
        line-height: 100px;
        text-align:center;
        margin: 30px;
    }
    div{
        overflow: hidden;
    }
</style>
<body>
    <p>看看我的 margin是多少</p>
    <div>
        <p>看看我的 margin是多少</p>
    </div>
</body>
</html>

在这里插入图片描述

2.浮动相关问题

高度塌陷问题,在通常情况下父元素的高度会被子元素撑开,而在这里因为其子元素为浮动元素所以父元素发生了高度坍塌,上下边界重合,这时就可以用BFC来清除浮动了。

<div style="border: 1px solid #000;">
    <div style="width: 100px;height: 100px;background: grey;float: left;"></div>
</div>

在这里插入图片描述
由于容器内元素浮动,脱离了文档流,所以容器只剩下2px的边距高度。如果触发容器的BFC,那么容器将会包裹浮动元素。

<div style="border: 1px solid #000;overflow: hidden">
    <div style="width: 100px;height: 100px;background: grey;float: left;"></div>
</div>

在这里插入图片描述

3.阻止元素被浮动元素覆盖

div浮动兄弟这该问题:由于左侧块级元素发生了浮动,所以和右侧未发生浮动的块级元素不在同一层内,所以会发生div遮挡问题。可以给右侧元素添加 overflow: hidden,触发BFC来解决遮挡问题。

<div style="height: 100px;width: 100px;float: left;background: lightblue">我是一个左浮动的元素</div>
<div style="width: 200px; height: 200px;background: grey">我是一个没有设置浮动, 
也没有触发 BFC 元素, width: 200px; height:200px; background: grey;</div>
123

在这里插入图片描述
这时候其实第二个元素有部分被浮动元素所覆盖,但是文本信息不会被浮动元素所覆盖,如果想避免元素被覆盖,可触发第二个元素的BFC特性,在第二个元素中加入overflow:hidden,就会变成:

<div style="height: 100px;width: 100px;float: left;background: lightblue">我是一个左浮动的元素</div>
<div style="width: 200px; height: 200px;background: grey;overflow:hidden">我是一个没有设置浮动, 
也没有触发 BFC 元素, width: 200px; height:200px; background: grey;</div>
123

在这里插入图片描述

这个方法可以用来实现两列自适应布局,效果不错,这时候左边的宽度固定,右边的内容自适应宽度。

4.自适应两栏布局

每个盒子的margin box的左边,与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<style>
    *{
        margin: 0;
        padding: 0;
    }
    body {
        width: 100%;
        position: relative;
    }
 
    .left {
        width: 100px;
        height: 150px;
        float: left;
        background: rgb(139, 214, 78);
        text-align: center;
        line-height: 150px;
        font-size: 20px;
    }
 
    .right {
        height: 300px;
        background: rgb(170, 54, 236);
        text-align: center;
        line-height: 300px;
        font-size: 40px;
    }
</style>
<body>
    <div class="left">LEFT</div>
    <div class="right">RIGHT</div>
</body>
</html>

页面:

在这里插入图片描述

又因为:

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

所以我们让right单独成为一个BFC

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<style>
    *{
        margin: 0;
        padding: 0;
    }
    body {
        width: 100%;
        position: relative;
    }
 
    .left {
        width: 100px;
        height: 150px;
        float: left;
        background: rgb(139, 214, 78);
        text-align: center;
        line-height: 150px;
        font-size: 20px;
    }
 
    .right {
        overflow: hidden;
        height: 300px;
        background: rgb(170, 54, 236);
        text-align: center;
        line-height: 300px;
        font-size: 40px;
    }
</style>
<body>
    <div class="left">LEFT</div>
    <div class="right">RIGHT</div>
</body>
</html>

页面:

在这里插入图片描述

right会自动的适应宽度,这时候就形成了一个两栏自适应的布局。

清除浮动

1、尾部添加div

<div>
    <p style="float:left">
    </p>
    <div style="clear:both"></div>
</div>

这个方法通俗点将就是,父元素下面的子元素都浮动了,如果有一个不浮动岂不是就能包住了?没错这个方法就是尾部添加div的方式思想。
2、伪类清除

<style>
    .clearfix{
        *zoom:1;
    }
    .clearfix:after{
        content:"";
        display:block;
        clear:both;
    }
</style>
<div class="clearfix">
    <ul style="float:left">
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
</div>

3、BFC处理
也就是触发BFC的生成条件
3.1、设置父元素float的值不为none

<div style="float:left">
    <ul style="float:left">
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
</div>

3.2、设置父元素overflow的值不为visible

<div style="overflow:hidden">
    <ul style="float:left">
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
</div>

3.3、display的值为inline-block、table-cell、table-caption

<div style="display:inline-block">
    <ul style="float:left">
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
</div>

用这个方法时注意ie8不支持inline-block

3.4、position的值为absolute或fixed

<div style="position:fixed">
    <ul style="float:left">
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
</div>

参考:
我对BFC的理解
浅析BFC原理及作用
BFC与清除浮动

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值