定宽+自适应两列布局
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后利用主列的左、右外边距定位。