margin塌陷 BFC模型理解

网上看了很多 BFC 的概念,发现都说得不是很完整和深入,刚好最近看了一些视频教程说到了 BFC 概念所以记录一下。

BFC 的概念:

  BFC 全称:Block format context 块级格式化上下文。 就是创建一个独立的容器

BFC 的特性:

  BFC 的垂直外边距会和兄弟节点的外边距发生重叠

  BFC 内部的元素不会影响外部的元素,同样,外部的元素不会影响 BFC 内部的元素

  BFC 不会与浮动元素发生重叠

  BFC 元素的高度计算会包括元素内的浮动元素的高度

如何创建 BFC:

  1. float 的值不为 none

  2. overflow 的值不为 visible

  3. position 的值不为 static 或 relative

  4. display 的值为 inline-block, table, table-cell

下面是结合代码分析 BFC 的特性

1. BFC 的垂直外边距会和兄弟节点的外边距发生重叠

效果图:

由效果图可见,两个 BFC 的元素垂直的外边距依然会发生合并,这很符合标准。但是网上一些教程所说的利用 BFC 元素让垂直相邻的元素外边距不发生外边距合并又是什么原理呢?

其实我个人认为与 BFC 第二点的特性相关,那就是:

2. BFC 元素内部的内容不影响外部内容,相反,外部的内容不会影响 BFC 内部的内容

这话怎么说呢。说一个另外的知识点。

肯定都有遇到过这样一个情况:一个父元素里面包含着一个子元素(假设他们都是div)当子元素设置了margin-top 的时候,向下偏移的不是子元素本身而是父元素。如下代码所示:

<style type="text/css">
        *{
            padding: 0;
            margin: 0;
        }
        .father{
            background-color: #ccc;
        }
        .child{
            width: 300px;
            height: 300px;
            margin-top: 50px;
            background-color: #333;
        }
</style>

<div class="father">
        <div class="child"></div>
</div>

相信大家都司空见惯,但是可曾明白里面的原理。

css 权威指南里面说到了这个原理点,意思就是:如果父元素没有设置 padding 同时也没有设置 border 的话,它的高度值等于第一个子元素的 border-top 到 最后一个子元素的 border-bottom 的这段距离。

如果设置了padding  或 border其中一个值的时候,那么父元素高度值就等于第一个子元素的 margin-top 到 最后一个子元素的margin-bottom 的这段距离

通俗的说,如果父元素没有设置padding 同时也没有设置 border 的话,它是不会把第一个子元素的 margin-top 和 最后一个子元素的 margin-bottom 包含在内的,这就演变成子元素的 margin 外露导致影响到了父元素外部的其他元素的排版,最要命的是这些外露的 margin 还会和父元素外边的元素发生边距合并。

如果父元素自己有 margin-top 或者 margin-bottom 但是它比它的子元素外露的 margin-top 或 margin-bottom 的值小的话,会被子元素外露的 margin-top 或 margin-bottom 覆盖掉

所以我们之前所用到的解决办法 —— 设置父元素的 padding-top = 1px 实际上是让父元素的高度计算包含了第一个子元素的 margin-top 和 最后一个子元素的 margin-bottom

因此关联回我们现在所说的 BFC 模型其实道理也一样,第一个子元素的margin 外露影响元素外部内容,但是BFC 本身的规则就是一个独立的容器,内部的内容不会影响到外面的元素,所以为了达到目的,它把自身的高度计算包含了内部第一个子元素的 margin-top 和 最后一个子元素的 margin-bottom 。

于是这就达到了网上所说的,利用在 BFC 内部再建立一个BFC 容器包裹一些不需要边距合并的元素达到目的。

我们可以在这个司空见惯的例子中运用 BFC ,表现出来的效果和为父元素增加 padding 或者 border 效果一样的:

用 BFC 的解决方案:

*{
            padding: 0;
            margin: 0;
        }
        .father{
            background-color: #ccc;
            overflow: auto;
        }
        .child{
            width: 300px;
            height: 300px;
            margin-top: 50px;
            background-color: #333;
        }


<div class="father">
    <div class="child"></div>
</div>

用 padding,border 老方法解决 

<style type="text/css">
        *{
            padding: 0;
            margin: 0;
        }
        .father{
            background-color: #ccc;
            padding-top: 1px;
        }
        .child{
            width: 300px;
            height: 300px;
            margin-top: 50px;
            background-color: #333;
        }
    </style>

<div class="father">
    <div class="child"></div>
</div>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值