双飞翼布局 and 圣杯布局分析

圣杯布局

圣杯布局源自 2006年发布的文章 In Search of the Holy Grail · An A List Apart Article

<div class="container">
  <div class="center">center</div>
  <div class="left">left</div>
  <div class="right">right</div>
</div>

具体实现如下:

1、 首先分别浮动left,right,center三列, 然后利用负margin把left,right定位到左右两边。

关于负margin的技术文章请参考:margin 详解

.center {
  float: left;
  width: 100%;
  height: 200px;
  background: #abcdef;
}

.left {
  float: left;
  width: 300px;
  height: 200px;
  margin-left: -100%;
  background: #aef;
}

.right {
  float: left;
  width: 200px;
  height: 200px;
  margin-left: -200px; /* right.width */
  background: #ccc;
}

2、 看似基本有了雏形,随后解决的就是中间center内容被遮挡的问题。此处直接添加父容器padding使内容得以显示。

.container{
  padding-left: 300px;  /* left.width */
  padding-right: 200px; /* right.width */
}

3、 内容位置正确了,但随之而来的问题就是left,right俩列别挤开。为了解决这个问题,圣杯布局使用相对定位使left,right列回到正确的位置。

.left {
    position: relative;
    left: -300px; /* left.width */
}
.right {
    position: relative;
    right: -200px; /* right.width */
}

4、 当浏览器缩小到一定程度时,这个布局可能会被破坏,可以在body上添加min-width属性解决。

body{
  min-width: 800px; /* left.width * 2 + right.width */
}

点击查看-圣杯布局

双飞翼布局

双飞翼布局介绍-始于淘宝UED.

  1. 前面与圣杯布局大抵相同,通过浮动center、left和right,然后利用负外边距正确定位left和right。
  2. 与圣杯布局同样的问题,而双飞翼布局的解决办法是在center外面嵌套一个宽度100%的div,由于父容器宽度定死,这时候我们就可以通过设置子元素的padding或者margin来将真正的内容排放到中间。

具体实现如下:

<div class="container">
  <div class="center">center</div>
  <div class="left">left</div>
  <div class="right">right</div>
</div>
body {
  min-width: 600px; /* left.width + right.width + center.content.width*/
}

.center {
  float: left;
  width: 100%;
}

.center div {
  height: 200px;
  margin-left: 300px;
  margin-right: 200px;
    background: #abcdef;
}

.left {
  float: left;
  width: 300px;
  height: 200px;
  margin-left: -100%;
  background: #aef;
}

.right {
  float: left;
  width: 200px;
  height: 200px;
  margin-left: -200px;
  background: #ccc;
}

点击查看-双飞翼布局

圣杯布局与双飞翼布局的比较

相同点:

  1. 俩种布局方式都是把center放在文档最前面,这里的原因,我觉得跟层叠顺序有关。

    可参考:z-index 详解

  2. 两种布局方式在实现上都是让三列浮动,然后通过负外边距形成三列布局。

不同点:

  1. 处理center的位置:
    • 圣杯布局是利用父容器的左、右内边距定位,left,right通过相对定位恢复偏差的位置;
    • 双飞翼布局是通过添加新的父容器,由于新添父容器位块级元素,所以它的宽度位100%,在通过设置子元素的margin或者padding来达到正常显示内容,也不影响最大宽度。
  2. 页面的最小宽度
    • 圣杯布局最小宽度为 left.width * 2 + right.width
    • 而双飞翼布局的最小宽度为 left.width + right.width 这里排斥了center该有的宽度,理论应该要多预留一些宽度给center.

总结

  • 双飞翼布局多了一个div,却减少了相对定位属性的代码,并且可以兼容IE6,无需任何hook.
  • 圣杯布局存在一定的局限性,低版本IE兼容性不佳,需要添加各种hook,代码量多。
  • 如果不考虑低版本IE兼容问题,可以使用许多如flex,box-sizing等新特性完成。

参考资料: