CSS margin重叠 & CSS BFC(Block Formatting Context)

CSS边界重叠
边界重叠是指两个或多个盒子(可能相邻也可能嵌套)的相邻边界(其间没有任何非空内容、补白、边框)重合在一起而形成一个单一边界。

两个或多个块级盒子的垂直相邻边界会重合,它们的边界宽度是相邻边界宽度中的最大值。注意水平边界是不会重合的。

1.父子重叠

<style>
    .parent {
        background: #E7A1C5;
    }
    .parent .child {
        background: #C8CDF5;
        height: 100px;
        margin-top: 10px;
    }
</style>
<section class="parent">
    <article class="child"></article>
</section>

期待这样:

实际这样:

在这里父元素的高度不是110px,而是100px,在这里发生了高度坍塌。原因是如果父元素无 border、padding、inline content 、 clearance时,子元素的margin-top/bottom会与父元素的margin产生重叠问题。

1、 外层元素padding代替
2、内层元素绝对定位  position: absolute;
3、外层元素 overflow:hidden; 
4、内层元素 加float:left; 或display:inline-block;(父子元素指定宽高)
5、内层元素padding:1px;
6、外层元素有边框

2.兄弟重叠

<style>
    #margin {
        background: #E7A1C5;
        overflow: hidden;
        width: 300px;
    }
    #margin>p {
        background: #C8CDF5;
        margin: 20px auto 30px;
    }
</style>
<section id="margin">
    <p>1</p>
    <p>2</p>
    <p>3</p>
</section>

实际:

可以看到1和2,2和3之间的间距不是50px,发生了边距重叠是取了它们之间的最大值30px。原因是当一个元素出现在另一个元素上面时,第一个元素的下外边距与第二个元素的上外边距会发生合并。

边距重叠计算方式
a、全部都为正值,取最大者;
b、不全是正值,则都取绝对值,然后用正值减去最大值;
c、没有正值,则都取绝对值,然后用0减去最大值。

解决:

1、 将元素设置为浮动 float:left;
2、 在设置margin-top/bottom值时统一设置上或下;
3、 元素的position的值为absolute/fixed;

注释:只有普通文档流中块框的垂直外边距才会发生外边距合并。行内框、浮动框或绝对定位之间的外边距不会合并。

3.空元素的边距重叠

假设有一个空元素,它有外边距,但是没有边框或填充。在这种情况下,上外边距与下外边距就碰到了一起,它们会发生合并:

鉴于以上问题 引出BFC.

BFC的定义
是 W3C CSS 2.1 规范中的一个概念,它决定了元素如何对其内容进行定位,以及与其他元素的关系和相互作用。
在创建了 Block Formatting Context 的元素中,其子元素会一个接一个地放置。垂直方向上他们的起点是一个包含块的顶部,两个相邻的元素之间的垂直距离取决于 ‘margin’ 特性。在 Block Formatting Context 中相邻的块级元素的垂直边距会折叠(collapse)。

在 Block Formatting Context 中,每一个元素左外边与包含块的左边相接触(对于从右到左的格式化,右外边接触右边), 即使存在浮动也是如此(尽管一个元素的内容区域会由于浮动而压缩),除非这个元素也创建了一个新的 Block Formatting Context 。

BFC到底是什么?

当涉及到可视化布局的时候,Block Formatting Context提供了一个环境,HTML元素在这个环境中按照一定规则进行布局。一个环境中的元素不会影响到其它环境中的布局。比如浮动元素会形成BFC,浮动元素内部子元素的主要受该浮动元素影响,两个浮动元素之间是互不影响的。这里有点类似一个BFC就是一个独立的行政单位的意思。

怎样才能形成BFC

  • float的值不为none。
  • overflow的值不为visible。
  • display的值为table-cell, table-caption, inline-block中的任何一个。
  • position的值不为relative和static。

BFC的作用

1.不和浮动元素重叠

如果一个浮动元素后面跟着一个非浮动的元素,那么就会产生一个覆盖的现象,很多自适应的两栏布局就是这么做的。比如下图的效果,参考例子

1 <div style="float:left; border: 2px solid red"> 123</div>
2 <p style="border: 2px solid blue;display:block;overflow:hidden;*zoom:1">
3 The quick brown fox jumped over the lazy dog's back.
4 The quick brown fox jumped over the lazy dog's back.
5 The quick brown fox jumped over the lazy dog's back.
6 The quick brown fox jumped over the lazy dog's back.
7 </p>

2.清除元素内部浮动

只要把父元素设为BFC就可以清理子元素的浮动了,最常见的用法就是在父元素上设置overflow: hidden样式,对于IE6加上zoom:1就可以了(IE Haslayout)。

3.嵌套元素Margin边距折叠问题的解决

按照BFC的定义,只有同属于一个BFC时,两个元素才有可能发生垂直Margin的重叠,这个包括相邻元素,嵌套元素,只要他们之间没有阻挡(例如边框,非空内容,padding等)就会发生margin重叠。

因此要解决margin重叠问题,只要让它们不在同一个BFC就行了,但是对于两个相邻元素来说,意义不大,没有必要给它们加个外壳,但是对于嵌套元素来说就很有必要了,只要把父元素设为BFC就可以了。这样子元素的margin就不会和父元素的margin发生重叠了。

原文地址:https://www.cnblogs.com/Iona/p/4750477.html