定宽+自适应两列布局
absolute + margin
1 | <div class="container"> |
1 | .container{ |
优点:
- 支持主列和边栏顺序互换
- 支持主列优先显示,即优先加载渲染
缺点:因为sidebar列脱离了文档流,当sidebar列比main列高时会覆盖后面的布局:点击查看在线demo。如果在container容器上添加overflow:hidden就会使sidebar溢出部分被裁减。在这种布局方式下,这个问题确实没有有效的解决办法。
float + margin
1 | <div class="sidebar">边栏</div> |
1 | .main{ |
点击查看在线demo
优点:左右两列顺序可互换
缺点:不支持主列优先显示
float + 负margin(双飞翼布局)
1 | <div class="main-wrapper"> |
1 | .main-wrapper{ |
点击查看在线demo
这个布局即为双飞翼布局,双飞翼布局源自淘宝UED,现在查看下淘宝店铺的DOM结构,就能找到双飞翼布局的身影。实现过程:
- 首先浮动
main列和sidebar列,然后通过负margin正确定位sidebar列。 - 把
main列嵌套在一个div里,该div的宽度值设为100%。 - 最后通过设置
main列的margin-left消除被sidebar覆盖的部分即可。
双飞翼布局优点:
- DOM按照主、子、附加列的顺序加载,实现了重要内容先加载。
main部分是自适应宽度的,很容易在定宽布局和流体布局中切换。- 在浏览器上的兼容性非常好,IE5.5以上都支持。
- 实现了内容与布局的分离,即Eric提到的Any-Order Columns.
- 任何一栏都可以是最高栏,不会出问题。
- 需要的hack非常少。
两列定宽+自适应三列布局
圣杯布局
圣杯布局源自 Matthew Levine 在06年的一篇文章,其DOM结构如下:1
2
3
4
5<div class="container">
<div class='main'>主体</div>
<div class='sub'>边栏</div>
<div class="extra">另一边栏</div>
</div>
实现圣杯布局的步骤
首先要使得
main,sub,extra三列浮动,然后利用负margin将sub和extra定位到main两边1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20.main{
float:left;
height:100px;
width:100%;
background-color:rgba(255,0,0,.5);
}
.sub{
float:left;
height:100px;
width:200px;
margin-left:-100%;
background-color:rgba(0,255,0,.5);
}
.extra{
float:left;
height:100px;
width:100px;
margin-left:-100px;
background-color:rgba(0,0,255,.5);
}sub和extra定位到main两边,但是覆盖了main列,圣杯布局对container容器添加边距,使得main列出现在正确的位置1
2
3
4
5
6
7
8.container{
height:100px;
/*第二步添加*/
padding-left:210px;
padding-right:110px;
}对
container容器添加内边距虽然让main列出现在正确的位置,但是也使得sub和extra列因为内边距影响偏离了原来的位置。圣杯布局使用相对定位让sub和extra列出现在正确的位置。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22.sub{
float:left;
height:100px;
width:200px;
margin-left:-100%;
background-color:rgba(0,255,0,.5);
/*第三步添加*/
position:relative;
left:-210px;
}
.extra{
float:left;
height:100px;
width:100px;
margin-left:-100px;
background-color:rgba(0,0,255,.5);
/*第三步添加*/
position:relative;
right:-110px;
}当浏览器缩小到一定程度时,这个布局可能会被破坏,可以在body上添加
min-width属性解决。最终的圣杯布局CSS代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40body{
/*第四步添加*/
min-width:520px; /* 2*sub + extra */
}
.container{
height:100px;
/*第二步添加*/
padding-left:210px;
padding-right:110px;
}
.main{
float:left;
width:100%;
height:100px;
background-color:rgba(255,0,0,.5);
}
.sub{
float:left;
height:100px;
width:200px;
margin-left:-100%;
background-color:rgba(0,255,0,.5);
/*第三步添加*/
position:relative;
left:-210px;
}
.extra{
float:left;
height:100px;
width:100px;
margin-left:-100px;
background-color:rgba(0,0,255,.5);
/*第三步添加*/
position:relative;
right:-110px;
}
优点:
- 使主要内容列先加载。
- 允许任何列是最高的。
- 没有额外的div。
- 需要的hack很少。
和双飞翼布局比较
和圣杯布局一样,分别浮动main、sub和extra列,然后利用负外边距正确定位sub和extra列。
这时依旧面临和圣杯布局同样的问题:main列没有正确定位且被sub、extra列覆盖。双飞翼布局的解决办法是在main列外面包裹了一个宽度100%的div,然后通过设置main列的左、右外边距正确定位main列。
异同点:
- 俩种布局方式都是把主列放在文档流最前面,使主列优先加载。
- 两种布局方式在实现上也有相同之处,都是让三列浮动,然后通过负外边距形成三列布局。
- 两种布局方式的不同之处在于如何处理中间主列的位置:圣杯布局是利用父容器的左、右内边距定位;双飞翼布局是把主列嵌套在div后利用主列的左、右外边距定位。