margin 为负值是符合 W3C 标准的,完全没有兼容性问题,另外需要一提的是 padding 和 border 不支持负值。存在就是有意义的,那么负边距究竟有什么样的作用?
在普通文档流中的效果
那些没有脱离文档流的元素,其在页面中的位置是跟随者文档流的变化而变化的。看下面这幅图:
现在我们把上图中的块状元素、行内元素以及inline-block元素都设一个负边距 margin:-10px; 看看会发生什么:
注意到根据文档流的渲染顺序,前面的元素的会被后面的元素覆盖10px,另外顶部的块状元素也向上隐藏了10px。
由此可知,在文档流中,元素的最终边界是由margin决定的,margin为负的时候就相当于元素的边界向里收,文档流只认这个边界,不会管元素的实际尺寸是多少。
对元素宽度的影响
如果一个元素未设置宽度(或者width:auto),负边距能增加元素的宽度。
比如下图的黑灰色部分是一个块状元素,它没有设定宽度。它被包裹在一个宽度为400px,且水平居中的父元素中。
现在给这个元素的设一个 margin-right:-100px;
对浮动和绝对定位元素的影响
浮动元素或者绝对定位的元素会根据元素的边界来定位,而这个边界是由 margin 值来决定的,因此 margin 值的改变会影响元素的位置。
浮动定位
利用浮动元素的负边距,可以实现将写在后面的某个元素前置显示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <style> .ul > div { width: 300px; height: 300px; float: left; } .li1 { background-color: #B7FF7C; } .li2 { background-color: #F9715F; } .li3 { background-color: #83F2FB; margin-left: -450px; } </style> <div class="ul"> <div class="li1">list1</div> <div class="li2">list2</div> <div class="li3">list3</div> </div>
|
绝对定位
绝对定位的元素定义的top、right、bottom、left等值是元素自身的边界到最近的已定位的祖先元素的距离,这个元素自身的边界指的就是 margin 定义的边界,如果margin为负则它的边界是向里收的。利用这点,就有了经典的利用绝对定位来居中的方法。
1 2 3 4 5 6 7 8 9
| div { position: relative; width:500px; height:300px; top: 50%; left: 50%; margin: -150px 0 0 -250px; background-color: pink; }
|
实际应用
两栏等高布局
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 28 29 30 31 32
| <style> .box { overflow: hidden; }
.list1, .list2 { width: 300px; float: left; margin-bottom: -1000px; padding-bottom: 1000px; }
.list1 { background-color: #B7FF7C; }
.list2 { background-color: #F9715F; } </style> <div class="box"> <div class="list1"> <p>左列</p> <p>左列</p> <p>左列</p> </div> <div class="list2"> <p>右列</p> <p>右列</p> </div> </div>
|
列表去边
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
| <style> .box { width: 1200px; margin: auto; background-color: #FEB91E; }
.ul { overflow: hidden; margin-right: -20px; // 增大了容器宽度 }
.li { width: 386.66px; // 计算后的宽度 height: 300px; margin-right: 20px; background-color: #B7FF7C; float: left; } </style> <div class="box"> <div class="ul"> <div class="li">list1</div> <div class="li">list2</div> <div class="li">list3</div> </div> </div>
|