CSS布局始于第2个版本,CSS 2.1把布局分为3种模型:常规流、浮动、绝对定位。CSS 3推出更多布局方案:多列布局、弹性盒、模板层、网格定位、网格层、浮动盒等。本章重点介绍CSS 2.1标准的3种布局模型,它们获得所有浏览器的全面、一致性的支持,被广泛应用。
1、流动布局
在默认状态下,HTML文档将根据流动模型进行渲染,所有网页对象自上而下按顺序动态呈现。改变HTML文档的结构,网页对象的呈现顺序就会发生变化。
流动布局的优点:元素之间不会存在错位、覆盖等问题,布局简单,符合浏览习惯;流动布局的缺点:网页布局样式单一,网页版式缺乏灵活性。
流动布局有如下特征:
- 块状元素自上而下按顺序垂直堆叠分布。块状元素的宽度默认为100%,占据一行显示。
- 行内元素从左到右遵循文本流进行分布,超出一行后,会自动换行显示。
【示例】设计在页面中添加多个对象,浏览器都会自上向下地逐个解析并显示所有网页对象:
html
<div id="contain">
<h2>标题元素</h2>
<p>段落元素</p>
<ul>
<li>列表项</li>
</ul>
<table>
<tr>
<td>表格行,单元格</td>
<td>表格行,单元格</td>
</tr>
</table>
</div>
2、浮动布局
浮动布局能够实现块状元素的并列显示,允许浮动元素向左或向右停靠,但不允许脱离文档流,依然受文档结构的影响。
浮动布局的优点:相对灵活,可以并列显示;
浮动布局的缺点:版式不稳固,容易错行、重叠。
2.1、定义浮动显示
在默认情况下,任何元素都不具有浮动特性,可以使用CSS的float属性定义元素向左或向右浮动,具体语法格式如下:
css
float:none | left | right
取值left表示元素向左浮动,right表示元素向右浮动,none表示消除浮动,默认值为none。
浮动布局有如下特征:
- 浮动元素以块状显示。如果浮动元素没有定义宽度和高度,它会自动收缩到仅能包住内容为止。如果浮动元素内部包含一张图片,则浮动元素将与图片一样宽;如果包含的是文本,则浮动元素将与最长文本行一样宽。而块状元素如果没有定义宽度,则显示为100%。
- 浮动元素与流动元素可以混用,不会重叠,二者都遵循先上后下的显示顺序,受文档流影响。
- 浮动元素仅能改变水平显示顺序,不能改变垂直显示方式。浮动元素不会强制前面的流动元素环绕其周围流动,而总是换行浮动显示。
- 浮动元素可以并列显示,如果宽度不够,则会换行显示。
【示例】设计3个并列显示的方块,通过float定义左、中、右3栏并列显示:
html
<style type="text/css">
body {padding: 0; margin: 0; text-align: center;}
#main { /*定义网页包含框样式*/
width: 400px;
margin: auto;
padding: 4px;
line-height: 160px;
color: #fff;
font-size: 20px;
border: solid 2px red;}
#main div {float: left;height: 160px;} /*定义三个并列栏目向左浮动显示*/
#left {width: 100px;background: red;} /*定义左侧栏目样式*/
#middle {width: 200px;background: blue;} /*定义中间栏目样式*/
#right {width: 100px; background: green;} /*定义右侧栏目样式*/
.clear { clear: both; }
</style>
<div id="main">
<div id="left">左侧栏目</div>
<div id="middle">中间栏目</div>
<div id="right">右侧栏目</div>
<br class="clear" />
</div>
注意:浮动布局可以设计多栏并列显示效果,但也容易错行,如果浏览器窗口发生变化,或者包含框的宽度不固定,则会出现错行显示问题,破坏并列布局效果。
2.2、清除浮动
使用CSS的clear属性可以清除浮动,定义与浮动相邻的元素在必要的情况下换行显示,这样可以控制浮动元素同时挤在一行内显示。clear属性取值包括以下4个:
- left:清除左边的浮动元素,如果左边存在浮动元素,则当前元素会换行显示。
- right:清除右边的浮动元素,如果右边存在浮动元素,则当前元素会换行显示。
- both:清除左右两边的浮动元素,不管哪边存在浮动对象,则当前元素都会换行显示。
- none:默认值,允许两边都可以存在浮动元素,当前元素不会主动换行显示。
【示例】设计一个简单的3行3列页面结构,设置中间3栏平行浮动显示:
html
<style type="text/css">
div {
border: solid 1px red; /* 增加边框,以方便观察 */
height: 50px; /* 固定高度,以方便比较 */}
#left, #middle, #right {
float: left; /* 定义中间3栏向左浮动 */
width: 33%; /* 定义中间3栏等宽 */}
</style>
<div id="header">头部信息</div>
<div id="left">左栏信息</div>
<div id="middle">中栏信息</div>
<div id="right">右栏信息</div>
<div id="footer">脚部信息</div>
如果设置左栏高度大于中栏和右栏高度,则发现脚部信息栏上移并环绕左栏右侧:
css
#left {height:100px; } /* 定义左栏高出中栏和右栏 */
如果为
元素定义一个清除样式:
css
#footer { clear:left; } /* 为脚部栏目元素定义清除属性 */
提示:Clear主要针对float属性起作用,对左右两侧浮动元素有效,对于非浮动元素是无效的。
3、定位布局
定位布局允许精确定义网页元素的显示位置,可以相对原位置,也可以相对定位框,或者是相对视图窗口。
定位布局的优点:精确定位;
定位布局的缺点:缺乏灵活性。
3.1、定义定位显示
使用position属性可以定义元素定位显示,具体语法格式如下:
css
position:static | relative | absolute | fixed
取值说明如下:
- static:表示静态显示,非定位模式。遵循HTML流动模型,为所有元素的默认值。
- absolute:表示绝对定位,将元素从文档流中脱离出来,可以使用left、right、top、bottom属性进行定位,定位参照最近的定位框。如果没有定位框,则参照窗口左上角。定位元素的堆放顺序可以通过z-index属性定义。
- fixed:表示固定定位,与absolute定位类型类似,但它的定位框是视图本身,由于视图本身是固定的,它不会随浏览器窗口的滚动而变化,因此固定定位的元素会始终位于浏览器窗口内视图的某个位置,不会受文档流动影响,这与background-attachment:fixed;属性功能相同。
- relative:表示相对定位,通过left、right、top、bottom属性设置元素在文档流中的偏移位置。元素的形状和原位置保留不变。
3.2、相对定位
相对定位将参照元素在文档流中的原位置进行偏移。
【示例】定义strong元素对象为相对定位,然后通过相对定位调整标题在文档顶部的显示位置:
html
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
p { margin: 60px; font-size: 14px;}
p span { position: relative; }
p strong {/*[相对定位]*/
position: relative;
left: 40px; top: -40px;
font-size: 18px;}
</style>
</head>
<body>
<p> <span><strong>虞美人</strong>南唐\宋 李煜</span> <br>春花秋月何时了?<br>往事知多少。<br>小楼昨夜又东风,
<br>故国不堪回首月明中。<br>雕栏玉砌应犹在,<br>只是朱颜改。<br>问君能有几多愁?<br>恰似一江春水向东流。</p>
</body>
<script>
</script>
</html>
通过下图可以看到,偏移之后,元素原位置保持不变。
3.3、定位框
定位框与包含框是两个不同的概念,定位框是包含框的一种特殊形式。从HTML结构的包含关系来说,如果一个元素包含另一个元素,那么这个包含元素就是包含框。包含框可以是父元素,也可以是祖先元素。
如果一个包含框被定义了相对定位、绝对定位或者固定定位,那么它不仅是一个包含框,也是一个定位框。定位框的主要作用是为被包含的绝对定位元素提供坐标偏移参考。
3.4、层叠顺序
定位元素可以层叠显示,类似Photoshop的图层模式,这样就容易出现网页对象相互遮盖现象。如果要改变元素的层叠顺序,可以定义z-index属性。如果取值为正整数,数字越大,则优先显示出来;如果取值为负数,数字越大,则优先被遮盖。
3.5、案例:设计定位模板页
html
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
body { /*定义窗体属性*/
margin: 0; /*清除IE默认边距*/
padding: 0; /*清除非IE默认边距*/
text-align: center; /*设置在IE浏览器中居中对齐*/}
#contain { /*定义父元素为相对定位,实现定位框*/
width: 100%; /*定义宽度*/
height: 310px; /*必须定义父元素的高度,该高度应大于绝对布局的最大高度,否则父元素的背景色就无法显示,且后
面的布局区域也会无法正确显示*/
position: relative; /*定义为相对定位*/
background: #E0EEEE;
margin: 0 auto; /*非IE浏览器中居中显示*/}
#header, #footer { /*定义头部和脚部区域属性,以默认的流动模型布局*/
width: 100%;
height: 50px;
background: #C0FE3E;
margin: 0 auto; /*非IE浏览器中居中显示*/}
#sub_contain1 { /*定义左侧子元素为绝对定位*/
width: 30%; /*根据定位框定义左侧栏目的宽度*/
position: absolute; /*定义子栏目为绝对定位*/
top: 0; /*在定位框顶边对齐*/
left: 0; /*在定位框左边对齐*/
height: 300px; /*定义高度*/
background: #E066FE;}
#sub_contain2 { /*定义右侧子元素为绝对定位*/
width: 70%; /*根据定位框定义右侧栏目的宽度*/
position: absolute; /*定义子栏目为绝对定位*/
top: 0; /*在定位框顶边对齐*/
right: 0; /*在定位框右边对齐*/
height: 200px; /*定义高度*/
background: #CDCD00;}
</style>
</head>
<body>
<div id="header">标题栏</div>
<div id="contain">
<div id="sub_contain1">左栏</div>
<div id="sub_contain2">右栏</div>
</div>
<div id="footer">页脚</div>
</body>
<script>
</script>
</html>
在上面示例中,设计左右栏(<div id="sub_contain1">、<div id="sub_contain2">)
绝对定位显示,两栏包含框(<div id="contain">)
为相对定位显示,这样左右栏就以包含框为定位参照。
由于定位框(<div id="contain">)
的高度不会跟随子元素(<div id="sub_contain1">、<div id="sub_contain2">)
的高度自适应调整,因此要实现合理布局,必须给父元素(<div id="contain">
)定义一个固定高度,这样才能显示中间行的背景,页脚栏目(<div id="footer">)
才会跟随其后正常显示。
注意:本例设计思路的前提条件是必须确保左右栏(<div id="sub_contain1"><div id="sub_contain2">)
的高度是固定的。如果是动态内容,就不应该采用本节模板进行设计。
4、案例实战
假设有如下文档主结构固定不变,将练习使用CSS设计不同的呈现版式:
html
<div id="container">
<div id="header">
<h1>页眉区域</h1>
</div>
<div id="wrapper">
<div id="content">
<p><strong>1.主体内容区域</strong></p>
</div>
</div>
<div id="navigation">
<p><strong>2.导航栏</strong></p>
</div>
<div id="extra">
<p><strong>3.其他栏目</strong></p>
</div>
<div id="footer">
<p>页脚区域</p>
</div>
</div>
4.1、设计固宽+弹性页面
本案例版式设计导航栏与其他栏目并为一列固定在右侧,主栏以弹性方式显示在左侧,实现主栏自适应页面宽度变化而侧栏宽度固定不变的版式效果,结构设计如下图所示:
本示例的样式代码如下:
css
div#wrapper { /* 主栏外框 */
float:left; /* 向左浮动 */
width:100%; /* 弹性宽度 */
margin-left:-200px /* 左侧外边距,负值向左缩进 */}
div#content { /* 主栏内框 */
margin-left:200px /* 左侧外边距,正值填充缩进 */}
div#navigation { /* 导航栏 */
float:right; /* 向右浮动 */
width:200px /* 固定宽度 */}
div#extra { /* 其他栏 */
float:right; /* 向右浮动 */
clear:right; /* 清除右侧浮动,避免同行显示 */
width:200px /* 固定宽度 */}
div#footer { /* 页眉区域 */
clear:both; /* 清除两侧浮动,强迫外框撑起 */
width:100% /* 宽度 */}
补充文本内容后的效果:
4.2、设计两栏弹性页面
在两栏浮动版式中,如果设置两列宽度都为自适应,那么设置起来会容易得多。例如,定义两栏版式中主栏向左浮动,宽度为70%,导航栏向右浮动,宽度为29.9%。
css
div#wrapper {
float:left; /* 向左浮动 */
width:70% /* 百分比宽度 */}
div#navigation {
float:right; /* 向右浮动 */
width:29.9% /* 百分比宽度 */}
div#extra {
clear:both; /* 清除左右浮动 */
width:100% /* 满屏显示 */}
本案例版式设置导航栏与其他栏目并为一列固定在右侧,主栏目以弹性方式显示在左侧,实现主栏自适应页面宽度变化,而侧栏宽度固定不变的版式效果,如下图所示:
设计的方法是采用负外边距进行调节,核心样式如下所示:
css
div#wrapper { /* 主栏外框 */
float:right; /* 向右浮动 */
width:100%; /* 弹性宽度 */
margin-right:-33%; /* 右侧外边距,负值向右缩进 */}
div#content { /* 主栏内框 */
margin-right:33%; /* 右侧外边距,正值填充缩进 */}
div#navigation { /* 导航栏 */
float:left; /* 向右浮动 */
width:32.9%; /* 固定宽度 */}
div#extra { /* 其他栏 */
float:left; /* 向左浮动 */
clear:left; /* 清除左侧浮动,避免同行显示 */
width:32.9% /* 固定宽度 */}
div#footer { /* 页眉区域 */
clear:both; /* 清除两侧浮动,强迫外框撑起 */
width:100% /* 宽度 */}
为了避免在IE7或者其他标准浏览器窗口中出现y轴滚动条,此时可以为body元素增加overflow-x:hidden;声明隐藏该滚动条:
css
body { overflow-x:hidden;}
4.3、设计三栏弹性页面
本案例通过浮动布局的方法,以百分比为单位设置栏目的宽度,版式结构示意图如下图所示:
本案例采用负外边距的方法进行设计,这里设计三列都向左浮动,然后通过负外边距定位每列的显示位置,布局示意图如下图所示:
注意,其他栏目在不受外界干扰的情况下会浮动在导航栏的右侧,但是并列浮动的总宽度超出窗口宽度就会发生错位现象。如果没有受负外边距的影响,则会显示在第2行的位置,通过外边距取负值,强迫它们显示在主栏区域的上面。核心样式如下所示:
css
div#wrapper { /* 主栏外包含框基本样式 */
float:left; /* 向左浮动 */
width:100% /* 百分比宽度 */}
div#content { /* 主栏内包含框基本样式 */
margin: 0 25% /* 在左右两侧预留侧栏空间 */}
div#navigation { /* 导航栏基本样式 */
float:left; /* 向左浮动 */
width:25%; /* 百分比宽度 */
margin-left:-100% /* 左外边距取负值进行定位 */}
div#extra { /* 其他栏基本样式 */
float:left; /* 向左浮动 */
width:25%; /* 百分比宽度 */
margin-left:-25% /* 左外边距取负值进行定位 */}
div#footer { /* 页脚包含框样式 */
clear:left; /* 清除左右浮动 */
width:100% /* 百分比宽度 */}
三列弹性布局的版式设计效果如下图所示:
4.4、设计两栏固宽+弹性页面
单纯的弹性或者固定版式布局相对来说都比较好控制,但是如果要设计一列弹性、两列固定的版式就比较麻烦。不过灵活使用负外边距在网页布局中的技巧,可以解决类似复杂的布局。
本案例网页结构继续沿用上一节的模板示例结构。通过浮动布局的方法,以百分比和像素为单位来设置栏目的宽度,版式结构示意图如下图所示:
要定义导航栏和其他栏的宽度固定,不妨选用像素为单位,对于主栏可以采用百分比为单位,然后通过负外边距定位每列的显示位置。布局示意图如下图所示:
注意,其他栏目在不受外界干扰的情况下会浮动在导航栏的右侧,但是并列浮动的总宽度超出窗口宽度就会发生错位现象。如果没有受负外边距的影响,则会显示在第2行的位置,通过外边距取负值,强迫它们显示在主栏区域的上面。核心样式如下所示:
css
div#wrapper { /* 主栏外包含框基本样式 */
float:left; /* 向左浮动 */
width:100% /* 百分比宽度 */}
div#content { /* 主栏内包含框基本样式 */
margin: 0 200px /* 在左右两侧预留侧栏空间 */}
div#navigation { /* 导航栏基本样式 */
float:left; /* 向左浮动 */
width:200px; /* 固定宽度 */
margin-left:-100% /* 左外边距取负值进行定位 */}
div#extra { /* 其他栏基本样式 */
float:left; /* 向左浮动 */
width:200px; /* 固定宽度 */
margin-left:-200px /* 左外边距取负值进行定位 */}
一列弹性、两列固定版式的布局效果如下图所示: