applegray

导航

寻找圣杯布局(译)——上

说实话,昨晚之前,我还真没听过圣杯布局这个词。看了A List apart的In Search of Holy Grails,觉得很不错,里面有好几个我以前理解错误或没想过的知识点。于是决定将那篇文章翻译成中文。由于非专业水平,翻译个大概就OK了。以下图片、代码均出自原文:http://www.alistapart.com/articles/holygrail/

 

 

《寻找圣杯布局》

      很抱歉,真的。这不是我命名的。我并不是想故意夸大它的重要性或贬低其他来突出圣杯。

     但是名字就在那儿,而且我们都知道这意味着什么。 

     三列。一个固定宽度,可以做你的导航栏,另一个可以放你的谷歌广告或你的Flickr照片,还有一个列,就放类似像在一个花哨的松露,流体中心的实质性内容。其广泛的适用性在这个黄金时代的博客,连同考虑到其相当大的困难,为它赢得了布局中圣杯的标题。

     很多文章已经写过关于圣杯,,也有几个好模板存在。然而,所有现有的解决方案都有所牺牲:适当的源代码秩序,宽屏页脚和精益标记通常在追求这种难以捉摸的布局中被妥协了。

      最近的一个项目带来了我个人的圣杯寻求结束。我接下来要描述的技术将允许您部署圣杯布局的同时不影响您的代码或你的灵活性。它将有以下特点:

1、有一个流体中心与固定宽度侧边栏

2、允许中心列在源代码中最早出现

3、允许任何列是最高的

4、只需要一个额外的div标记和非常简单的CSS,以及最少的hack、补丁

 

站在巨人的肩膀上

     这里介绍的技术灵感是受亚历克斯·罗宾逊的辉煌的《一个真正的布局》激发的。亚历克斯在他的文章中甚至解决了圣杯的问题,但是他的解决方案需要两个wrapper,而且在每一个列中不额外添加div的话很难设定padding

     另一个是来自《埃里克·迈耶的适应》,使用定位混合多个单元类型。他的例子还产生了一个三列的布局与固定侧栏和流体中心列。遗憾的是,它依赖于近似百分比和在差别很大不同的屏幕分辨率中填补了部分的视窗。

 

说的话够多了,来看看实际的代码吧

     所需的HTML是直观和优雅的。(为了清晰的证明了这种技术,我们有意地使用非语义id“中心”、“左”和“右。“我们建议你使用语义ids在任何应用程序的技术----编者。)

<div id="header"></div>

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

</div>

<div id="footer"></div>

  就这些。一个额外的div包含了所有你需要的列,这甚至满足了我的强迫性标记的习惯。

     样式表一样简单。让我们说,你想要一个固定宽度是200像素的左列和一个固定宽度是150像素的右列。为了简化评论,我将使用缩写词LC、RC和CC来代表左,右,中心列。必要的CSS如下:

body {
  min-width: 550px;      /* 2x LC width + RC width */
}
#container {
  padding-left: 200px;   /* LC width */
  padding-right: 150px;  /* RC width */
}
#container .column {
  position: relative;
  float: left;
}
#center {
  width: 100%;
}
#left {
  width: 200px;          /* LC width */
  right: 200px;          /* LC width */
  margin-left: -100%;
}
#right {
  width: 150px;          /* RC width */
  margin-right: -150px;  /* RC width */
}
#footer {
  clear: both;
}
/*** IE6 Fix ***/
* html #left {
  left: 150px;           /* RC width */
}

     可以简单的替换数值与您期望的维度,圣杯就是你的了。这种技术适用于所有现代浏览器:Safari、Opera,Firefox,(需配合底部的hack)IE6。ie5 5支持将需要至少一盒模型黑客,这是留给读者作为练习。

点击这里,去惊叹一下它的幽雅吧。

 

它是如何工作的

     该战略是非常简单的。容器div将有一个流体中心和固定宽度的填充物在侧边。诀窍就是让左列来填充左内边距,让右列填充右内边距,剩下中心列填充流体容器的宽度。

让我一步步的构建。

 

第一步:搭建框架

     由header, footer 和container开始

<div id="header"></div>

<div id="container"></div>

<div id="footer"></div>

     我们先根据我们所想要的左列和右列宽度来给container设定内边距

#container {
  padding-left: 200px;   /* LC width */
  padding-right: 150px;  /* RC width */
}

     然后我们的布局看起来就是这样

 

第二步:增加列

     现在我们有了基本的框架,然后插入列

<div id="header"></div>

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

<div id="footer"></div>

     接下来,我们添加适当的宽度和浮动它们让它们在同一线上。我们也需要页脚清除浮动来保持它在浮动列下方。

#container .column {
  float: left;
}
#center {
  width: 100%;
}
#left {
  width: 200px;  /* LC width */
}
#right {
  width: 150px;  /* RC width */
}
#footer {
  clear: both;
}

     注意中心列100%的宽度指其占据了容器div内容的宽度(padding排除在外)。当布局集合到一起时我们将会再次看到这100%宽度,它仍将占据中央容器的内容宽度。

      现在想要列排成一线,但因为中心列占用了100%的可用空间,左和右列包装。

 

第三步:将左列拖回恰当的位子

     剩下的最后一件事就是把列排成一线的放到容器的padding里。以为中心列一开始已经在恰当的位置了,所以我们将专注于左列。

     让左列在恰当的地方需要两步。首先,我们用100%的负外边距让它穿过整个中心列去到恰当的位子。记住,100%是指容器的内容宽度,这也正是中心列的层宽度。

#left {
  width: 200px;        /* LC width */
  margin-left: -100%;  
}

     现在,左列重叠的中心列,分享它的左边缘。右列向左浮动左且刚好被中心列的右边缘顶了下来(但仍包裹在内),如下图:

     为了将左列推到旁边恰当的位子,我们将使用相对定位,偏移量恰好是左列的宽度。

#container .columns {
  float: left;
  position: relative;
}
#left {
  width: 200px;        /* LC width */
  margin-left: -100%;  
  right: 200px;        /* LC width */
}

     "right"这个属性将它从右边缘退离了200 px;也就是说,到了左边。现在,左列十分契合填充了容器的left padding。

 

第四步:将右列拉到恰当的位子

     剩下的唯一任务是把右列到位。为了做到这一点,我们只需要将它从容器的主体脱离,进入到容器的padding。我们将再次使用一个负外边距。

#right {
  width: 150px;          /* RC width */
  margin-right: -150px;  /* RC width */
}

     每一样现在看起来都在合适的位置了:

 

第五步:设计防守

     如果浏览器窗口大小缩放了,以便中心列变得小于左列,布局休息在一个符合标准的浏览器。在body设置一个最小宽度保持列所在的地方。在IE6这不会发生,因此,它不支持最小宽度并不是一个问题。

body {
  min-width: 550px;  /* 2x LC width + RC width */
}

     当然,在Internet Explorer,不会有布局技术会是完美的,除非它添加某种额外方法。负边距使左列IE6(完整的浏览器窗口的宽度)过分左倾。我们需要把它推回到正确的位子,使用右列的宽度,以下这个明星html hack其他的浏览器将不能识别,我们准备好了。

* html #left {
  left: 150px;  /* RC width */
}

     为什么需要使用右列的宽度呢?这其中包括了一点代数的知识。我不会用这点细节来烦你的。你可以自己解决或者仅仅把它当做是IE的许多魅力中的其中一个吧。

 

(未完待译)

posted on 2012-09-24 14:12  applegray  阅读(304)  评论(0)    收藏  举报