margin属性

	之前看张鑫旭老师的《css世界》这本书感觉还不错,总结分享一些出来也方便自己查看~

对于padding,元素设定了width或者保持“包裹性”的时候,会改变元素可视尺寸;但是对于margin则相反,元素设定了width值或者保持“包裹性”的时候,margin对尺寸没有影响,只有元素是“充分利用可用空间”状态的时候,margin才可以改变元素的可视尺寸。
(Ps:包裹性具有包裹和自适应性两个特点,指 元素的尺寸只由内部元素决定,但是永远小于包含块容器的尺寸)
比方说,如下CSS:

    .father {
          width: 300px;
          margin: 0-20px;
        }

此时元素宽度还是300像素,尺寸无变化。因为只要宽度设定,margin就无法改变元素尺寸,这和padding是不一样的。
但是,如果是下面这样的HTML和CSS:

	<div class="father">
            <div class="son"></div>
        </div>
        .father { width: 300px; }
        .son {  margin: 0-20px; }

则.son元素的宽度就是340像素了,尺寸通过负值设置变大了,因为此时的宽度表现是“充分利用可用空间”。
或者这么说吧,只要元素的尺寸表现符合“充分利用可用空间”,无论是垂直方向还是水平方向,都可以通过margin改变尺寸。
1、margin的百分比值
和padding属性一样,margin的百分比值无论是水平方向还是垂直方向都是相对于宽度计算的。不过相对于padding, margin的百分比值的应用价值就低了一截,根本原因在于和padding不同,元素设置margin在垂直方向上无法改变元素自身的内部尺寸,往往需要父元素作为载体,此外,由于margin合并的存在,垂直方向往往需要双倍尺寸才能和padding表现一致。例如:

.box {
        background-color: olive;
        overflow: hidden;
    }
    .box > div {
        margin: 50%;
    }
   <div class="box">
        <div></div>
    </div>

结果.box是一个宽高比为2:1的橄榄绿长方形。是不是有点儿奇怪:50%+50%应该是100%,应该上下一样,是1:1的正方形,怎么最后是2:1的长方形呢?这就涉及下面margin合并的内容了。
2、什么是margin合并
块级元素的上外边距(margin-top)与下外边距(margin-bottom)有时会合并为单个外边距,这样的现象称为“margin合并”。
(1)块级元素,但不包括浮动和绝对定位元素,尽管浮动和绝对定位可以让元素块状化。
(2)只发生在垂直方向,需要注意的是,这种说法在不考虑writing-mode的情况下才是正确的,严格来讲,应该是只发生在和当前文档流方向的相垂直的方向上。由于默认文档流是水平流,因此发生margin合并的就是垂直方向。
3、margin合并的3种场景
margin合并有以下3种场景。
(1)相邻兄弟元素margin合并。这是margin合并中最常见、最基本的,例如:

p { margin: 1em 0; }
    <p>第一行</p>
    <p>第二行</p >

则第一行和第二行之间的间距还是1em,因为第一行的margin-bottom和第二行的margin-top合并在一起了,并非上下相加。
(2)父级和第一个/最后一个子元素。我们直接看例子,在默认状态下,下面3种设置是等效的:

    <div class="father">
            <div class="son" style="margin-top:80px; "></div>
        </div>

        <div class="father" style="margin-top:80px; ">
            <div class="son"></div>
        </div>

        <div class="father" style="margin-top:80px; ">
            <div class="son" style="margin-top:80px; "></div>
        </div>

那该如何阻止这里margin合并的发生呢?
对于margin-top合并,可以进行如下操作(满足一个条件即可)
• 父元素设置为块状格式化上下文元素;
• 父元素设置border-top值;
• 父元素设置padding-top值;
• 父元素和第一个子元素之间添加内联元素进行分隔。
对于margin-bottom合并,可以进行如下操作(满足一个条件即可):
• 父元素设置为块状格式化上下文元素;
• 父元素设置border-bottom值;
• 父元素设置padding-bottom值;
• 父元素和最后一个子元素之间添加内联元素进行分隔;
• 父元素设置height、min-height或max-height。
4、margin合并的计算规则
我把margin合并的计算规则总结为“正正取大值”“正负值相加”“负负最负值”3句话。下面来分别举例说明。
(1)正正取大值。如果是相邻兄弟合并:

   .a { margin-bottom: 50px; }
        .b { margin-top: 20px; }
        <div class="a"></a >
        <div class="b"></a >

此时.a和.b两个<div>之间的间距是50px,取大的那个值。
如果是父子合并:

    .father { margin-top: 20px; }
        .son { margin-top: 50px; }
        <div class="father">

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

此时.father元素等同于设置了margin-top:50px,取大的那个值。
如果是自身合并:

  .a {
          margin-top: 20px;
          margin-bottom: 50px;
        }
        <div class="a"></div>

则此时.a元素的外部尺寸是50px,取大的那个值。
(2)正负值相加。如果是相邻兄弟合并:

 .a { margin-bottom: 50px; }
        .b { margin-top: -20px; }
        <div class="a"></a >
        <div class="b"></a >

此时.a和.b两个<div>之间的间距是30px,是-20px+50px的计算值。
如果是父子合并:

 .father { margin-top: -20px; }
        .son { margin-top: 50px; }
        <div class="father">
          <div class="son"></div>
        </div>

此时.father元素等同于设置了margin-top:30px,是-20px+50px的计算值。
如果是自身合并:

   .a {
          margin-top: -20px;
          margin-bottom: 50px;
        }
        <div class="a"></div>

则此时.a元素的外部尺寸是30px,是-20px+50px的计算值。
(3)负负最负值。如果是相邻兄弟合并:

    .a { margin-bottom: -50px; }
        .b { margin-top: -20px; }
        <div class="a"></a >
        <div class="b"></a >

此时.a和.b两个<div>之间的间距是-50px,取绝对负值最大的值。
如果是父子合并:

     .father { margin-top: -20px; }
        .son { margin-top: -50px; }

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

此时.father元素等同于设置了margin-top:-50px,取绝对负值最大的值。
如果是自身合并:

 .a {
          margin-top: -20px;
          margin-bottom: -50px;
        }
        <div class="a"></div>

则此时.a元素的外部尺寸是-50px,取绝对负值最大的值。
好啦,上面内容只是书里的冰山一角,分享一下~

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值