CSS 盒模型中,margin 是我们老熟悉的一个属性了, 它的负值你用过吗? 你知道 margin 负值的秘密武器吗?我们一起看看吧!

1、带竖线分隔的横向列表(例如:网站底部栏目)

传统的分隔符是使用 “|” 来实现的,弊端显而易见,不利于表现与结构的分离,同时增加了后台输出时的判断工作。所以我们采用 border-left 左边框来模拟分割线,然后通过 margin-left:-1px 隐藏掉第一个列表项的边框,父元素设置 overflow:hidden 来隐藏溢出部分,这样完美达到首尾无分割线的要求。

2012-5-4 更新

实际测试中发现 iphone safari 设置 margin 负值 =border-widht 并不能很好的隐藏,还有约 0.5px 的细线,iPad 没测不知道如何?修复方法如下:

/*  修复 iphone safari 不能完全隐藏边框的 bug  */
@media  screen and (max-device-width: 480px){.nav-list-item { margin-left:-2px;}
.ui-tab-trigger-item {margin-bottom:-2px;}
}

2、带底部分割线的竖向列表(例如:新闻列表)

原理同横向列表相同,需要注意的是 margin 负值在 IE 中的层级 bug,详细参见:IE6 IE7 IE8(Q) 负边距 (margin) 导致元素溢出 hasLayout 容器时显示异常,得到的最终解决方案是用 zoom:1 确保触发 hasLayout,然后设置 position:relative。

3、两栏、三栏自适应布局

曾经有这样一个经典的需求:

1)两栏抑或三栏布局,主体自适应宽度;

2)一个或两个侧边栏固定宽度;

3)主体部分 xhtml 结构在最前面(网速慢时可以优先显示,对 SEO 有利)

4)自适应高度,且不影响等高;

5)兼容 IE6+,firefox,chrome,opera。

于是乎 margin 负值便大放光彩,首先是国外出现的圣杯布局,掀起一股 margin 负值热潮。紧接着在栅格化布局大行其道的淘宝,玉伯大湿进一步利用 margin 负值,创造了同一种 xhtml 结构,两栏或三栏位置通过 css 任意调整的布局,玉伯美其名曰:双飞翼布局–比翼双飞,像鸟儿翱翔蓝天一样自由。(双飞翼布局完整 demo) 至此,margin 负值在布局之路上配合 float 妹子,已经发挥得淋漓尽致。

优雅的 demo

4、多栏等高

正如上面所说,有时候我们还希望多栏等高,使页面看起来更美。于是便有了经典的 padding-bottom:9999px;margin-bottom:-9999px;先通过 padding 把盒子扩展到足够高,然后通过 margin 伪娘把它给拉回来,最后父元素设置 overflow:hidden 隐藏溢出,这样多栏布局中就会以最高栏为其他栏的视觉高度。

当然万物没有完美的,这种等高方法的弊端如下:

1)当高度超过 9999px 时候失效,当然一般高度不会超过这个,也可以设置为最大值 32767px(为啥,因为 int 的最大值就是 32767,超过这个数值会以最大值计算)

2)无法设置底部边框

其他的就不多说了,以后会专门写一篇多栏等高的文章,详细介绍各种方法的利弊,大家按需使用。

5、产品列表

有时候会要求一行产品列表左右两边是没有空隙的,中间有一定的间距;比如我们设置了 li {margin-right:20px;} 那么最后一个肯定也是有 20px 的间距的,怎么办?我们可以通过设置父元素(比如 ul)margin-right:-20px; 来扩展容器的宽度,然后把整体的宽度加在最外层的元素上,此处如果把宽度加在了父元素上(比如 ul)会导致此方法失效,因为宽度定死了,margin 负值便无法扩展容器的宽度了。

6、已知高宽元素水平垂直居中

对于水平居中当然我们有更好的方法,块级元素设置 margin-left:auto; margin-right:auto; 行内元素可以使用 text-align:center 。垂直居中就不多说了,深入研究又是一篇文章了!

7、模拟表格线

上面的布局通过表格当然很好实现,但是前几天 点点 老兄说这个结构要用 ul 无序列表来写,第一时间便想到了用 inline-block 和 margin 负值来做了。实际中问题还是挺多的,遇到了 IE 宽度奇偶 BUG。国外大神的解决方法是 body{margin-left:1px;},但是发现治标不治本,IE6 和 7 还是坑爹。于是想到了把 li 的宽度设置为小数 width:49.99%; 虽然 IE6-7 右边框还是有一点点错位,但是视觉上基本可以了,无需刻意追求 1px 的差异。

然后 点点 老兄又说了:如果用 CSS3 如何写呢?那么自然想到了 columns 属性,研究发现这爷们居然也有 IE 的奇偶癖好了,两列的时候,li 如果是奇数除了 chrome,其他现代浏览器都越好似的,一起错位了。

这个问题我们下回分解,margin 负值能很好的解决这样的需求了,兼容性也不错。

8、tab 选项卡

最后说说 demo 中的整体结构选项卡中同样用到了 margin 负值,选中状态下,我们需要隐藏掉底部边框。

在选项卡中,遇到了 firefox box-shadow 导致 outline 扩展的 bug,解决方案见 demo。

好啦,作为云路科技开篇博文,说的似乎有点多了,demo 是穿插在 选项卡 里面的,大家如果有不明白的先用 firebug 看看吧

本文地址 https://shaoshilei.com/2014-01/margin-negative-a-secret-weapon.html