zoukankan      html  css  js  c++  java
  • CSS中margin折叠问题记录

    为了了解margin折叠问题,首先需要知道一个概念:块级格式上下文Block Formatting Context(简称BFC ),这是Web页面的一种布局方式,通俗点说,也是指页面上一个渲染区域,里面的元素按文档流中的顺序垂直排列,并且发生垂直方向上的margin折叠,同事这个区域内的元素布局不会对外面的元素有任何影响,反过来,也是一样。那要问了,这个要BFC是怎么产生。1、在W3C标准中有明确的说明,这里就简要概括一下:

    当元素满足一下任何一个条件是都会产生一个BFC:

    • float属性取值不是“none”
    • overflow属性取值不是“visible”
    • display的值为 “table-cell”, “table-caption”, or “inline-block”中的任何一个
    • position的值不为 “static” 或 “relative”中的任何一个

    可以看看下面这个图:

    果然按定义规定定义的几个BFC,内部的排列都是垂直排列的。

    2、BFC内部垂直方向上的margin折叠:

    先看下面的例子:

     1 <!DOCTYPE html>
     2 <html>
     3 <head lang="en">
     4     <meta charset="UTF-8">
     5     <title>测试</title>
     6 </head>
     7 <style>
     8     *{
     9         margin: 0;
    10         padding: 0;
    11     }
    12     #father{
    13         width: 2000px;
    14         height: 200px;
    15         background: #0016d9;
    16     }
    17     #first-child{
    18         margin-top: 20px;
    19         background: chocolate;
    20         width: 60px;
    21         height: 60px;
    22     }
    23     #second-child{
    24         background: chartreuse;
    25         width: 60px;
    26         height: 60px;
    27         margin-bottom: 20px;
    28     }
    29     #three-child{
    30         margin-top:40px;
    31         background: fuchsia;
    32         width: 60px;
    33         height: 60px;
    34     }
    35 
    36 </style>
    37 <body>
    38     <div id="father">
    39         <div id="first-child">box1</div>
    40         <div id="second-child">box2</div>
    41         <div id="three-child">box3</div>
    42     </div>
    43 </body>
    44 </html>
    View Code

    看到这段代码你可以先画一画可能出现的结果。

    下面的这段代码画出来的结果:

    结果是不是跟你想得一样呢,不管是不是跟你想得一样,反正跟我想的是不太一样。我开始觉得box1应该蓝色框上边20px,box2和box3应该距离60px(盒子边长就是60px),但是事实上不是这样。box1距离body上边20px,而box2和box3之间距离40px,就是因为发生了折叠,可能有人会问,这里面没有构成BFC啊,其实外面那个根元素就是一个最大的BFC,我们看到的这些元素就在这个大的BFC里面发生了margin折叠。为了让这个折叠现象去除,我们可以让发生折叠的地方建立独立的BFC,因此我们可以给蓝色框加一个属性overflow:hidden,然后给box2和box3再加一个父级框,并添加可以构造BFC的属性。

    如下所示:

     1 <!DOCTYPE html>
     2 <html>
     3 <head lang="en">
     4     <meta charset="UTF-8">
     5     <title>测试</title>
     6 </head>
     7 <style>
     8     *{
     9         margin: 0;
    10         padding: 0;
    11     }
    12     #father{
    13         overflow: hidden;
    14         width: 200px;
    15         height: 400px;
    16         background: #0016d9;
    17     }
    18     #first-child{
    19         margin-top: 20px;
    20         background: chocolate;
    21         width: 60px;
    22         height: 60px;
    23     }
    24     #second-child{
    25         background: chartreuse;
    26         width: 60px;
    27         height: 60px;
    28         margin-bottom: 20px;
    29     }
    30     #three-child{
    31         margin-top:40px;
    32         background: fuchsia;
    33         width: 60px;
    34         height: 60px;
    35     }
    36 
    37 </style>
    38 <body>
    39     <div id="father">
    40         <div id="first-child">box1</div>
    41         <div style="overflow: hidden">
    42             <div id="second-child">box2</div>
    43         </div>
    44         <div style="float: left">
    45             <div id="three-child">box3</div>
    46         </div>
    47 
    48 
    49     </div>
    50 </body>
    51 </html>
    View Code

    得到我们想要的结果:

    3、总结一下

    • margin折叠的产生有几个条件:

      • 这些margin都处于普通流中,并在同一个BFC中;
      • 这些margin没有被非空内容、padding、border 或 clear 分隔开;
      • 这些margin在垂直方向上是毗邻的,包括以下几种情况:
        1、一个box的top margin与第一个子box的top margin
        2、一个box的bottom margin与最后一个子box的bottom margin,但须在该box的height 为auto的情况下
        3、一个box的bottom margin与紧接着的下一个box的top margin
        4、一个box的top margin与其自身的bottom margin,但须满足没创建BFC、零min-height、零或者“auto”的height、没有普通流的子box

      垂直方向上毗邻的box不会发生折叠的情况:

      • 根元素的外边距不会参与折叠
      • 一个有clearance的box的上下margin毗邻,它会与紧接着的下一个box发生margin折叠,但折叠后的margin不会再与它们父box的bottom margin折叠

      折叠边距的计算

      当两个margin都是正值的时候,取两者的最大值;当 margin 都是负值的时候,取的是其中绝对值较大的,然后,从 0 位置,负向位移;当有正有负的时候,先取出负 margin 中绝对值中最大的,然后,和正 margin 值中最大的 margin 相加。但必须注意,所有毗邻的margin要一起参与运算,不能分步进行。

  • 相关阅读:
    卡特兰数
    hdu 1023 Train Problem II
    hdu 1022 Train Problem
    hdu 1021 Fibonacci Again 找规律
    java大数模板
    gcd
    object dection资源
    Rich feature hierarchies for accurate object detection and semantic segmentation(RCNN)
    softmax sigmoid
    凸优化
  • 原文地址:https://www.cnblogs.com/hot-destiny/p/6285536.html
Copyright © 2011-2022 走看看