1、CSS包含3种基本的布局模型,用英文归纳为:Flow、Layer 和 Float。
在网页中,元素有三种布局模型:
一、流动模型(Flow)css
流动模型是默认的网页布局模式。html
在流动模型下,内联元素都会在所处的包含元素内从左到右按顺序水平分布显示。浏览器
二、浮动模型 (Float)float:right/left/none;
布局
三、层模型(layer)绝对定位position: absolute; 相对定位position: relative; 固定定位position: fixed;
post
解释网站
圣杯布局与双飞翼布局针对的都是三列左右栏固定中间栏边框自适应的网页布局(想象一下圣杯是主体是加上两个耳朵;鸟儿是身体加上一对翅膀),圣杯布局是Kevin Cornell在2006年提出的一个布局模型概念,在国内最先是由淘宝UED的工程师(传说是玉伯)改进并传播开来,在中国也有叫法是双飞翼布局,它的布局要求有几点: ui
三列布局,中间宽度自适应,两边定宽;url
中间栏要在浏览器中优先展现渲染; spa
容许任意列的高度最高;3d
下面咱们看看具体的实现方法。
HTML结构
1
2
3
4
5
6
7
|
< div class = "header" >header</ div >
< div class = "container" >
< div class = "main" >main</ div >
< div class = "left" >left</ div >
< div class = "right" >right</ div >
</ div >
< div class = "footer" >footer</ div >
|
由于须要中间栏优先展现渲染,因此中间的main在HTML的结构中倒是最靠前的。在实际的网站中这样作的好处就是用户可以先看到网页正文信息,通常网页两边的导航信息和说明信息咱们认为优先级没有正文重要。
1.设置一下基本样式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
*{ margin : 0 ; padding : 0 ;}
body{ min-width : 700px ;}
.header,.footer{
border : 1px solid #333 ;
background : #aaa ;
text-align : center ;
}
. left ,.main,. right {
min-height : 130px ;
}
.container{
border : 2px solid yellow;
}
. left {
width : 200px ;
background : red ;
}
. right {
width : 220px ;
background : green ;
}
.main{
background : blue ;
}
|
为了高度保持一致给left middle right都加上min-height:130px
2.将主体部分的三个子元素都设置左浮动
1
2
3
|
. left ,.main,. right {
float : left ;
}
|
此时的页面显示如图所示,Shen Me Gui不要紧,事情会变得好起来的
咱们看一下上面的效果比较明显的两个问题,一是footer跑到上面去了,二是container容器高度塌陷了,这是典型的“清除浮动和闭合浮动”问题。
3.解决浮动问题
1
2
3
4
5
6
7
|
.container{
border : 2px solid yellow;
overflow : hidden ; /*闭合浮动*/
}
.footer{
clear : both ; /*清楚浮动*/
}
[附]清浮动经常使用的方法
.clearfix:after{
content:"";
display:block;
clear:both
}
.clearfix{
*zoom:1; /*解决兼容性问题*/
}
|
给container加上overflow:hidden触发BFC闭合浮动,给footer加上clear属性清除浮动。
咱们发现footer移到了下面,而且container的高度塌陷也修复了。
4.设置main宽度为width:100%,让其单独占满一行
1
2
3
4
|
.main{
width
:
100%
;
background
:
blue
;
}
|
5.设置left和right负的外边距
咱们的目标是让left、main、right依次并排,可是上图中left和right都是位于下一行,这里的技巧就是使用负的margin-left:
1
2
3
4
5
6
7
8
9
10
|
.
left
{
margin-left
:
-100%
;
width
:
200px
;
background
:
red
;
}
.
right
{
margin-left
:
-220px
;
width
:
220px
;
background
:
green
;
}
|
负的margin-left会让元素沿文档流向左移动,若是负的数值比较大就会一直移动到上一行。关于负的margin的应用也是博大精深,这里确定是不能详细介绍了。
设置left部分的margin-left为-100%,就会使left向左移动一整个行的宽度,因为left左边是父元素的边框,因此left继续跳到上一行左移,一直移动到上一行的开头,并覆盖了main部分(仔细观察下图,你会发现main里面的字“main”不见了,由于被left遮住了),left上移事后,right就会处于上一行的开头位置,这是再设置right部分margin-left为负的宽度,right就会左移到上一行的末尾。
6.修复覆盖问题
第五步咱们说过设置left和right负的外边距覆盖了main部分的内容,如今想办法修复这个问题,首先给container的左右加上一个内边距,分别为left和right的宽度。
1
2
3
4
5
|
.container{
border
:
2px
solid
yellow;
padding
:
0
220px
0
200px
;
overflow
:
hidden
;
}
|
因为left、main、right三个部分都被container包裹着,因此给其添加内边距,三个子元素会往中间挤。貌似仍是没有修复问题,别着急,咱们已经在container的左右两边留下了相应宽度的留白,只要把left和right分别移动到这两个留白就能够了。可使用相对定位移动left和right部分,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
.
left
,.main,.
right
{
position
:
relative
;
float
:
left
;
min-height
:
130px
;
}
.
left
{
margin-left
:
-100%
;
left
:
-200px
;
width
:
200px
;
background
:
red
;
}
.
right
{
margin-left
:
-220px
;
right
:
-220px
;
width
:
220px
;
background
:
green
;
}
|
至此,咱们完成了三列中间自适应的布局,也就是传说中的圣杯布局。完整的代码以下:
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
<!DOCTYPE html>
<
html
>
<
head
>
<
meta
charset
=
"utf-8"
>
<
title
>圣杯布局</
title
>
<
style
type
=
"text/css"
>
*{margin: 0;padding: 0;}
body{min-width: 700px;}
.header,
.footer{
border: 1px solid #333;
background: #aaa;
text-align: center;
}
.left,
.main,
.right{
position: relative;
float: left;
min-height: 130px;
}
.container{
border: 2px solid yellow;
padding:0 220px 0 200px;
overflow: hidden;
}
.left{
margin-left: -100%;
left: -200px;
width: 200px;
background: red;
}
.right{
margin-left: -220px;
right: -220px;
width: 220px;
background: green;
}
.main{
width: 100%;
background: blue;
}
.footer{
clear: both;
}
</
style
>
</
head
>
<
body
>
<
div
class
=
"header"
>header</
div
>
<
div
class
=
"container"
>
<
div
class
=
"main"
>main</
div
>
<
div
class
=
"left"
>left</
div
>
<
div
class
=
"right"
>right</
div
>
</
div
>
<
div
class
=
"footer"
>footer</
div
>
</
body
>
</
html
>
|
圣杯布局和双飞翼布局解决问题的方案在前一半是相同的,也就是三栏所有float浮动,但左右两栏加上负margin让其跟中间栏div并排,以造成三栏布局。不一样在于解决”中间栏div内容不被遮挡“问题的思路不同。
HTML 结构
1
2
3
4
5
6
7
8
9
|
<
div
class
=
"header"
>header</
div
>
<
div
class
=
"container"
>
<
div
class
=
"main"
>
<
div
class
=
"content"
>main</
div
>
</
div
>
<
div
class
=
"left"
>left</
div
>
<
div
class
=
"right"
>right</
div
>
</
div
>
<
div
class
=
"footer"
>footer</
div
>
|
双飞翼布局的前五步和圣杯布局彻底相同,咱们只须要修改第六步,前面是设置container的内边距以及相对定位来解决这个覆盖问题的,双飞翼布局中,为了main内容不被遮挡,在main里面添加一个子元素content来显示内容,而后设置content的margin-left和margin-right为左右两栏div留出位置。
直接贴出代码,读者能够自行参透他们的异同:
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
<!DOCTYPE html>
<
html
>
<
head
>
<
meta
charset
=
"utf-8"
>
<
title
>圣杯布局</
title
>
<
style
type
=
"text/css"
>
*{margin: 0;padding: 0;}
body{min-width: 700px;}
.header,
.footer{
border: 1px solid #333;
background: #aaa;
text-align: center;
}
.left,
.main,
.right{
float: left;
min-height: 130px;
}
.container{
border: 2px solid yellow;
overflow: hidden;
}
.left{
margin-left: -100%;
width: 200px;
background: red;
}
.right{
margin-left: -220px;
width: 220px;
background: green;
}
.main{
width: 100%;
background: blue;
}
.content{
margin: 0 220px 0 200px;
}
.footer{
clear: both;
}
</
style
>
</
head
>
<
body
>
<
div
class
=
"header"
>header</
div
>
<
div
class
=
"container"
>
<
div
class
=
"main"
>
<
div
class
=
"content"
>main</
div
>
</
div
>
<
div
class
=
"left"
>left</
div
>
<
div
class
=
"right"
>right</
div
>
</
div
>
<
div
class
=
"footer"
>footer</
div
>
</
body
>
</
html
>
|
双飞翼布局比圣杯布局多使用了1个div,少用大体4个css属性(圣杯布局container的 padding-left和padding-right这2个属性,加上左右两个div用相对布局position: relative及对应的right和left共4个属性,;而双飞翼布局子div里用margin-left和margin-right共2个属性,比圣杯布局思路更直接和简洁一点。简单提及来就是”双飞翼布局比圣杯布局多建立了一个div,但不用相对布局了。