Margin会重叠,你造吗

之因此要专门写一篇文章去解释margin重叠,一是由于前面的文章里有提到过,怕有些童鞋不了解;二是要写的内容不是三言两语就能说清楚的。css

在讲重叠以前,咱们先来了解一下margin这个属性。html

一. margin 基础讲解

这个属性呢,太常见,我就大概讲讲,有几点你们注意一下就好。chrome

margin, 实为margin-left, margin-right, margin-top, margin-bottom的一个简写,这些子属性分别用来设置box的左 / 右 / 上 / 下外边距的宽度,它们的具体用法以下:浏览器

属性名: margin-left / margin-right / margin-top / margin-bottom
值: <length> | <percentage> | inherit
初始值: 0
继承性: 无
应用对象:全部dom元素,除了display为table-row-group,table-row, table-column-group, table-column, table-header-group, table-footer-group, table-cell
百分比: 参考containing block的 宽度
计算值( computed value,参考第4条):开发人员指定的百分比值 或 一个绝对长度

有一些使用细节须要说明一下:bash

  • margin-top和margin-bottom在inline box(看第18条)上没有任何效果。
  • 属性值设为百分比时,参考对象为containing block的宽度,即便是margin-top,margin-bottom也是酱紫的
  • margin设为一个值时,代表四个子属性均为此值;设为两个值时,代表margin-top和margin-bottom将为第一个值,margin-left和margin-right将为第二个值;设为三个值,代表margin-top取第一个值,margin-left和margin-right取第二个值,margin-bottom取第三个值;设为四个值,则按照top, right, bottom, left的顺序从第一个值开始设置。例如:
margin:20px;  等同于 全部边均为20px

margin:10px 20px; 等同于 margin-top & margin-bottom为10px, margin-left & margin-right为20px

margin:10px 20px 30px; 等同于 margin-top为10px, margin-left & margin-right为20px, margin-bottom为30px

margin:10px 20px 30px 40px; 等同于 margin-top为10px,margin-right为20px,margin-bottom为30px,margin-left为40px复制代码

嗯哼~蛮简单的~~那就来点复杂的吧!dom

二. margin 重叠 详解

何为margin重叠?两个或多个box的相邻margin合在一块儿,成为一个margin。其实就是两个margin重叠在一块,那么呈现出来的效果固然是一个的咯。spa

如何才能产生这种效果呢?3d

首先,你得保证用的是垂直方向的margin(margin-top & margin-bottom)。你要是用margin-left和margin-right,试一百次都不会出现!code

其次,应用对象要选好。不是全部box均可以!(忽然以为css里的规则一套一套的,水好深~~)orm

最后,重叠的环境要准备好。即便对象选好了,重叠也不是百分百就有,只有知足特定的条件才会产生。

重叠对象

在我说出以前,你们能够先想一想哪些对象会有margin重叠。

咱们能够试试排除法。CSS中的box无非就四种:float box,absolute positioned box,inline-level box, block-level box。

看过前面的定位文章的童鞋应该知道,float box和absolute positioned box都会脱离正常流而自成一条流,流与流之间是各玩各的,互不干扰,那么咱们能够先排除这两种。而inline-level box在渲染过程当中会参与inline formatting context,这个上下文中的box不会发生margin重叠。那么剩下的只有block-level box。

那么,全部的block-level box都会发生重叠吗?

是的,可是——要排除root box(第28条)

如今,咱们大体知道重叠对象会是两个block-level box(不包括root box)。这只是一个初筛条件,这两个重叠对象还必须同属一个block formatting context,具体为何呢,看看以前介绍bfc的文章就明白了。

重叠环境

对于一个符合条件的box而言,如下任何一种状况都会发生重叠:

  1. top margin 与 它的第一个处于普通流中的孩子的top margin
  2. height 为auto,它的bottom margin 与 它的最后一个处于普通流中的孩子的bottom margin
  3. bottom margin 与 它的下一个处于普通流中的兄弟的top margin
  4. overflow为visible(即该box不会创建bfc), min-height 的computed value(第四条)为0,height的computed value为0或auto,无孩子box,它的top margin与bottom margin

特例:overflow不为visible的block-level box的margin不会与它的任何在普通流中的孩子发生margin 重叠,但可与处在同一bfc的兄弟box发现margin 重叠。

咱们来看看示例:

例1:父box与第一个子孩子box

<!DOCTYPE>
<html>
  <head>
      <style>
          .parent{
              margin-top:20px;
              margin-bottom:10px;
              background-color: #e6e96e;
          }
          .child{
              background-color: aquamarine;
          }
          .first{
            margin-top:30px;
            margin-bottom:30px;
          }
      </style>
  </head>
  <body>
    <div class='parent'>
        <div class='child first'>haha</div>       
    </div>
 </body>
</html>复制代码

chrome浏览器显示:

很明显,二者margin发生重叠。

例2:box自身的top margin与bottom margin发生重叠 && 兄弟box之间margin重叠 && overflow不为visible的box不与孩子box发生margin重叠

<!DOCTYPE>
<html>
  <head>
      <style>
          .parent{
              width:500px;
              min-height: 0;
              height:auto;
              margin-top:20px;
              margin-bottom:10px;
              background-color: #e6e96e;
          }
          .parent-second{
              overflow:hidden;
          }
          .child{
              background-color: aquamarine;
          }
          .first-child{
            margin-top:30px;
            margin-bottom:30px;
          }
          .second-child{
              width:200px;
              margin-top:60px;
              margin-bottom:60px;
          }
      </style>
  </head>
  <body>
    <div class='parent'>
    </div>
    <div class='parent parent-second'>
            <div class='child first-child'>haha in second div</div>
            <div class='child second-child'>lala in second div</div> 
    </div>
 </body>
</html>复制代码

chrom显示以下:

咱们看第一个 div.parent ,它的top margin与bottom margin发生重叠,这个重叠结果又与div.parent.second-parent的top margin发生重叠,因此页面最上方的空白处margin只有20px,这个数值能够经过查看div.parent.second-parent的margin获得(下图的橙色部分)。

由上图,咱们也能够看到,div.parent.second-parent并未与本身的第一个孩子box发生margin 重叠。

重叠margin计算

假设第一个box的top margin值为A,它的第一个子孩子的top margin值为B,二者margin重叠,重叠结果会按以下规则计算:

A,B均为正值,则取max(A, B)
A为负值,B为正值,则为B-|A|
A,B均为负值,则取0-max(|A|,|B|)

来个例子

为了更好的展现重叠结果,将html元素的top margin设为100px(注:html元素产生的是root box,不会发生margin重叠),同时去掉浏览器为body设置的margin。

<!DOCTYPE>
<html>
  <head>
      <style>
          html{
            margin-top:100px;
          }
          *{
            margin-top:0;
            margin-bottom:0;
          }
          .parent{
              width:100px;
              height:100px;
              background-color: #e6e96e;
          }
          .child{
              width:100%;
              height:100%;
              background-color: aquamarine;
          }
      </style>
  </head>
  <body>
    <div class='parent'>
        <div class='child'>haha</div>       
    </div>
 </body>
</html>复制代码

chrome展现以下:

例3:A为负值,B为正值

为div.parent及div.child加上margin-top

.parent{
              width:100px;
              height:100px;
              margin-top:-60px;
              background-color: #e6e96e;
          }
          .child{
              width:100%;
              height:100%;
              margin-top:10px;
              background-color: aquamarine;
          }复制代码

chrome里显示以下:

用inspect方式查看margin的范围:

能够看到,重叠margin值为html元素所设margin值的一半,即50px。它背后的运算过程是:10-|-60| = -50

例4:A, B均为负值

为两个div加上margin-top

.parent{
              width:100px;
              height:100px;
              margin-top:-10px;
              background-color: #e6e96e;
          }
          .child{
              width:100%;
              height:100%;
              margin-top:-50px;
              background-color: aquamarine;
          }复制代码

chrome显示以下:

再查看下margin范围

margin重叠的结果依然为50px,但背后的运算却不一样,0 - max(|-10|, |-50|) = 0-50 = -50

小结:只有垂直margin才可重叠,且参与的对象为同一个bfc的block-level box;重叠只有知足特定的条件才会发生;重叠的计算因margin值的正负状况而有所不一样。

相关文章
相关标签/搜索