CSS理解之margin

作者: 徐国军_plus | 来源:发表于2017-07-31 17:20 被阅读116次

    1.margin与百分比单位

    Paste_Image.png Paste_Image.png

    2.margin重叠

    margin重叠通常特性:

    • 只发生在block水平元素(例如:p、div、list、item标签.....)
    • 只发生在垂直方向(margin-top/margin-bottom)

    margin重叠三种情况:

    • 相邻的兄弟元素
    • 父级和第一个/最后一个子元素
    • 空的block元素(自己和自己重叠)

    demo 1:
    1.相邻兄弟元素margin重叠

    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <title>JS Bin</title>
      <style>
        p{
      line-height:2em;
      margin:1em 0;
      background:#f0f1f3;
    }
      </style>
    </head>
    <body>
      <p>第一行</p>
      <p>第二行</p>
      </div>
    </body>
    </html>  
    

    兄弟元素的上下margin发生了重叠

    2.父级和第一个/最后一个子元素

    demo 1:

    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <title>JS Bin</title>
      <style>
        .father{
          height:200px;
          background:red;
        }
      </style>
    </head>
    <body>
      <div class="father">
        <div class="son">
          我是子元素
        </div>
      </div>
    </body>
    </html>
    
    Paste_Image.png
    当我们为子元素设置margin后:
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <title>JS Bin</title>
      <style>
        .father{
          height:200px;
          background:red;
        }
        .son{
          margin-top:80px;
        }
      </style>
    </head>
    <body>
      <div class="father">
        <div class="son">
          我是子元素
        </div>
      </div>
    </body>
    </html>
    
    Paste_Image.png
    对最后的子元素设置的margin-top:80px;等同于为父元素设置了margin-top:80px;(父元素的margin-top=0,最后的子元素的margin-top=80px,发生了外边距重叠),也等同于他们两个同时设置margin-top:80px;
    Paste_Image.png Paste_Image.png

    inline元素(内联元素,像图片、文字这样的东西)
    块状格式化上下文元素(BFC元素)

    同样可以利用父子margin重叠条件来去除margin重叠:

    demo 2:

    为父元素添加`overflow:hidden;`,使其变为状格式化上下文元素(BFC元素)
    
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <title>JS Bin</title>
      <style>
        .father{
          height:200px;
          background:red;
         overflow:hidden;
        }
        .son{
          margin-top:80px;
        }
      </style>
    </head>
    <body>
      <div class="father">
        <div class="son">
          我是子元素
        </div>
      </div>
    </body>
    </html>
    
    Paste_Image.png

    demo 2 :

    为父元素设置border-top:
    
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <title>JS Bin</title>
      <style>
        .father{
          height:200px;
          background:red;
          border:1px solid;
        }
        .son{
          margin-top:80px;
        }
      </style>
    </head>
    <body>
      <div class="father">
        <div class="son">
          我是子元素
        </div>
      </div>
    </body>
    </html>
    
    Paste_Image.png

    demo 2:

    为父元素和第一个子元素之间添加一个 (空格或文字、图片等内联元素)inline元素
    
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <title>JS Bin</title>
      <style>
        .father{
          height:200px;
          background:red;
        }
        .son{
          margin-top:80px;
        }
      </style>
    </head>
    <body>
      <div class="father">
         
        <div class="son">
          我是子元素
        </div>
      </div>
    </body>
    </html>
    
    Paste_Image.png

    去掉margin-bottom重叠与上面类似。

    3.空的block元素margin重叠:

    Paste_Image.png

    空的block元素发生margin重叠,也需要一些条件限制:

    Paste_Image.png

    去掉空的block元素的margin重叠也是利用上面的条件:

    Paste_Image.png

    3.margin重叠的计算规则:

    1、正正取大值:

    Paste_Image.png

    2、正负值相加:

    Paste_Image.png

    3、负负最负值(取绝对值大的):

    Paste_Image.png

    3、理解CSS中的margin auto

    首先理解margin atuo的作用机制 ,先看一些事实例子:

    1.元素有时候,就算没有设置width或height,也会自动填充外部容器

    例1:

    image.png
    图中是一个div元素,可以看到设置了背景色之后,它的宽度自动填满了它所在的容器。

    例2:

    image.png
    我们设置左右定位值left:0; right:0;,它的宽度同样自动填充填满了它所在的容器,只不过它的容器是它的第一个父级相对定位元素。

    以上两个例子是比较常见的,没有设置宽高也会自动填充所在容器。

    若刚才的两个例子,如果设置了width或heigth,自动填充特性就会被覆盖。


    上图宽度从填满整个所在的容器到宽度500px,这就产生了剩余空间,图中的剩余空白部分空间width=整个容器宽度-500px,而margin auto 就是 为了填充这个空白的尺寸设计的,这就是margin auto的作用。 image.png image.png

    总之一句话,auto就是用来分配。

    通过以上的例子,很多事情就很好理解了,比方说:

    1.为什么图片设置了margin:0 auto不水平居中?

    image.png

    如上图,设置了margin auto,图片为什么还是不居中呢?
    因为图片是inline水平的,它占据的空间并没有撑满整个容器,如果没有设置宽度值。所以它就不满足margin auto 用来填充剩余空间的条件,因为他根本就没有剩余空间。要想让它居中也很简单:

    image.png
    为图片设置display:block属性,这时就算没有为图片设置宽度,它也会占满整个容器,这时候在设置margin auto 它就会自动分配剩余空间。

    2.为什么明明容器定高,子元素也定高了,margin auto 0 无法垂直居中?

    image.png

    上图水平方向剧中了,但是垂直方向不剧中,父级元素高度有了,子元素高度也有了,为什么还是不垂直居中呢?

    因为他不满足占满整个容器这个条件,想一下,如果,没有为.son设置高度值,它之前满足占满整个容器这个条件吗?很显然不满足,也就没有剩余空间,所以设置height:100px margin auto不会垂直居中。

    还需要注意一点:用margin:auto来实现居中,它计算后的值必须是正直,比如说你的父容器宽度1000px,子元素宽度2000px,这时设置margin:auto它是不居中的。

    那么如何实现垂直方向上的剧中呢,方法很多不止一种:

    1.writing-mode与垂直居中:

    image.png

    更改流为垂直居中之后,内容会自动撑满垂直方向的高度。这时宽度不会自动撑满容器,所以宽度的水平居中就失效了。

    2.绝对定位元素实现垂直居中:

    image.png

    子元素设置了top:0;right:0;bottom:0;left:0;之后,没有设置宽高,absolute元素也自动填满了容器。

    image.png
    这时再设置宽高,自动填充就会被覆盖,如上图所示。这时上图蓝色旁边的空间尺寸就是被强制更改的尺寸,也就是margin:auto可以用来分配的尺寸空间,此时在设置margin:auto空间就被重新分配了,从而就实现了绝对定位元素的水平和垂直居中效果。但是这个特性只有IE8+以上的浏览器才支持。 image.png

    4.CSS margin负值定位

    1.margin负值下的两端对齐(主要利用了margin可以改变元素尺寸这一特性:正直变小,负值变大)

    image.png
    一个block水平元素,如果没有设置宽度值,我们通过设置margin可以改变它的尺寸:
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width">
      <title>JS Bin</title>
      <style>
      .box{
        width:1200px;
        margin:auto;
        background:orange;
      }
      .ul{
        overflow:hidden;
        margin-right:-20px;
      }
      .li{
        width:386.66666px;height:300px;background:green;float:left;margin-right:20px;
      }
      </style>
    </head>
    <body>
      <div class="box">
        <div class="ul">
          <div class="li">列表1</div>
          <div class="li">列表2</div>
          <div class="li">列表3</div>
        </div>
      </div>
    </body>
    </html>
    

    由于<div class="ul"></div>没有设置宽度,所以设置了margin-right:-20px;后,改变了它的宽度,增大了20px,变为1220px。这时我们再把li的宽度设置为计算好的386.66666px,就可以实现没有间隙的两端对齐。主要利用了margin负值增加它的空间

    image.png image.png

    5.CSS margin失效情形解析

    1. inline水平元素的垂直margin无效,前提:
    • inline水平元素是非替换元素,例如,不是<img>元素;
    • 正常书写模式,是正常的流(不是writing-mode这种重置它的书写模式)

    demo:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <style>
            
        </style>
    </head>
    <body>
        <span style="margin:233px;">margin: 0px;</span>
    </body>
    </html>
    

    可以看出它的垂直方向是没有margin的,是无效的。

    2.第二种常见的无效是margin重叠,比如你设置了margin-top当发现没有效果,这就是margin重叠带来的影响。

    3.display:table-cell与margin

    MDN:margin可以应用于任何元素,除了display为table的相关类型(不包括table-caption,table以及inline-table)。
    换句话说,如果这个元素的display属性是table-cell/table-row等类似这样的表格相关的声明,它的margin是无效的。

    demo:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <style>
            .table-cell{
                display: table-cell;
                margin: 100px;
            }
        </style>
    </head>
    <body>
        <span class="table-cell">span.table-cell</span>
        <div>
           <div class="table-cell">div.table-cell</div> 
        </div>
        
    </body>
    </html>
    
    Paste_Image.png

    可以看出设置的margin是无效的。

    但是对替换元素设置table-cell是可以发生作用的,但平时我们不会给替换元素设置table-cell,这是没有任何意义的,所以记住这点就行。

    4.position:absolute与margin,绝对定位元素非定位方向的margin值“无效”,定位方向的margin值是有效的。

    相关文章

      网友评论

        本文标题:CSS理解之margin

        本文链接:https://www.haomeiwen.com/subject/onpnkxtx.html