http://www.aspxhome.com/design/css/200811/513012.htm
I’m sorry. Really. I didn’t name it. I don’t mean to overstate its importance or trivialize the other and rather weightier Holy Grails.
But the name’s out there, and we all know what it means.
Three columns. One fixed-width sidebar for your navigation, another for, say, your Google Ads or your Flickr photos—and, as in a fancy truffle, a liquid center for the real substance. Its wide applicability in this golden age of blogging, along with its considerable difficulty, is what has earned the layout the title of Holy Grail.
Many articles have been written about the grail, and several good templates exist. However, all the existing solutions involve sacrifices: proper source order, full-width footers, and lean markup are often compromised in the pursuit of this elusive layout.
A recent project has brought my personal grail quest to an end. The technique I’ll describe will allow you to deploy the Holy Grail layout without compromising your code or your flexibility. It will:
- have a fluid center with fixed width sidebars,
- allow the center column to appear first in the source,
- allow any column to be the tallest,
- require only a single extra
divof markup, and - require very simple CSS, with minimal
hackspatches.
On the shoulders of giants
The technique presented here is inspired by Alex Robinson’s brilliant One True Layout. Alex even addressed the Holy Grail problem in his article, but his solution requires two wrappers and makes padding difficult without a further layer of
divs within each column.Another lead came from Eric Meyer’s adaptation that uses positioning to mix multiple unit types. His example also yields a three-column layout with fixed sidebars and a liquid center. Unfortunately, it relies on approximate percentages and fills a portion of the viewport that varies widely with different screen resolutions.
Enough talk—let’s see some code
The required HTML is intuitive and elegant.
(For the sake of clarity in demonstrating this technique, we are intentionally using the non-semantic
ids “center,” “left,” and “right.” We recommend you use semantic ids in any application of this technique. —Ed.)<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>That’s it. A single extra
div to contain the columns is all that you need; this satisfies even my obsessive compulsive markup habits.The stylesheet is almost as simple. Let’s say you want to have a left column with a fixed width of 200 pixels and a right column with a fixed width of 150 pixels. To simplify the comments, I’ll abbreviate the left, right, and center columns as LC, RC, and CC, respectively. The essential CSS is here:
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 */
}Simply replace the values with your desired dimensions and the grail is yours. The technique works in all modern browsers: Safari, Opera, Firefox, and (with the single-rule hack at the bottom) IE6. IE5.5 support would require at least a box-model hack, which is left as an exercise to the reader.
Take a look and marvel at the elegance.
How it works
The strategy is straightforward. The container
div will have a liquid center and fixed-width padding on the side. The trick is then to get the left column to line up with the left padding and the right column with the right padding, leaving the center column to fill the liquid width of the container.Let’s build this up step by step.
STEP 1: CREATE THE FRAME
Start with the header, footer, and container.
<div id="header"></div>
<div id="container"></div>
<div id="footer"></div>We pad the container with the width we want our left and right columns to occupy.
#container {
padding-left: 200px; /* LC width */
padding-right: 150px; /* RC width */
}Our layout now looks like this:
Step 1: Create the frame
STEP 2: ADD THE COLUMNS
Now that we have our basic frame, we’ll stick in the columns.
<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>Next we add the appropriate widths and float them to get them in line. We’ll also need to clear the footer to keep it beneath the floated columns.
#container .column {
float: left;
}
#center {
width: 100%;
}
#left {
width: 200px; /* LC width */
}
#right {
width: 150px; /* RC width */
}
#footer {
clear: both;
}Note that the 100% width on the center column refers to the width of the container div, exclusive of the padding. We’ll see this 100% width again as the layout comes together, and it will still refer to this central width of the container.
The columns now want to line up in order, but because the center column is taking up 100% of the available space, the left and right columns wrap.
Step 2: Add the columns
STEP 3: PULL THE LEFT COLUMN INTO PLACE
The only thing left is to get the colums to line up with the padding on the container. The center column starts exactly where it needs to be, so we’ll focus on the left column.
It takes two steps to get the left column in place. First, we’ll pull it all the way across the center column with a 100% negative margin. Remember that the 100% refers to the central width of the container, which is also exactly the width of the center column.
#left {
width: 200px; /* LC width */
margin-left: -100%;
}Now the left column is overlapping the center column, sharing its left edge. The right column floats left and nestles against right edge of the center column (but still wraps), leaving us with the following:
Step 3: Pull the left column into place—halfway there
To push the left column the rest of the way over, we’ll use relative positioning with an offset that’s exactly the width of the left column.
#container .columns {
float: left;
position: relative;
}
#left {
width: 200px; /* LC width */
margin-left: -100%;
right: 200px; /* LC width */
}The
right property pushes it 200px away from the right edge; that is, to the left. Now the left column lines up perfectly with the left padding of the container.Step 3: Left column pulled into place
STEP 4: PULL THE RIGHT COLUMN INTO PLACE
The only task remaining is to pull the right column into place. To do that, we just need to pull it out of the container and into the container’s padding. We’ll again use a negative margin.
#right {
width: 150px; /* RC width */
margin-right: -150px; /* RC width */
}
Everything is now in its right place, and the wrapping disappears.
Step 4: Pull the right column into place
STEP 5: DESIGN DEFENSIVELY
If the browser window is resized so that the center becomes smaller than the left column, the layout breaks in a standards-compliant browser. Setting a
min-width on the body keeps your columns in place. With IE6 this doesn’t happen, so the fact that it doesn’t support min-width isn’t a problem.body {
min-width: 550px; /* 2x LC width + RC width */
}Of course, no layout technique would be complete without requiring some sort of workaround in Internet Explorer. The negative margin pulls the left column too far to the left in IE6 (the full width of the browser window). We need to push it back to the right the full width of the right column—using the star-html hack to mask it from other browsers—and we’re ready to go.
* html #left {
left: 150px; /* RC width */
}The reason we need to use the width of the right column involves a bit of algebra. I won’t bore you with the details; you can work it out for yourself or just consider it another one of IE’s many charms.
Padding, please
I’m no designer, but looking at the layout above offends even my aesthetic sensibilities. The unpadded columns are hard on the eyes and difficult to read. We need whitespace.
One of the drawbacks of using percentages with the One True Layout to create liquid columns that it makes padding the columns a bit tricky. Percentage paddings tend to look bad at some screen widths. Fixed paddings can be added, but only by cluttering the markup with a
div nested inside each column.With this technique, padding isn’t a problem. Padding can be added directly to the left and right columns; just adjust the width accordingly. To give a 10-pixel padding to the left column in the example above, but keep it’s full width (padding + width) at 200px, simply change the rule as follows:
#left {
width: 180px; /* LC fullwidth - padding */
padding: 0 10px;
right: 200px; /* LC fullwidth */
margin-left: -100%;
}Padding the center requires a little more ingenuity, but no more markup and only a pinch of additional CSS.
The padding plus a width of 100% causes the center column to expand beyond the non-padded width of the container. In order to tame it back into place, we need to increase the right margin by the total amount of the padding. This ensures that the center column is only as large as we expect it to be.
Also, since the center column is now wider, the left column has a larger distance to move in order to get to the correct place. Increasing the offset by the total center padding does the trick.
To make this concrete, I’ll modify the example to add a 10-pixel padding to each side column (for a total of 20 pixels), and a 20-pixel padding to each side of the center (for a total of 40 pixels). The new CSS looks like this:
body {
min-width: 630px; /* 2x (LC fullwidth +
CC padding) + RC fullwidth */
}
#container {
padding-left: 200px; /* LC fullwidth */
padding-right: 190px; /* RC fullwidth + CC padding */
}
#container .column {
position: relative;
float: left;
}
#center {
padding: 10px 20px; /* CC padding */
width: 100%;
}
#left {
width: 180px; /* LC width */
padding: 0 10px; /* LC padding */
right: 240px; /* LC fullwidth + CC padding */
margin-left: -100%;
}
#right {
width: 130px; /* RC width */
padding: 0 10px; /* RC padding */
margin-right: -190px; /* RC fullwidth + CC padding */
}
#footer {
clear: both;
}
/*** IE Fix ***/
* html #left {
left: 150px; /* RC fullwidth */
}Of course, top and bottom padding can be added without any problems. See thisnicely padded version for the full template.
This technique works just as well for ems. Unfortunately, you can’t mix-and-match ems and pixels, so choose, but choose wisely.
Equal-height columns
This technique really comes together when the columns are given equal heights. The method I’m using is adapted wholesale from the One True Layout, so I won’t go over it in detail. To deploy it, simply add the following CSS:
#container {
overflow: hidden;
}
#container .column {
padding-bottom: 20010px; /* X + padding-bottom */
margin-bottom: -20000px; /* X */
}
#footer {
position: relative;
}Here, I’ve given the columns an extra padding of 10px on the bottom.
The usual caveats apply. Be aware that Opera 8 has a bug with
overflow: hiddenthat leaves all of your columns huge. A workaround is detailed on the One True Layout page; you can use that, or wait for Opera 9 (which fixes the bug) to come out of beta.One additional problem unique to this layout is that IE doesn’t clip the column backgrounds at the bottom of the container. They spill out over the footer if the page is not as tall as the viewport. This isn’t a problem if you don’t have a separate footer, or if your pages are tall enough to ensure that you’ll always take up the whole viewport.
If you need that footer, though, never fear. This, too, is fixable, but requires one more
div. Add a wrapper to the footer, like so:<div id="footer-wrapper">
<div id="footer"></div>
</div>Now re-use the same trick with the equal columns to make the footer wrapper extend beyond the page, leaving the footer itself for you to do with as you please.
* html body {
overflow: hidden;
}
* html #footer-wrapper {
float: left;
position: relative;
width: 100%;
padding-bottom: 10010px;
margin-bottom: -10000px;
background: #fff; /* Same as body
background */
}This solves the problem, and leaves us with the desired result and a minimum of cruft.
Oh, and there’s one more thing
The extremists out there might be wondering to themselves whether there’s not an even better way to do this. After all, the method I’ve illustrated introduces a non-semantic container
div. Surely we can’t have one extra div cluttering up our otherwise flawless markup.If you, like me, have been wondering this very thing, wonder no more. As a special bonus, I present to you the wrapper-free Holy Grail, in all its minimalist glory. One
divfor each section of the code—no more, no less. Semantic bliss, almost worthy of the title of “Holy Grail.”The principle behind the CSS is the same. The padding has been applied directly to the body, eliminating the need for any containers. Negative margins stretch the header and footer to ensure that they take up the entire space.
This tiny version works in all the aforementioned browsers, even (almost shockingly) Internet Explorer. Equal-height columns do not work, however, and this layout will break down for very small window widths. Use it with caution.
So what now?
While this particular application of the Holy Grail is rather specific, the technique can be generalized considerably. Why not have two liquid columns? Why not switch up the column orders? These applications are beyond the scope of this article, but achievable with minor modifications. Use the grail wisely, and it can be a particularly handy (and clutter-free) addition to your bag of CSS tricks. 
很抱歉我没有将这篇文章命名.我不是想夸大他的重要性或是轻视其他的Holy Grails.但是确实是这么称呼,我们都明白它的含义.
三栏,一个是固定宽度的导航栏,另一个是GOOGLE广告,或是Filckr图片展示,就像Fancy的松露巧克力一样,和一个重要的柔滑的夹心。在这个博客流行的黄金年代它是相当适用的,加之相当大的实现难度,理所应当的获取了”圣杯”的名称.
在最近的一个项目中我终于找到了传说中的圣杯。我在不会改变您的代码和灵活性的前提下尽可能的描述他。他会是:
- 一个自适应适应的中心和固定宽度的侧边栏
- 允许中间的内容先于其他出现在代码中
- 允许任何一栏都是最高的高度
- 只需要额外的一个DIV标签
- 非常的简单的CSS代码和很少很少的HACK 补丁
站在巨人的肩膀上
这个技术的灵感来自于Alex Robinson’s的One True Layout。他曾经在他的文章里阐述过”圣杯”的若干问题,但是他的解决方法需要两个包装并且要求每一栏都需要一个父级DIV,否则很难写内在结构.
另一方面则是由Eric Meyer’s的写法想到的,他利用了多种类型的单元混合定位。它的例子中也是用了固定的侧边栏和自适应的中心层,可是不幸的是,他依赖于近似的百分比,不是固定的值,而且填充了一部分随屏幕分辨率不同而自适应宽度的层。
言归正传,看看代码
代码是很直观而且很优雅的。
(为了直观起见,我们使用了非语义化的”中心”、”左”和”右”来阐述我们的代码,但是我们建议您在您的代码中使用语义化的标签 -Ed.)
<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 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包含着我们的三个层,这样的结构符合我集中内容上一体的标记为一体的习惯(obsessive compulsive markup habits. 翻译的不准确)
样式很也简单,左边侧栏是200PX,右边是150,为了简便标示用LC,RC,CC分别代表左边,右边和中间,样式如下:
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 */
}
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 */
}
重新度量你想要的模型的价值,你会发现其实很简单.这布局能在Opera, Firefox, and IE6(需要在最后一句HACK).IE5.5则需要HACK CSS盒模型。刚好也给读者一个练习的机会(Orz).
再看一遍这段优化代码(例子)
再看一遍这段优化代码(例子)
原理
其实诀窍很简单,让左边栏与右边padding,右边栏与左边padding,中间刚好剩下自适应的内容层.
让我们一步一步来演示这个过程
第一步:创建父级容器
包括header, footer, and container.
<div id="header"></div>
<div id="container"></div>
<div id="footer"></div>
<div id="container"></div>
<div id="footer"></div>
我们让container(包容的容器)padding-left,padding-right,padding的值分别是左边栏和右边栏的值.
#container {
padding-left: 200px; /* LC width */
padding-right: 150px; /* RC width */
}
padding-left: 200px; /* LC width */
padding-right: 150px; /* RC width */
}
我们的布局大致是这样的:
翻译]寻找圣杯 in search of the holy grail" rel="lightbox" target=_blank>
第二步:添加栏
我们现在已经有了父级容器,现在来插入里面的三栏
<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 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>
现在我们要添加宽度和浮动属性以使他们在一行,并且在footer清除浮动
#container .column {
float: left;
}
#center {
width: 100%;
}
#left {
width: 200px; /* LC width */
}
#right {
width: 150px; /* RC width */
}
#footer {
clear: both;
}
float: left;
}
#center {
width: 100%;
}
#left {
width: 200px; /* LC width */
}
#right {
width: 150px; /* RC width */
}
#footer {
clear: both;
}
你会留意到中间的层已经和外面的层一样宽了(除去padding值的情况下),一会我们就可以看见所有的层都在一起并且也是100%宽。现在,层的顺序就是我们想要的顺序了,但是因为中间的层占据了100%的宽度,所以左边和右边的层就掉了下来。
第三步:把左边栏放在左边
现在我们要干的是怎么样让这三栏在一行,中间的容器已经完全符合我们的要求了,我们只需要关注剩下的两个,先从左边的开始。
需要两步让左边栏在左边.第一步:让他以100%的负margin(margin-left: -100%;)穿过中间的层,记住一定要用100%,因为中间的层的宽度是100%.
#left {
width: 200px; /* LC width */
margin-left: -100%;
}
width: 200px; /* LC width */
margin-left: -100%;
}
现在左边栏和中间栏重合,左边重合,右边栏浮动过来(虽然还是掉下去了),现在的结果变成了下面的样子:
翻译]寻找圣杯 in search of the holy grail" rel="lightbox" target=_blank>
第二步:现在要把左边栏拉到正确的位置,我们使用相对定位来抵消左边栏的宽度
#container .columns {
float: left;
position: relative;
}
#left {
width: 200px; /* LC width */
margin-left: -100%;
right: 200px; /* LC width */
}
float: left;
position: relative;
}
#left {
width: 200px; /* LC width */
margin-left: -100%;
right: 200px; /* LC width */
}
因为设置了right: 200px;所以左边栏被中心层的右边推远了200px,刚好到了左边。(The right property pushes it 200px away from the right edge; that is, to the left.)现在左边栏刚好完美的到了他应该到的位置
第四步:把右边栏放到右边
剩下的事就是把右边栏放在右边,需要把他拉出容器放在容器的padding上,我们依然利用负边距。
#right {
width: 150px; /* RC width */
margin-right: -150px; /* RC width */
}
width: 150px; /* RC width */
margin-right: -150px; /* RC width */
}
现在所有的东西都在他该在的位置上了,没有谁”掉队”,呵呵。
第五步:补充设计
如果浏览器重新调整大小,中间的容器小于左边栏的时候,整个布局都会被破坏掉,所以要设置一个min-width来保持我们的布局不被片破坏,虽然在IE6上这个属性是不起作用的,但是没关系。
body {
min-width: 550px; /* 2x LC width + RC width */
}
min-width: 550px; /* 2x LC width + RC width */
}
没有任何一个布局是不要对IE增加一些额外的工作就能完成的。(-_-!) 在IE6中负边距会使左边栏离的太远(在全宽浏览下),我们要用右边栏的宽大把他向右拉回来。并且用* html来屏蔽其他浏览器执行他.
* html #left {
left: 150px; /* RC width */
}
left: 150px; /* RC width */
}
至于为什么要用右边栏的宽度,要牵涉到一些算法。当然我不会用去解释这些,我们只要知道这样是起作用的,我们甚至可以认为这个是IE的众多”魔法”之一。
Padding, please
我不是设计师,但是上面的布局实在是触犯了我的审美观。没有边距的栏目是很分辨和阅读的,我们需要空隙!
使用One True Layout这样百分比布局的的弊端之一就是会造成中间层的padding困难,百分比的padding在某些分辨率下会变的很难看。可以用固定宽度的padding,但是需要给每一栏内部嵌套一个div。
用这个布局padding不是问题,他可以直接给左、右边栏添加padding,只需响应的调整即可。例如我们要给上面的例子添加10px的padding,并且保持他(width+padding)还是200px,只需要小小的改动
#left {
width: 180px; /* LC fullwidth - padding */
padding: 0 10px;
right: 200px; /* LC fullwidth */
margin-left: -100%;
}
width: 180px; /* LC fullwidth - padding */
padding: 0 10px;
right: 200px; /* LC fullwidth */
margin-left: -100%;
}
要给中心层加padding需要一个技巧,但是不需要额外的结构,只需额外的一小段css。加的100%的宽度导致中心层和外部的的padding以外(non-padded width)的宽度一样宽。为了达到我们想要的效果,我们需要增加右边的margin,使其等于padding值的总和,这样就保证了他会是我们想要的大小。
我们改变了中间层的改变成现在这样后,左边栏需要移动更多的距离才能在正确的位置上,这也是技巧所在。我们需要给右边框的抵消值(上面的right值)增加上中间层的padding值。
为了更具体的说明,我继续以上面的例子为例,现在给每一个边框增加10px的padding值(合计20px),中间层增加20px的padding值(合计40px),新的样式如下:
为了更具体的说明,我继续以上面的例子为例,现在给每一个边框增加10px的padding值(合计20px),中间层增加20px的padding值(合计40px),新的样式如下:
body {
min-width: 630px; /* 2x (LC fullwidth +
CC padding) + RC fullwidth */
}
#container {
padding-left: 200px; /* LC fullwidth */
padding-right: 190px; /* RC fullwidth + CC padding */
}
#container .column {
position: relative;
float: left;
}
#center {
padding: 10px 20px; /* CC padding */
width: 100%;
}
#left {
width: 180px; /* LC width */
padding: 0 10px; /* LC padding */
right: 240px; /* LC fullwidth + CC padding */
margin-left: -100%;
}
#right {
width: 130px; /* RC width */
padding: 0 10px; /* RC padding */
margin-right: -190px; /* RC fullwidth + CC padding */
}
#footer {
clear: both;
}
/*** IE Fix ***/
* html #left {
left: 150px; /* RC fullwidth */
}
min-width: 630px; /* 2x (LC fullwidth +
CC padding) + RC fullwidth */
}
#container {
padding-left: 200px; /* LC fullwidth */
padding-right: 190px; /* RC fullwidth + CC padding */
}
#container .column {
position: relative;
float: left;
}
#center {
padding: 10px 20px; /* CC padding */
width: 100%;
}
#left {
width: 180px; /* LC width */
padding: 0 10px; /* LC padding */
right: 240px; /* LC fullwidth + CC padding */
margin-left: -100%;
}
#right {
width: 130px; /* RC width */
padding: 0 10px; /* RC padding */
margin-right: -190px; /* RC fullwidth + CC padding */
}
#footer {
clear: both;
}
/*** IE Fix ***/
* html #left {
left: 150px; /* RC fullwidth */
}
当然上下的padding值能很方便的添加,具体请参看nicely padded version 中的例子
这个布局也能在em下很好的工作,但是不能在混合em和px的时候工作,选什么你来定,但是要选的正确。
这个布局也能在em下很好的工作,但是不能在混合em和px的时候工作,选什么你来定,但是要选的正确。
等高栏
这个布局能保证所有的栏目都是等高的,实现方式是来着与One True Layout的adapted wholesale。所以我不详细解释,增加和修改代码如下
#container {
overflow: hidden;
}
#container .column {
padding-bottom: 20010px; /* X + padding-bottom */
margin-bottom: -20000px; /* X */
}
#footer {
position: relative;
}
overflow: hidden;
}
#container .column {
padding-bottom: 20010px; /* X + padding-bottom */
margin-bottom: -20000px; /* X */
}
#footer {
position: relative;
}
我特别在下面留了10个像素
附加的说明,请注意在Opera上存在一个bug,即overflow:hidden会让你所有的栏目都变大,在One True Layout上有详细的解决办法。你可以使用这个方法或是等Opera 9(被修复了这个bug)来测试。
另一个问题是,在IE中如果内容的高度没有背景图片的高度高,背景不会被剪掉,他会超出footer。如果你没有独立的footer或是内容比背景高,这也不是个问题。如果你仍然需要一个footer,不要怕还是有解决的办法的。用一个DIV把footer封装一下就可以。
<div id="footer-wrapper">
<div id="footer"></div>
</div>
<div id="footer"></div>
</div>
现在依然用上面我们使用到的让各个栏目对齐的技巧来让footer超过封装的DIV,来显示我们想要显示的内容
* html body {
overflow: hidden;
}
* html #footer-wrapper {
float: left;
position: relative;
width: 100%;
padding-bottom: 10010px;
margin-bottom: -10000px;
background: #fff; /* Same as body
background */
}
overflow: hidden;
}
* html #footer-wrapper {
float: left;
position: relative;
width: 100%;
padding-bottom: 10010px;
margin-bottom: -10000px;
background: #fff; /* Same as body
background */
}
现在解决了所有的问题,得到了我们想要的结果和很少量冗余的代码。
哦,还需要说明的
完美主义者有可能是想知道是否有一个更好的方式来做到这一点?我之前声明过,我引用了一个非语义化的包含容器(DIV),确实,我们不应该包含一个额外的结构来打乱我们完美的结构.
如果你像我一样,象知道这样怎么去实现,不需要更多的结构,我向你介绍”wrapper-free Holy Grail (没有包含的圣杯)”,其最抽象的特殊之处在于,用一个DIV实现了各部分 — 不多也不少,语义化,不愧于”圣杯”的美名.其原理是相似的.主体直接应用padding不需要多余的容器,而用负边距来延伸header和footer 使其刚好达到想要的宽度.
这种布局能在所有的浏览器上正常工作,甚至(令人震惊)是在IE上,但是不是等高的.而且在非常小的窗口中是会”破掉”的,使用他的时候一定要谨慎.
最后
虽然文中提到的例子很具体,但是这项技术的使用范围确实很大.为什么不能有两个活动的中心层,为什么不调换层的顺序.这些引用都超出了本文的表述范围,但是要实现他们只需要很小的改动即可.使用圣杯是明智的.他可以成为你使用CSS的技巧之一.