什么是圣杯布局?
根据 wikipedia词条,圣杯指多列等高的网页布局。因为目前的实现方法都存在局限,而又很难找到一个最优解,圣杯因此而得名。
holy-grail.png在[Matthew Levine 的文章](In Search of the Holy Grail http://alistapart.com/article/holygrail) 中提到了圣杯的五个要求:
- 中间列宽度自适应(fluid),两边列宽度固定
- 在源文档(source)中,中间列处于侧边两列之前
- 任意一列都可以作为最高列
- 除了必要的元素之外,只多出一个div标签
- 用简洁的CSS实现,尽量减少hack
Padding Solution
这个方法来自[Matthew Levine 的文章](In Search of the Holy Grail http://alistapart.com/article/holygrail)。
实现思路:在三列之外包上一个div,通过padding留出左右列的空间,再通过 relative positon 把左右列移动到合适位置。
- 首先通过 float: left 把三个div排到同一行,并分别设置三列的宽度
- 在三列之外包上一个div,设置其左右padding分别为左右列的宽度
- 对左列设置 margin-left: -100% 从而移动到最左侧。通过 position: relative, right: [width_of_left_col] 把左列移动到padding留出的左侧空间。
- 使用 position: relative, right: -[width_of_right_col] 把右列移动到padding留出的右侧空间。
- 对 footer 设置 clear: both, 防止和三列重叠。
- 中间列的最小宽度不能低于左列宽度。
// HTML
<div class="body">
<div class="header">header</div>
<div class="container">
<div id="center" class="column">
main
</div>
<div id="left" class="column">
nav
</div>
<div id="right" class="column">
ads
</div>
</div>
<div class="footer">footer</div>
</div>
// CSS
.body {
min-width: 600px;
}
.footer {
clear: both;
}
.container {
padding: 0 200px;
}
.column {
position: relative;
float: left;
}
#center {
width: 100%;
}
#left {
width: 200px;
margin-left: -100%;
right: 200px;
}
#right {
width: 200px;
margin-right: -200px;
}
Margin Solution
- 在center column外面套一层div,宽度为100%。
- 两边列和中间div都为float:left,使三列同行显示。
- 对左列margin-left:-100%,使其定位于最左的宽度。
- 中间列两边设置margin分别为左右列的宽度。
- 右边列设置margin-left为负自己的宽度,使其缩进wrapper里面
// HTML
<div class="header">header</div>
<div class="center-wrapper">
<div id="center">
main
</div>
</div>
<div id="left">nav</div>
<div id="right">ads</div>
<div class="footer">footer</div>
// CSS
.footer {
clear: both;
}
.center-wrapper {
float: left;
width: 100%;
}
#center {
margin: 0 200px;
}
#left {
float: left;
width: 200px;
margin-left: -100%;
}
#right {
float: left;
width: 200px;
margin-left: -200px;
}
Flexbox Solution
最简单的实现方法。
<div class="header">header</div>
<div class="container">
<div id="center">
main
</div>
<div id="left">nav</div>
<div id="right">ads</div>
</div>
<div class="footer">footer</div>
.container {
display: flex;
}
#left {
width: 200px;
order: -1;
}
#right {
width: 200px;
}
#center {
flex: 1;
}
Follow-up
当窗口很狭窄的时候,把左边列移动到中间列之上,右边列移动到中间列之下。
holy-grail-stack.png// CSS
@media(max-width:600px){
.container{
flex-direction: column;
}
}
网友评论