margin合并 margin无效的情形 margin:auto

margin是盒模型几个属性中一个非常特殊的属性。
如:只有margin不显示当前元素背景,只有margin可以设置为负值,margin和宽高支持auto,以及margin具有非常奇怪的重叠特性。


 



margin 重叠

 

margin重叠又叫margin合并,发生这种情况有两个前提

 

1、只发生在block元素上(不包括float、absolute、inline-block元素)

 

2、只发生在垂直方向上(不考虑writing-mode)


margin重叠的3种场景
1,相邻兄弟元素margin重叠

 <style>
        p{
            margin: 1em 0;
            background-color: orange;
        }
    </style>

    <p>第一行</p>
    <p>第二行</p>

 

 


2,父级和第一个 / 最后一个子元素     父子级的margin重叠又叫margin传递






3.  空块级元素的margin重叠







margin合并的计算规则
正正取大值    正负值相加    负负最负值

正正取大值

  <style>
        /* a 和 b 两个div之间的间距是50px  取最大值 */
        .a{margin-bottom: 50px;background-color: orange;}
        .b{margin-top:20px;background-color: pink;}

        /* father元素等同于设置margin-top:50px  取大的那个值*/
        .father{margin-top: 20px;background-color:orange;}
        .son{margin-top: 50px;background-color:pink;}

        /* c的外部尺寸是50px */
        .c{
            margin-top: 20px;
            margin-bottom: 50px;
            background: orange;
        }
     
    </style>

    <!-- 相邻兄弟合并 -->
    <div class="a">a</div>
    <div class="b">b</div>
<br/>
<br/>
<br/>

    <!-- 父子合并 -->
    <div class="father">父元素father
        <div class="son">子元素son</div>
    </div>
    <br/>
    <br/>
    <br/>

    <!-- 自身合并 -->
    <div class="c">c</div>

 
正负值相加

 <style>
        /* a 和 b 两个div之间的间距是30px  -20px+50px的计算值 */
        .a{margin-bottom: 50px;background-color: orange;}
        .b{margin-top:-20px;background-color: pink;}

        /* father元素等同于设置margin-top:30px  -20px+50px的计算值*/
        .father{margin-top: 20px;background-color:orange;}
        .son{margin-top: 50px;background-color:pink;}

        /* c的外部尺寸是30px  -20px+50px的计算值*/
        .c{
            margin-top: 20px;
            margin-bottom: 50px;
            background: orange;
        }
     
    </style>

    <!-- 相邻兄弟合并 -->
    <div class="a">a</div>
    <div class="b">b</div>
<br/>
<br/>
<br/>

    <!-- 父子合并 -->
    <div class="father">父元素father
        <div class="son">子元素son</div>
    </div>
    <br/>
    <br/>
    <br/>

    <!-- 自身合并 -->
    <div class="c">c</div>

 

负负最负值

 <style>
        /* a 和 b 两个div之间的间距是-50px  取绝对负值最大值 */
        .a{margin-bottom: -50px;background-color: orange;}
        .b{margin-top:-20px;background-color: pink;}

        /* father元素等同于设置margin-top:-50px  取绝对负值最大值*/
        .father{margin-top: -20px;background-color:orange;}
        .son{margin-top: -50px;background-color:pink;}
 
        /* c的外部尺寸是-50px  取绝对负值最大值*/
         .c{
            margin-top: -20px;
            margin-bottom: -50px;
            background: orange;
        } 
    </style>
</head>
<body>
    <!-- 相邻兄弟合并 -->
    <div class="a">a</div>
    <div class="b">b</div>
<br/>

    <!-- 父子合并 -->
 <div class="father">父元素father
        <div class="son">子元素son</div>
    </div> 
    <br/>

    <!-- 自身合并 -->
 <div class="c">c</div>

 

margin重叠的意义
如<h2> <p>   <ul>  默认全都是垂直方向的margin值,且单位都是em
字体默认是16px   如果字体增大,且margin是像素大小  ,则字体文字变大但间距不变,原本段落有秩序的阅读会让人窒息   em 是相对单位,无论字体变的多大字体都排版的很好
css世界的设计本意是图文信息展示,有了默认的margin值,我们的文章 新闻都不会挤在一起,垂直方向层次分明

兄弟margin重叠的意义 :和em类似,都是让图文信息的排版更加舒服 自然,可保证元素上下间距一致,无论是<h2>标题这种margin 偏大的元素,还是中规中距的<p>元素  可根据取值规则来取  如正正取大值
父子margin重叠的意义 :在页面中任何地方嵌套或直接放入任何裸<div>  都不会影响原来的块状布局
                                         有了父子margin合并,外面在嵌套一次<div>元素就跟没有嵌套一样,表现为margin-top:20px 就好像是设置在最外面的<div>元素上一样
                                        <div style="margin-top:20px ;"></div>
自身margin重叠的意义 :可避免不小心遗落或者生产的空标签影响排版和布局

 <style>
     /*
所以遇到列表 或者模块 全部都是保留上下margin设置
因为有margin合并,无需担心列表间距很大, 就是15px  

*/

     .list{
         margin-top: 15px;
         margin-bottom: 15px;
     }

<body>
    <p>第一行</p>
    <p></p>
    <p></p>
    <p></p>
    <p></p>
    <p>第二行</p>

    <!-- 最终效果和下面的一样  如果没有margin上面第一行 到 第二行 需要间隔很多行-->
    <p>第一行</p>
    <p>第二行</p>

 

 

 


margin :auto
元素没有设置width 或 height  会自动填充对应的方位 .元素如果设置了width 或 height ,自动填充的特性就会被覆盖

margin:auto 的计算规则
1,如果一侧定值,一侧auto ,则auto为剩余空间大小
2, 如果两边都是auto, 则平分剩余空间

例子:总剩余大小是100px ,其中margin-right :80px  那margin-left :auto  计算值就是剩余的20px

 <style>
   .father{
       width:300px;
       background-color:#ccc;
   }

   .son{
       width: 200px;
       height: 120px;
       margin-right: 80px;
       margin-left: auto;
       background-color: #cd0000;
   }
</style>

  <div class="father">
      <div class="son">tttt</div>
  </div>

 

 


margin 的初始值大小是0     ,块级元素实现右对齐  除了float:right   还可以用margin-left :auto
margin属性的auto计算 就是为了块级元素左中右对齐而设计的,
内联元素使用text-align  控制左中右对齐

  <style>
   .father{
       width:300px;
       background-color:#ccc;
   }

   .son{
       width: 200px;
       height: 120px;
   
       margin-left: auto;
       background-color: #cd0000;
   }
</style>


居中对齐  左右两侧同时设置 auto计算; 即可

  .father{
       width:300px;
       background-color:#ccc;
   }

   .son{
       width: 200px;
       height: 120px;
       margin-right:auto;
       margin-left: auto;
       background-color: #cd0000;
   }

 
有时 元素定高 容器定高,margin:auto 无法垂直居中
原因:触发margin:auto 计算有一个前提条件,就是width 或 height 为auto时,元素是具有对应方向的自动填充特性的
例如,把下面例子中 .son元素的height:100px 去掉, .son的高度会自动和父元素等高变成200px吗 ,显然不会 也就无法触发margin:auto 计算 也就无法垂直居中


margin实现垂直居中有 2种方法,
1,使用writing-mode改变文档流的方向  能垂直居中,但不能水平居中

  <style>
  .father{
       
       height: 150px;
       background-color:#ccc;
       writing-mode: vertical-lr;
   }

   .son{
       height: 100px;
       margin: auto;
       background-color: #cd0000;
   }
</style>

  <div class="father">
      <div class="son">111</div>
  </div>


2,绝对定位元素的margin:auto;  既能水平居中 也能垂直居中  这个IE8及以上浏览器才支持

    <style>

 .father{
     width:300px;
     height: 150px;
     position: relative;
     background-color: orange;
 }

 .son{
     /* 
     此时的.son 元素尺寸表现为, "格式化宽度和格式化高度"
     和<div>"正常流宽度" 一样 同属于外部尺寸
     也就是尺寸自动填充父级元素的可以尺寸
      */
     position:absolute;
     left: 0;
     top:0;
     right: 0;
     bottom: 0;
     background-color: pink;
     /* 
     宽高被限制,原本应该填充的空间 就被空余了出来
     这空余的空间就是margin:auto计算的空间
     这样水平和垂直方向同时的居中
      */
     width: 200px;
     height: 100px;
     margin:auto;

 }
</style>

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

 

 

 

绝对定位元素 的格式化高度 即使父元素height :auto 也是支持的



margin无效情形分析

1. inline 水平元素的垂直margin 无效 (水平可以) 2个前提

 

 

1> 非替换元素,例如:不是<img>元素

 

2> 正常的书写模式 (就是没有改变书写流方向的)
 <!-- 水平有位移 400px ,垂直没有效果 -->
    <div style="background-color: #ccc;">
        <span style="margin:400px;background-color: green;">margin:400px</span>
      </div>

 



2 . margin重叠






3. display : table-cell  / table-row 等声明的margin无效

但不包括table-caption table 以及inline-table 这些是可以通过margin来控制外边距的 )甚至::first-letter伪元素也可以解析margin

例: 无论内联元素还是水平元素 如 一旦设置了display :table-cell    那 margin无效

 <style>
        /* 
        无论块级元素 还是行内元素 一旦设置了 display: table-cell;
        在去设置margin 是无效的
         */
        span,div{
            background-color: orange;
        }
        .table-cell{
           display: table-cell;
            margin:0 100px;
        }

</style>

  <span class="table-cell">span.table-cell</span>
  <br/>
  <br/>
  <div class="table-cell">div.table-cell</div> 

 


如图片 和文字间隔开,设置table-cell元素 添加margin撑开间距  无效       只能给img 添加margin-right 来撑开间距 

 <style>
        .wrap1 img{
            float: left;
        }
       
       .wrap1 .d1{
           /* 通过给table-cell元素 添加margin撑开间距  无反应 */
           display: table-cell;
           margin-right: 30px;
       }

        /*
        通过给table-cell元素 添加margin撑开间距  无反应
        只能给img 添加margin-right 来撑开间距   
         */
       .wrap2 img{
            float: left;
            margin-right: 30px;
        }

       .wrap2 .d2{
           display: table-cell;
          
       }


</style>

<div class="wrap1">
    <img src="./img/bg-1.png"/>
    <div class="d1">无论块级元素 还是行内元素 一旦设置了 display: table-cell;
        在去设置margin 是无效的,无论块级元素 还是行内元素 一旦设置了 display: table-cell;
        在去设置margin 是无效的无论块级元素 还是行内元素 一旦设置了 display: table-cell;
        在去设置margin 是无效的</div>
</div>
<br/>
<br/>
<br/>
<div class="wrap2">
    <img src="./img/bg-1.png"/>
    <div class="d2">无论块级元素 还是行内元素 一旦设置了 display: table-cell;
        在去设置margin 是无效的,无论块级元素 还是行内元素 一旦设置了 display: table-cell;
        在去设置margin 是无效的无论块级元素 还是行内元素 一旦设置了 display: table-cell;
        在去设置margin 是无效的</div>
</div>

 


例外的 替换元素
图片 设置display:table-cell  且设置margin是有效果的

<style>
        .wrap1{
            background-color: orange;
        }
        .wrap1 img{
            display:table-cell;
            margin:100px;
        }
       
</style>

<div class="wrap1">
    <img src="./img/bg-1.png"/>
</div>
   

 
同样是替换元素如buttom 但与img 又有不同
设置display:table-cell      margin:15px  用js获取当前值的时候返回的是display:inline-block  margin:15px
也就是说按钮 在谷歌浏览器下 按钮永远是display:inline-block水平  这时的margin也是起作用的

替换元素设置 display:table-cell 在规范里是没有的,作为一种非定义行为。使得各个浏览器表现都有差异
FireFox :table-cell类型 inline-block的渲染行为
IE : table-cell类型 也是table-cell渲染行为
总之替换元素 tell-cell 能与margin发生作用的 (一般也不会给替换元素设置tell-cell 无任何意义)



4. position:absolute 与margin   注意:是加引号的无效

绝对定位元素 非定位方位的margin 是无效值 "无效" 也就是说定位方位的margin 是有效的

什么是非定位方位
图片设置了top:10% left:30% ,此时right 和 bottom都属于auto状态 ,如果设置margin-right margin-bottom 是无效 看不到定位变化的
图片设置了right:10% bottom:30% ,此时top 和 left都属于auto状态, 如果设置margin-left margin-top 是无效 看不到定位变化的

看似非定位元素是无效的,但绝对定位的margin值一直有效,只不过在特定的清境下 有着微妙的效果 ,不像普通元素那样,可以和兄弟元素插科打诨
 
虽对立方向的margin设置他的定位没有影响,影响是他的占位空间
 
图片默认方位定位是left top 即使不写 ,margin对他们来说也是有效的,
对于没有写的方位定位如 right bottom 定位没有影响,影响是他的占位空间
在特定的情景下就能观察出来 ,给父元素加relative


5,鞭长莫及导致的margin无效
105 不是无效而是不够大而已
 <div style="background-color: #f0f3f9;overflow: hidden;">
        <img src="./img/bg-1.png" style="float: left;" />
        <div style="margin-left:105px;">
          鞭长莫及导致的margin无效 因为图片左浮动,这里的margin是相对整个容器而言的,105px之前度是没反应的
        </div>
    
      </div>

 

<style>
        /* 
        margin-left:180px 是有效的,如果margin-left的值<=156 都是无效的
         */
        .box>img{
            float: left;
            width: 156px;
        }
        .box>p{
            margin-left: 180px;
        }
    </style>

<div class="box">
    <img src="./img/bg-1.png"/>
    <p>内容</p>
</div>

 

 




6,内联特性导致的margin无效

   <div style="background-color: #f0f3f9;height: 150px;width: 300px;margin: 100px auto;text-align: center;">
        <img src="./img/bg-1.png" style="margin-top: -90px;" />X
      </div>

 























































posted @ 2021-01-11 05:24  沁莹  阅读(588)  评论(0)    收藏  举报