2015-04-22 时候写的老文,因为希望引用所以拿了出来。
那天被一个同学问了一个问题,三列的div,要求父div的高度和三个div的高度都和三个中字数最多,也就是高度最高的那个一样高。试了试才发现确实有问题。在网上查到了解决方案,运用了一些很奇葩的代码,贴上来和大家分享。点击这里查看demo。
之后仔细的百度了一下,发现了这么一个叫做内外补丁负值法的东西。不过百度内外补丁负值法,出来的都是同一篇文章,感觉不是一个真正的术语。还是把这篇文章贴出来,有兴趣的同学可以看看。
在这个解决方案中,又涉及到了传说中的负margin。之前在阿里笔试也有一个三栏布局的题,其中一个解决方案用的也是左右的负margin。深入研究之后又发现了圣杯布局、双飞翼布局等很多示例,确实要好好研究负边距这个东西了。
之后参考了CSS布局奇淫巧计之-强大的负边距这篇文章,里面做了实际的demo,总结成一点就是,css中盒子真正的边界,是由margin决定的,而且margin可以很霸气的通过负值来压缩实际宽度(padding不允许负值)。
有了这一点认识之后,很多问题都解决了。就比如说上边那个demo,通过padding-bottom:10000px;
创建了一个足够高的盒子,再通过margin-bottom:-10000px;
抵消这部分盒子在文档流中的实际占位(但是实际还是存在的,所以就会按照第一个的高度等高),再给父级元素加上overflow:hidden
,去掉多余的高度,效果就实现了。
同时,在上边那篇文章里还解决了一个布局的问题,就是多列间有margin,但是两边没margin的问题(听不懂我中文的直接点这里看demo吧,我知道自己说的不好)。之前一直是循环到一行最后一个的时候给加上一个class,现在可以免了,就比如我在demo里用margin-right:10px;
给li之间创建一个间隔,然后用marigin-rignt:-10px;
强行加宽ul,使四个li能在一行,但是ul外content的宽度设为width:830px;
(4200px+310px;),这样就可以正确的居中了。
之后简单说下圣杯布局和双飞翼布局吧,他们主要是为了解决三栏问题。三栏问题的研究可以看看张鑫旭老师的博客文章我熟知的三种三栏网页自适应的布局方法。然后以双飞翼举例吧,他的DOM结构是这样的。
<div class="main">
<div class="main-content"></div>
</div>
<div class="sub"></div>
<div class="extra"></div>
把main放在最前面,然后对.sub
(也就是left)使用margin-left:100%;
强行移动到左边;对.extra
(也就是right)使用margin-left
:(right的宽度);强行移动到右边。由于右边的栏会盖住main的内容,所有就直接给main里加上子div,通过给子div加上margin-right
防止重叠保证正常显示。如此煞费苦心的布局目的只有一个,就是让浏览器先渲染main,实现主内容先被加载的效果。圣杯布局的话,印象中就是把.main-content
的margin
换成了.main
的padding
,目的都是一样的。
再多说一点关于三栏布局的东西,就是在利用浮动布局来实现三栏的时候,应该记住,在DOM里的顺序,是左浮动的div
最前,右浮动的div
中间,中间的在最后,不然就会出问题。千万不要想当然觉得中间的div
在DOM的中间,然后两边div
分别float
。因为中间的div
默认要占一行,按理说右边的会先被挤下去,再float
,所以他就上不来了,实现不了我们想要的效果。如果没有把中间的div
放到第一个位置的需求的话,还是建议用浮动的方法做三栏布局,简单易用成本低。
自此也算是总结了负边距的一些效果,有时候想想的话,要是pading支持负值的话又会有什么样的奇怪方案出现呢?
== 2015-11-27更新 ==
今天见到了一个奇怪的面试题,用三个div实现一条彩虹,同样使用了负边距。
相关推荐:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。