0%

负margin的应用

负margin的应用,现在在许多地方都能看到,个人认为它是CSS进阶之路上不可不了解的一个东西,巧妙的使用负margin可以解决很多问题

海玉的一篇博客我知道你不知道的负Margin提到了负margin的理论:

负margin理论:

在说明什么是负margin之前,你得清楚margin是个啥么玩意,如果还不清楚可以先阅读本人的前一篇文章《不要告诉我你懂margin》,预补下知识,回头再读这篇文章,相信俩篇文章都能给你带来不少的收获。

为了形象、易懂的解释负margin,我们将引入W3C上没有的参考线的说法。何谓参考线?参考线就是 margin移动的基准点,此基准点相对于box(自身)是静止的。而margin的数值,就是box相对于参考线的位移量。

一个完整的margin属性是这么写的margin: top right bottom left;(eg: margin:10px 20px 30px 40px)。在margin属性中一共有两类参考线,top和left的参考线属于一类,right和bottom的参考线属于另一类。top和left是以外元素为参考,right和bottom是以元素本身为参考。margin的位移方向是指margin数值为正值时候的情形,如果是负值则位移方向相反。

marginMoveDefault

上面段文字和图片或许挺难理解,我们来看实际代码:


{margin:0; padding:0;}
.wrap{width:400px; border:5px solid #aaa;}
.example{width:200px; height:200px; background:#CCCCFF;}
.normal{width:200px; height:200px; background:#CCE8CF;}
/
添加或者注释掉下面的margin属性,查看前后差别
.example{margin:-10px 20px -30px 40px;}
*/

来分析这段代码,example元素下方有一相邻元素normal(注:这里分析的是添加和删除margin后的example元素,normal元素仅作为example元素前后效果的参照)。

根据上文的参考线原理margin:-10px(top) 20px(right) -30px(bottom) 40px(left); 上-10px和左40px将以外元素为参考,所谓外元素就是本元素的边界元素(再白话点的解释就是元素的紧邻元素,这里涉及到containing block知识,可自行网上搜索)。example元素上边和左边的边界元素即为wrap父元素,wrap父元素为基准点,example的margin-top为-10px,想象下如果这里margin-top为+10px会什么情况,没错如果为+10px,example元素相对于wrap父元素边缘为基准,那么example元素会同wrap父元素10px产生间隙边距,那么反过来,margin-tip:-10px;还是与wrap父元素边缘为基准,反过来向上推10px的距离位置。example元素的margin-left为40px,这里就按照正常逻辑相隔40px边距,同理如果为-40px,那么就是反方向向左推进40px的距离位置。

再来看example元素的margin-right和margin-bottom,由上文得知这俩个值是以元素本身为参考。什么叫以元素本身为参考呢,确切含义是指以自身为参考来影响周围元素的位置(实质即为影响下边和右边相邻元素的参考线)。这里的margin-bottom为-30px,对于其自身位置没有任何变化,但是对于其下方元素normal元素产生了极大的影响,因为normal元素的上边界元素即为example元素,根据example元素边界来判定自身位置,想象下如果example元素margin-bottom为+30px,那么example元素将隔开下方的normal元素,反之为-30px,下方normal元素由于example参考线内凹,导致了normal元素自个儿身不由己的被“提”了上去了。这就是以自身为参考影响周围元素位置的含义。

这里梳理一下规律,当margin四个值都为正数值的话,那么margin按照正常逻辑同周围元素产生边距。当元素margin的top和left是负值时会引起元素的向上或向左位置移动。而当元素margin的bottom和right是负值时会影响右边和下边相邻元素的参考线。如果你再想深入了解参考线理论的话你也可访问由浅入深漫谈margin属性这篇文章。

看下面的一个常见例子,#main的宽度是700px,图片大小200*250,相互之间的间距30,然后三张图片居中,这是个非常常见的需求


#main{width:700px; background: #eee;}
ul{zoom:1;margin-right:-50px;margin-left:16px;}
ul::after{
content: ‘’;
display: table;
clear: both;
line-height: 0;
}
li{float:left; margin:0 30px 0 0; width:200px; height:250px; background: #ff0;}

demo1链接:margin_demo1.html

关键的代码就是ul的margin-right:-50px;

再来看第二个例子,也是常用的一种情况,左边是一个预览图片,右边附上文字或者介绍


#block{
width:300px;
padding:20px 20px 20px 70px;
zoom:1;
border:1px solid #eee;
}

#block::after{
    display: table;
    line-height: 0;
    content: "";
    clear: both;
}
#block a{
    float: left;
    width: 60px;
    height: 60px;
    margin: 0 0 0 -70px;
}
#block p{
    line-height: 20px;
}</code></pre>

这样写的好处是可以自适应宽度,在很多情况下可以用到,#block要清浮动

负margin的例子很多,如http://www.time.com/time/的导航,巧妙的使用li和a的负margin实现了任意高度的分隔线效果,我写沪江网新版首页的选项卡Tab的时候就有参考它的代码,并兼容了Ie6、7浏览器。