• 关于collapsed margin(外边距合并)


      这是前面写postion定位时写到最后面的例子的时候发现的一个问题,于是专门写一篇随笔来解释记录一下,毕竟两个知识点同时写在一篇文章里面有点混乱的感觉。。

      上篇随笔position定位遇到的问题在这里重新展示出来,代码如下:

     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4     <title></title>
     5     <script type="text/javascript" src="jquery.js"></script>
     6     <style type="text/css">
     7         div{
     8             width: 100px;
     9             height: 100px;
    10             margin-top: 20px;
    11             background-color: red;
    12         }
    13         span{
    14             position: relative;
    15             display: block;
    16             width: 100px;
    17             height: 100px;
    18             background-color: pink;
    19             margin-top: -40px;
    20         }
    21     </style>
    22     <script type="text/javascript">
    23     
    24     </script>
    25 </head>
    26 <body>
    27     <div>
    28         <span></span>
    29     </div>
    30 </body>
    31 </html>
    View Code

      在现在的比较新版的浏览器的效果图如下:

      (这里粉色的height为80px;)

      现在来解释一下原因(这里遇到的一个问题是外边距合并的问题):

      collapsed margin:外边距合并。详细解释可以看:W3C官网的解释

      In CSS, the adjoining margins of two or more boxes (which might or might not be siblings) can combine to form a single margin. Margins that combine this way are said to collapse, and the resulting combined margin is called a collapsed margin.

      中文解释:在CSS中,两个或多个毗邻(父子元素或兄弟元素)的普通流中的块元素垂直方向上的 margin 会发生叠加。这种方式形成的外边距即可称为外边距叠加(collapsed margin)。

      毗邻:没有被非空内容、padding、border 或 clear 分隔开的两个元素(可以是父子关系或者兄弟关系,只要相邻即可)。

      普通流:除浮动( float )、绝对定位( absolute )外的代码。

      下面几种情况算是毗邻:

      (1)top margin of a box and top margin of its first in-flow child

        一个元素的 margin-top 和它的第一个子元素的 margin-top

      (2)bottom margin of box and top margin of its next in-flow following sibling

        普通流中一个元素的 margtin-bottom 和它的紧邻的兄弟元素的的 margin-top

      (3)bottom margin of a last in-flow child and bottom margin of its parent if the parent has ‘auto’ computed height

        一个元素( height 为 auto )的 margin-bottom 和它的最后一个子元素的margin-bottom

      (4)top and bottom margins of a box that does not establish a new block formatting context and that has zero computed ‘min-height’, zero or ‘auto’ computed ‘height’, and no in-flow children

        一个没有创建 BFC、没有子元素、height 为0的元素自身的 margin-top 和 margin-bottom

      上网找了一下图片说明一下:

    • 兄弟元素

      

    • 父子元素

      

    • 空元素

      

    • 以上三种混合

      

      

      现在可以解释最前面遇到的问题了:

      在上面的代码中,之所以父元素div和子元素span会重叠并且看到的实际高度只有80px,就是因为div的margin-top:20px;与span的margin-top:-40px;发生重叠,剩下-20px,而此时的margin-top:-20px;就会被认为是父元素div的外边距了,所以才会整体向上移动20px的距离。

    (注意:这里因为两个外边距一个是负一个是正,所以刚好叠加只剩下-20px,而不是比较得到比较大的数作为外边距的值)

    * 两个相邻的外边距都是正数时,折叠结果是它们两者之间较大的值
    * 两个相邻的外边距都是负数时,折叠结果是两者绝对值的较大值
    * 两个外边距一正一负时,折叠结果是两者的相加的和

      

      应该如何避免这种情况:

      官网如下说:

    • Margins between a floated box and any other box do not collapse (not even between a float and its in-flow children).
    • Margins of elements that establish new block formatting contexts (such as floats and elements with 'overflow' other than 'visible') do not collapse with their in-flow children.
    • Margins of absolutely positioned boxes do not collapse (not even with their in-flow children).
    • Margins of inline-block boxes do not collapse (not even with their in-flow children).
    • The bottom margin of an in-flow block-level element always collapses with the top margin of its next in-flow block-level sibling, unless that sibling has clearance.
    • The top margin of an in-flow block element collapses with its first in-flow block-level child's top margin if the element has no top border, no top padding, and the child has no clearance.
    • The bottom margin of an in-flow block box with a 'height' of 'auto' and a 'min-height' of zero collapses with its last in-flow block-level child's bottom margin if the box has no bottom padding and no bottom border and the child's bottom margin does not collapse with a top margin that has clearance.
    • A box's own margins collapse if the 'min-height' property is zero, and it has neither top or bottom borders nor top or bottom padding, and it has a'height' of either 0 or 'auto', and it does not contain a line box, and all of its in-flow children's margins (if any) collapse.

      即:

    • 浮动元素和其他任何元素之间不发生外边距叠加 (包括和它的子元素).
    • 创建了 BFC 的元素不会和它的子元素发生外边距叠加
    • 绝对定位元素和其他任何元素之间不发生外边距叠加(包括和它的子元素).
    • inline-block 元素和其他任何元素之间不发生外边距叠加 (包括和它的子元素).
    • 普通流中的块级元素的 margin-bottom 永远和它相邻的下一个块级元素的 margin-top 叠加(除非相邻的兄弟元素clear)
    • 普通流中的块级元素(没有 border-top、没有 padding-top )的 margin-top 和它的第一个普通流中的子元素(没有 clear )发生 margin-top 叠加
    • 普通流中的块级元素( height 为 auto、min-height 为 0、没有 border-bottom、没有 padding-bottom )和它的最后一个普通流中的子元素(没有自身发生 margin 叠加或 clear )发生 margin-bottom 叠加
    • 如果一个元素的 min-height 为 0、没有 border、没有 padding、高度为 0 或者 auto、不包含子元素,那么它自身的外边距会发生叠加

      总结:

    • 兄弟元素间设置 float 或 inline-block 或 absolute
    • 为父元素设置 BFC 或 padding 或 border
    • 设置margin时最好用同一个方向,要不都 top 要不都 bottom.

    2016-8-5补充:

       当父元素里面包含的两个子元素是浮动的话,那么该父元素不会包裹子元素,即不会被子元素撑开,解决的方式就是:为父元素设置overflow:hidden或浮动父元素。采用这种方式的根本原因在于创建BFC的元素,子浮动元素也会参与其高度计算,即不会产生高度塌陷问题。实际上只要让父元素生成BFC即可,并不只有这两种方式。

    哪些情况会产生BFC:

    • 根元素

    • float属性不为none

    • position为absolute或fixed

    • display为inline-block, table-cell, table-caption, flex, inline-flex

    • overflow不为visible

      参考资料:css框模型

      

  • 相关阅读:
    九度OJ 1131:合唱队形 (DP、最长上升下降序列)
    九度OJ 1130:日志排序 (排序)
    九度OJ 1129:Skew数 (大数运算)
    九度OJ 1128:求平均年龄 (基础题)
    九度OJ 1127:简单密码 (翻译)
    九度OJ 1126:打印极值点下标 (基础题)
    九度OJ 1125:大整数的因子 (大数运算)
    九度OJ 1124:Digital Roots(数根) (递归)
    存储过程
    Cookie 和 Session
  • 原文地址:https://www.cnblogs.com/loveya/p/5458769.html
Copyright © 2020-2023  润新知