你不知道的margin

选项卡
当了一回标题党了(震惊!99%的人都不知道XXXX <( ̄︶ ̄)>),本文是对我所了解的margin的一些说明,希望能给大家带来些许有意思的知识。
margin和padding是css中应用最多的了吧,没有之一,这两兄弟帮我们解决了一个又一个的布局问题。好了,来看看margin的一些应用吧。

何为margin

来看看官方的说明:

边界,元素周围生成额外的空白区。“空白区”通常是指其他元素不能出现且父元素背景可见的区域。——CSS权威指南

CSS 边距属性定义元素周围的空间。通过使用单独的属性,可以对上、右、下、左的外边距进行设置。也可以使用简写的外边距属性同时改变所有的外边距。——W3School

margin就是盒模型的外边距,它最基本用途就是控制元素周围空间的间隔,把一个个元素分隔开来。margin始终是透明的。

垂直外边距合并问题

外边距合并指的是,当两个垂直外边距相遇时,它们将形成一个外边距。合并后的外边距的高度等于两个发生合并的外边距的高度中的较大者。

其实这个问题一般常见于父元素和子元素,第一个子元素的margin-top会顶开父元素与父元素相邻元素的间距,其原因是第一个子元素的margin-top和父元素的margin-top没有东西与其分隔开来,导致了两者的margin-top重合了。
简单点说就是:父元素的第一个子元素的上边距margin-top如果碰不到有效的东西如border或者padding将两者的margin-top阻隔,就会不断一层一层的找自己祖先元素的麻烦,直到有隔断的东西,或者找到了最终的父元素。
当然解决办法太多了:

  1. 其子元素浮动、inline-block、绝对定位;
  2. 父元素建立BFC(float(除了none)、overflow(除了visible)、display(table-cell/table-caption/inline-block)、position(除了static/relative)),大家常用的overflow: hidden;来解决就是这个做法。
  3. 父元素和子元素隔断两者的margin-top,也就是父元素添加:after,padding-top,border-top,总之能隔断就行

负margin

首先盒模型的大小等于盒子的border+padding+正margin,负margin是不会影响其大小的。
那么负margin有啥用呢?负margin主要是让元素脱离自身的位置发生移动,当元素margin的top和left是负值时会引起元素的向上或向左位置移动(当然元素移动了,会导致后面的元素一起动)。而当元素margin的bottom和right是负值时会影响右边和下边相邻元素的参考线(比如margin-bottom: -100px;会让它下面挨着的元素上移100px)。
负margin

负margin的应用:
  1. 悬停图片放大
    其实这个东西有很多人是用transform: scale()来做的,让图片放大,但是这个其实也可以用负margin来做,让img宽高变大然后通过负margin让其中心位置不变,当然这个兼容性特好,不追求动画效果的话ie7都没啥问题的。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    <div class="box">
    <img src="http://ouzdb04w7.bkt.clouddn.com/image/2017/10/27/timg1.jpg" alt="" class="pox"/>
    </div>
    .box{
    margin: 50px;
    width: 200px;
    height: 200px;
    border: 1px solid #000;
    overflow: hidden;
    }
    .pox{
    width: 200px;
    height: 200px;
    background-color: red;
    transition: all 0.4s ease;
    vertical-align: top;
    }
    .box:hover .pox{
    margin: -25px 0 0 -25px;
    width: 250px;
    height: 250px;
    }
  2. 选项卡
    负margin是可以用作于特殊样式的选项卡的,而且负margin可以实现border重叠,也就是两个紧挨着的1px border可以用margin-left:-1px让其重叠,变成1px的border,下面的选项卡就只是使用负margin达到了效果,当然还有很多种方式可以实现,但是这种方式简单快捷,ie7什么的不在话下。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    ul.list{
    height:38px;
    line-height: 38px;
    overflow: hidden;
    list-style: none;
    background: #f8f8f8;
    margin-bottom: -1px;
    }
    #list li{
    float: left;
    width: 99px;
    text-align: center;
    border-left: 1px #e5e5e5 solid;
    border-right: 1px #e5e5e5 solid;
    margin-left: -1px;
    cursor: pointer;
    }
    #list .active{
    position: relative;
    background-color: #FFf;
    }
  3. 绝对定位效果
    负margin是可以达到绝对定位的视觉效果的,但是有要注意:负margin的重叠的话背景会被正常元素覆盖,ie7则相反。

    特大喜讯

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    .mybox{
    width: 200px;
    height: 112px;
    }
    .mybox img{
    width: 100%;
    height: 100%;
    }
    .mybox span{
    top: -100px;
    display:block;
    color: #FFF;
    text-align:right;
    margin-right: 10px;
    background-color: red;
    }
  4. 自适应布局
    当然,负margin最出名的应用还是自适应上的。
    双飞翼布局:

    header
    main
    left
    right

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    .wrapper {color:#fff;}
    .col {float: left;}
    .header {height: 50px;background-color: #666;color:#fff;line-height: 50px;text-align: center;}
    .main {width: 100%;background-color: #555;}
    .main-wrap {margin: 0 100px 0 100px;height: 200px;}
    .left {width: 100px;height: 200px;margin-left: -100%;background-color: #999;}
    .right {width: 100px;height: 200px;margin-left: -100px;background-color: #999;}
    .footer {height: 50px;background-color: #666;color:#fff;}
    .clearfix::after{content: "";display:block;clear:both;visibility:hidden;height:0;overflow:hidden;}
    <div class="myheader clearfix">
    header
    </div>
    <div class="wrapper clearfix">
    <div class="main col">
    <div class="main-wrap">
    main
    </div>
    </div>
    <div class="left col">
    left
    </div>
    <div class="right col">
    right
    </div>
    </div>
    <div class="footer">footer</div>

圣杯布局:

header
main
left
right

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
.wrapper2 {padding: 0 100px 0 100px; color:#fff;}
.col2{position: relative;float: left;}
.myheader {height: 50px;background-color: #666;color:#fff;text-align: center;line-height: 50px;}
.main2 {width: 100%;height: 200px;background-color: #555;}
.left2 {width: 100px;height: 200px;margin-left: -100%;left: -100px;background-color: #999;}
.right2 {width: 100px;height: 200px;margin-left: -100px;right: -100px;background-color: #999;}
.footer {height: 50px;background-color: #666; color:#fff;}
.clearfix::after{content: "";display:block;clear:both;visibility:hidden;height:0;overflow:hidden;}
<div class="myheader clearfix">
header
</div>
<div class="wrapper2 clearfix">
<div class="main2 col2">
main
</div>
<div class="left2 col2">
left
</div>
<div class="right2 col2">
right
</div>
</div>
<div class="footer">footer</div>

margin配合定位绝对居中

margin还可以配合绝对定位实现绝对居中的功能


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.box{
width: 400px;
height: 400px;
background-color: #e5e5e5;
position: relative;
}
.pox{
width: 100px;
height: 100px;
background-color: #000;
margin: auto;
position: absolute;
top: 0; left: 0; bottom: 0; right: 0;
}
<div class="box">
<div class="pox"></div>
</div>

ok,这就是我所认识的margin,可能有所遗漏,不过暂时也记不得了,后面再补充,下一篇准备padding吧。
本文代码地址:链接