总结:margin负值的影响:
当元素(块级元素)没有设置宽度时:margin负值会增加元素的宽度,当设置宽度时,margin负值只会影响元素的位置。
就是负的边距好像能减小元素在文档流中的尺寸一样,但事实上,它的尺寸大小并没变,只是文档流在计算元素位置的时候,会 认为负边距把元素的尺寸减小了,因为位置也就发生变化了。这只是打个很形象的比喻,帮助大家理解一下。
还要注意的是,文档流只能是后面的流向前面的,即文 档流只能向左或向上流动,不能向下或向右移动。比如,一 个没有设定高度的块状元素,其高度是自动的,具体来说就是由它里面的文档流最后的位置决定的。
假设它里面有一个出于文档流中的子元素,高度为100px; 那这时这个父元素的高度就等于子元素的高度100px了,如果子元素继续增高,那么父元素也会跟着增高。
可是如果这时子元素设一个负的margin- bottom,比如-20px,因为负边距会影响到文档流,本来文档流的高度是从父元素的最顶端到子元素的最底端这段高度,现在子元素有一个 margin-bottom:-20px;就相当于文档流要向上退后20px,这样整个文档流的高度就减少了20px了,那么父元素的高度也会跟着减少 20px。
在标准浏览器中,这还需要父元素拥有一个overflow:hidden的属性才能办到,在IE浏览器中则不需要。所以以前所说的多列等高布局就是利用这个原理来实现的
总之一句话,在文档流中,元素的最终边界是由margin决定的,margin为负的时候就相当于元素的边界向里收,文档流认的只是这个边界,不会管你实际的尺寸是多少。
左和右的css负边距对元素宽度的影响
负边距不仅能影响元素在文档流中的位置,还能增加元素的宽度!
这个作用能实现的前提是:该元素没有设定width属性(当然auto是可以的)。
比如下图的黑灰色部分是一个块状元素,它没有设定宽度。它被包裹在一个宽度为400px,且水平居中的父元素中。
现在给这个元素的设一个margin-right:-100px;
我们看到它的宽度的确变长100px;然后再给它设一个margin-left:-100px;
我们看到它变得更宽了。
负的margin会改变元素的宽度,这的确很让人费解,如果说负边距会改变元素在文档流中的位置还是很好理解的话,那改变宽度这种现象还真的蛮让人不可思议的。。
左和右的css负边距对元素宽度的影响
负边距不仅能影响元素在文档流中的位置,还能增加元素的宽度!
这个作用能实现的前提是:该元素没有设定width属性(当然auto是可以的)。
比如下图的黑灰色部分是一个块状元素,它没有设定宽度。它被包裹在一个宽度为400px,且水平居中的父元素中。
现在给这个元素的设一个margin-right:-100px;
我们看到它的宽度的确变长100px;然后再给它设一个margin-left:-100px;
我们看到它变得更宽了。
负的margin会改变元素的宽度,这的确很让人费解,如果说负边距会改变元素在文档流中的位置还是很好理解的话,那改变宽度这种现象还真的蛮让人不可思议的。
1 那这货有什么用途呢?我就举一个例子吧。
想 要创建上图中黑框内的几个元素按顺序排下来,中间带些间隔的布局要怎么做?,当然最简单省事的方法就是利用浮动了。我们把黑框里面的子元素向左浮动,然后 设一个合适的margin-right,是不是就办到了呢?但因为外边黑框的宽度是固定的,就是里面四个子元素的宽度加上三列间隔的宽度,所以靠近右边边 界的子元素就不应该有正向的margin-right了,否则这一行就只能容纳三个子元素了。有人说那这还不简单,给靠近右边界的那些子元素加一个 class,把它的margin-right设为0不就行了。这当然可以,但如果这些子元素是在模板中通过循环动态输出的,那在循环的时候还得判断哪些子 元素是靠近右边边界的,如果是就加上一个class。这样做的话是不是就有点麻烦了?所以解决办法是加大子元素的父容器的宽度,让它能够容纳一行中有四个 子元素加上四列间隔的宽度,然后最外面的的黑框的那个容器设一个overflow:hidden就行了。上面说了负的左右边距能加大元素的宽度,所以给子 元素的父容器设一个合适的负的margin-right就可以了。当然你也可以直接在css中把子元素的父容器的宽度设宽一些,举这个例子只是为了说明负 边距也是一种方法。看下完整的代码:
<style>
body,ul,li{ padding:0; margin:0;}
ul,li{ list-style:none;}
.container{ height:210px; 460px; border:5px solid #000;}
ul{ height:210px; overflow:hidden; margin-right:-20px;}/*一个负的margin-right,相当于把ul的宽度增加了20px*/
li{ height:100px; 100px; background:#09F; float:left; margin-right:20px; margin-bottom:10px;}
</style>
<div class="container">
<ul>
<li>子元素1</li>
<li>子元素2</li>
<li>子元素3</li>
<li>子元素4</li>
<li>子元素5</li>
<li>子元素6</li>
<li>子元素7</li>
<li>子元素8</li>
</ul>
</div>
2 css负边距对绝对定位元素的影响
css绝对定位的元素定义的top、right、bottom、left等值是元素自身的边界到最近的已定位的祖先元素的距离,这个元素自身的边界指的就 是margin定义的边界,所以,如果margin为正的时候,那它的边界是向外扩的,如果margin为负的时候,则它的边界是向里收的。利用这点,就 有了经典的利用绝对定位来居中的方法:
但该方法的缺点是必须要知道要居中元素的高度和宽度
3. 图片与文字对齐问题
当图片与文字在一起,往往都是不对齐的,因为图片和文字默认是底部对齐。当图片较小比较明显,使用vertical-align:middle;
对齐,在firefox,chrome下能达到理想效果,但是IE下还是有点别扭。
使用margin负值能在每个浏览器上显示完全一致。img标签支持margin四个方向的正的和负的定位。
一般使用img标签来显示图标,要与文字对齐达到理想的效果,可以设置img{margin:0 3px -3px 0;}。
4. 隐藏首(末)边框
本着结构尽量简洁,样式代码尽量少,减少对js的依赖的原则,我们可以用样式来实现列表项头尾无边框的效果,而无需额外设置诸如<li class=”last”>最后一个</li>
样式部分:
<style type=”text/css”>
ul{
margin:30px;
padding:0;
300px;
}
li{ list-style:none;}
/** 横排模式 **/
.cross{
overflow:hidden;
zoom:1;
} /** overflow:hidden隐藏最上边border,IE6需要zoom:1 **/
.cross li {
float:left;
padding:0 11px 0 10px;
border-left:1px solid #AAA;
margin-left:-1px;
} /*margin负值隐藏掉最左边边框*/
/*竖排模式*/
.vertical {
overflow:hidden;
position:relative;
zoom:1;
} /*IE下子容器如果包含属性position:relative,则父容器失效(IE bug),所以也需要设置父容器position:relative解决,IE6需要zoom:1来触发haslayout*/
.vertical li{
border-top:1px dashed #CEE1EE;
padding:5px 0;
position:relative;
margin-top:-1px;
} /*竖排margin负值IE6不兼容,改为positon方式处理,与margin负值原理相同*/
</style>
结构部分:
<ul class=”cross”>
<li>tab1-1</li>
<li>tab1-2</li>
<li>tab1-3</li>
<li>tab1-4</li>
</ul>
<ul class=”vertical”>
<li>这里是一条信息</li>
<li>这里是一条信息</li>
<li>这里是一条信息</li>
<li>这里是一条信息</li>
<li>这里是一条信息</li>
</ul>
5.页面上实现css sprite背景定位效果
使用img定义margin的负值实现类似background-position效果。此方法能减少一个页面请求数,但是有违样式与布局分离的原则,因此不推荐使用。
ps:
使用margin负值在IE6/IE7下的bug:有一部分被隐藏掉了
<div style=”height:120px;120px; border: 5px solid #888; “>
<div style=”background-color:#CEE1EE;margin-top: -10px;position:relative;zoom:1″>
<a href=”http://fed.renren.com/”>人人前端测试</a></div>
</div>
解决方法:添加position:relative; zoom:1;
总结:如果box没有设置宽度可以通过设置margin-left margin-right 负值来扩大box的宽度,如果设置了宽度,将只会改变box的位置,和影响后续元素的位置,不能改变box的宽度
负margin用作布局效果的确有其独到之处,但自身也有一个小的缺陷,即如果内部最后一个子元素使用负margin上移后,由于父元素是其边距元素,其实际高度由于内部子元素上移也会跟着变小。
解决方式就是设置一个最小高度,最小高度值为较小的固定元素高度(此例即为左边固定的图片高度),就可彻底解决负margin上移影响父元素高度Bug。
来自:
http://www.hicss.net/i-know-you-do-not-know-the-negative-margin/
http://www.cnblogs.com/2050/archive/2012/08/13/2636467.html
http://www.duidea.com/2012/1108/1570.html