第5章 CSS布局   网页是一种在浏览器上展示的平面设计作品,网页布局就是将网页元素合理排列在 网页版面上,达到美观大方、井然有序的效果。使用CSS 进行网页布局,本质是利用标准 流、浮动或定位属性的性质对网页布局元素进行合理排列。 5.1 浮动 在标准流中,块级元素的盒子都是上下排列,行内元素的盒子都是左右排列,如果仅 按照标准流的方式进行排列,就只有这几种可能性,限制太大。CSS 的制订者也想到了这 样排列限制的问题,因此又给出浮动和定位方式,从而使排版的灵活性大大提高。 如果希望相邻的块级元素盒子左右排列(所有盒子浮动) , 或者希望一个盒子被另一 个盒子中的内容所环绕(一个盒子浮动)做出图文混排的效果,最简单的实现办法就是运 用浮动(float)属性使盒子在浮动方式下定位。 5.1.1 盒子浮动后的特点 在标准流中,一个块级元素在水平方向会自动伸展,在它的父元素中占满整行;而在 竖直方向和其他元素依次排列,不能并排,如图5. 1 所示。使用“浮动 ” 方式后,这种排列 方式就会发生改变。 CSS 中有一个float 属性,默认值为none,也就是 标准流通常的情况,如果将float 属性的值设为left 或 right,元素就会向其父元素的左侧或右侧靠紧,同时盒 子的宽度不再伸展,而是收缩,在没设置宽度时,会根 据盒子里面的内容确定宽度。 下面通过一个实验演示浮动的作用,基础代码如 下,这个代码中没有使用浮动。 所示 【。 例5. 1 】 盒子不浮动时,其显示效果如图5. 1 图5.1 三个盒子在标准流中  141  div{   padding:10px;  margin:10px;  border:1px dashed #111;   background-color:#90baff;  } .father{   background-color:#ff9;  border:1px solid #111;  }
  
Box-1
  
Box-2
  
Box-3
1. 一个盒子浮动 接下来在例5.1 代码中添加一条CSS 代码,使Box.1 盒子浮动。 【例5.2】 只有一个盒子浮动时,其显示效果如图5.2 所示。  .son1{float:left;} 可发现,给Box.1 添加浮动属性后,Box.1 的宽度不再自动伸展,而且不再占据原来 浏览器分配给它的位置。如果再在未浮动的盒子Box.2 中添一行文本,就会发现Box.2 中的内容是环绕着浮动盒子的,如图5.3 所示。 图5.2 第一个盒子浮动     图5.3 增加第二个盒子的内容 总结: 设置元素浮动后,元素发生了如下改变。 ● 浮动后的盒子将以行内块(inline.block)元素显示,即宽度会自动收缩,但保持块级 元素的其他性质。 ● 浮动的盒子将脱离标准流,即不再占据浏览器原来分配给它的位置。 ● 未浮动的盒子将占据浮动盒子的位置,同时未浮动盒子内的内容会环绕浮动后的 盒子。 所谓“脱离标准流”,是指元素不再占据在标准流下浏览器分配给它的空间,其他元 素就好像这个元素不存在一样。例如,图5.2 中,当Box.1 浮动后,Box.2 就顶到了Box.1 的位置,相当于Box.2 视Box.1 不存在一样。但是,浮动元素并没有完全脱离标准流,这 表现在浮动盒子会影响未浮动盒子中内容的排列,例如Box.2 中的内容会跟在Box.1 盒 子之后排列,而不会忽略Box.1 盒子的存在。 2. 多个盒子浮动 【例5.3】 在例5.1 基础上将Box.1 和Box.2 都设为左浮动。  142  .son1,.son2{ float:left; } 此时显示效果如图5.4 所示(在Box.3 中添加了一行文本)。可发现,Box.2 盒子浮 动后仍然遵循上面浮动的规律,即Box.2 的宽度也不再自动伸展,而且不再占据原来浏览 器分配给它的位置。 如果将Box.1 的浮动方式改为右浮动: . son1{float:right},则显示效果如图5.5 所 示,可看到Box.2 移到了Box.1 的前面,这说明元素浮动后其显示顺序和它们在代码中的 位置可能并不一致。 图5.4 设置两个盒子浮动     图5.5 改变浮动方向 【例5.4】 将Box.1、Box.2 和Box.3 都设为左浮动,其显示效果如图5.6 所示。  .son1,.son2,.son3{ float:left; } 图5.6 三个盒子都浮动 可发现,三个盒子都浮动后,就产生了块级元素 水平排列的效果。同时,都脱离标准流,导致其父元 素中的内容为空。 对于多个盒子浮动,除遵循单个盒子浮动的规 律外,还有以下两条规律。 ● 多个浮动元素不会相互重叠,一个浮动元素 的外边界(margin)碰到另一个浮动元素的外边界后便停止运动。 ● 如果包含的容器太窄,无法容纳水平排列的多个浮动元素,那么最后的浮动盒子会 向下移动(见图5.7)。但如果浮动元素的高度不同,那么当它们向下移动时,可能 会被卡住(见图5.8)。 图5.7 没有足够的水平空间      图5.8 Box.3 被卡住了 5.1.2 清除浮动元素的影响 clear 是清除浮动属性,它的取值有left、right、both 和none(默认值),若设置盒子的 clear 属性值为left 或right,则表示该盒子的左边或右边不允许有浮动的元素。若clear 属  143 性值设置为both,则表示两边都不允许有浮动元素,因此该盒子将会在浏览器中另起一行 显示。【 例5.5】 在图5.5 两个盒子浮动的基础上,设置Box.3 清除浮动,即在例5.1 基础上 设置如下CSS 代码,其显示效果如图5.9 所示。  .son1{float:right;}.son2{float:left;} .son3{clear:both; } 可以看到,对Box.3 清除浮动(clear:both;),表示Box.3 的左右两边都不允许有浮动 的元素,因此Box.3 会移动到下一行显示。 实际上,clear 属性既可以用在未浮动的元素上,也可以用在浮动的元素上。 【例5.6】 在例5.5 基础上对Box.3 同时设置清除浮动和浮动。  .son3{clear:both; float:left;} 则效果如图5.10 所示。可以看到,Box.3 的左右仍然没有浮动的元素。 图5.9 对Box.3 清除浮动       图5.10 对Box.3 设置清除浮动和浮动 由此可见,清除浮动是清除其他盒子浮动对该元素的影响,而设置浮动是让元素自身 浮动,两者并不矛盾,因此可同时设置元素清除浮动和浮动。 由于上下margin 叠加现象只会发生在标准流的情况下,而浮动方式下盒子的任何 margin 都不会叠加,因此设置盒子浮动并清除浮动后,上下两个盒子的margin 不叠加。 在图5.10 中,Box.3 到Box.1 之间的垂直距离是20px,即它们的margin 之和。 5.1.3 清除浮动影响的方法 在网页布局中,浮动元素会影响其他元素的正常排列,导致网页元素不能按我们的意 愿显示。因此,设置元素浮动后,应尽量清除该元素浮动对其他元素的影响。对于下列两 种情形,应采用不同的方法清除浮动。 1. 来自子元素的浮动 如果一个父元素内所有的子元素都浮动,一定要记得对这个父元素进行清除浮动处 理,否则该父元素下面的元素会顶到浮动元素的位置上,如图5.11 所示。 【例5.7】 清除子元素浮动对父元素的影响,其显示效果如图5.12 所示。  div{  padding:10px;   margin:10px;   border:1px dashed #111;  background-color:#9bf; } .father{  background-color:#ff9;  border:1px solid #111; }  144    .cls { clear: both; }   .son1{  float:right; }  .son2{ float:left; }   .box3{background:#ccf;}
    
Box-1
Box-1
    
Box-2
    
    
Box-3
     图5.11 未清除子元素浮动时的效果      图5.12 清除子元素浮动后的效果 这种方法添加了一个元素(.cls)专门用来清除浮动,如果不愿添加新元素,可使用伪 元素的方法设置清除浮动。下面的代码可在父元素内部的末尾添加一个伪元素。 【例5.8】 使用伪元素清除浮动的经典代码,其显示效果如图5.12 所示。  .father:after { content: ''; display: table; clear: both; } .father { .zoom: 1; }    /.兼容IE6、IE7,如不需要,则可去掉./ 注意: 对于一个父元素内的所有子元素都浮动,一种极其错误的做法是设置父元素 的高度来掩饰浮动对它的影响,如.father{height:50px;},这样做只是掩饰了浮动,并没有 清除浮动的影响,虽然使父元素看起来正常了,但父元素下面的元素仍然会顶到上面去。 因此,在CSS 布局时,若发现一个元素移动到它原来位置的左上方或右上方,并且和 其他元素发生了重叠,则很可能是受到了其他盒子浮动的影响。 2. 来自兄弟元素的浮动 如果一个元素前面的兄弟元素浮动(见图5.13),就可以对紧邻该浮动元素的后一个 元素进行清除浮动处理。例如,若不希望Box.3 受前面兄弟元素浮动的影响,则可对 Box.3 清除浮动。 【例5.9】 对Box.3 清除浮动,其显示效果如图5.14 所示。  div{   padding:10px 20px;   margin:7px;  border:1px dashed #111;   background-color:#9bf;  float:left; }    /.所有div 都浮动./ .box3{background:#ccF;   clear:both;}    /.对Box-3 清除浮动./
Box-1
Box-1
Box-2
Box-3
Box-4
 145 图5.13 清除浮动前      图5.14 清除浮动后 除直接对后面的元素清除浮动外,还可以增加一个元素专用于清除浮动。 【例5.10】 增加一个元素专用于清除浮动,其显示效果如图5.14 所示。  
Box-1
Box-1
Box-2

    
Box-3
Box-4
虽然增加一个元素使代码变得冗余了一些,但这样使每个元素的功能变得更加清晰, 因此推荐使用。 3. 避免滥用浮动 元素浮动会对其他元素的布局产生影响,因此应避免滥用浮动,例如: ● 为了使元素宽度收缩而设置浮动,由于浮动元素的宽度会自动收缩(称为主动包 裹),于是就用浮动属性代替width 属性。实际上,若只需要改变元素的宽度,则应 设置width 属性,而不是float。 ● 为了清除浮动的影响而浮动。清除浮动正确的做法是使用clear 属性(例如图5.9 中的Box3),但如果对Box3 设置float 属性,再设置width 值,似乎也能达到图5.9 中的效果,但实际上这种错误的做法将导致更多的元素受到浮动的影响而布局混 乱。因此,如果要清除浮动,就应对相应的元素设置clear 属性,而不是float。 5.2 浮动的应用举例 利用单个盒子浮动,可制作出图文混排及首字下沉等效果。利用多个盒子浮动,则可 制作出水平导航条等效果。 5.2.1 图文混排及首字下沉 如果一个盒子浮动,另一个盒子不浮动,那么浮动的盒子将被未浮动盒子的内容所环 绕。如果这个浮动的盒子是图像元素,而未浮动的盒子是一段文本,就实现了图文混排 效果。【 例5.11】 图文混排效果实例,其显示效果如图5.15 所示。  

在遥远古希腊的大草原中,……这就是“人马族”。

人马族里唯独的一个例外--奇伦……

在图文混排的基础上让第一个汉字也浮动,同时变大,则出现了首字下沉的效果。 【例5.12】 在例5.11 基础上添加首字下沉效果代码,其显示效果如图5.16 所示。  p:first-letter{  font-size:3em;  float:left;  } 图5.15 图文混排效果   图5.16 首字下沉和图文混排效果 若浮动第一个段落,再给段落添加边框,则会出现文章导读框效果。 【例5.13】 文章导读框效果,如图5.17 所示。  p{  margin:0;  font-size:14px;  line-height:1.5;   text-indent: 2em;  } p:first-child{  width:160px;  float:left;   /.第一个段落浮动./   margin:10px 10px 0 0;  padding:10px;   border:3px gray double;  background:#9BD;  }

在遥远的古希腊大草原中……

“半人半兽”代表着理性与非理性……

图5.17 导读框效果 从以上3 个例子可以看出,网页中无论是图像还是文本,任何元素在排版时都应视为 一个盒子,而不必在乎元素的内容。  147 5.2.2 水平导航条 在4.2.3 节中,利用元素的盒子模型制作了一个竖直导航条。把这个竖直导航条变 为水平导航条,有例5.14 和例5.15 两种方法。 【例5.14】 设置所有a 元素浮动,这是因为多个元素浮动,这些元素就会水平排列。 当然,水平导航条一般不需设置宽度,可以把width 属性去掉。图5.18 是水平导航条的效 果,它的结构代码如下。 图5.18 水平导航条   CSS 样式主要是给元素设置盒子和背景属性,代码如下。  #nav{font-size: 14px;} #nav a {   color: red;  background-color: #9CF;   text-align: center;  text-decoration: none;   padding:6px 10px 4px;  border: 1px solid #39F;   float:left;  /.使a 元素浮动,实现水平排列./  } #nav a+a{margin-left:5px;} /.设置第2 到最后一个a 元素有5 像素的左间距./ #nav a:hover {color: white; background-color: #930;}/.设置前景色和背景色./ 提示: ● 本例使用相邻选择器(#nav a+a)选中了除第1 个a 元素外的其他a 元素,再给它 们设置左边距,这样就实现了第一个a 元素没有左边距。 ● 设置浮动后的元素将自动以块级元素显示,因此就不需要再对#nav a 选择器添加 display:block 属性了,因为这是多余的。 【例5.15】 将所有a 元素的display 属性设置为inline.block,inline.block 元素兼有块 级元素和行内元素的特点,表现在它可以像块级元素一样设置宽度和高度,同时它又像行 内元素一样是从左到右排列,宽度不会自动伸展。其CSS 关键代码如下。  #nav a {     ……   display: inline-block;}  /.将例5-14 中的float:left;改成这条,效果和 例5-14 一样./ 5.2.3 新闻栏目框 在网站的首页中,文字内容一般被组织成栏目框的形式。网站是按栏目组织内容的, 因此栏目框是最常见的网页界面元素,掌握栏目框的制作是网页制作中一项重要的基 本功。  148 【例5.16】 一种简洁风格的栏目框,其显示效果如图5.19 所示。 图5.19 简洁风格的栏目框 栏目框可分为栏目标题栏和内容列表区。对于栏目标题栏,常见的结构代码如下:  
  

基层动态

    更多>>
可见,栏目标题栏由2 部分组成,即左边的栏目标题和右边的“更多”链接,因此需要 2 个HTML 元素来存放。为了将栏目标题栏组合成一个整体,使用了一个div 元素将这 两元素包裹起来。 对于“更多”链接,之所以将其放入一个span 元素中,是为了将CSS 布局样式和CSS 文本样式分离,即对span 元素设置布局样式,而对a 元素设置文本样式。span 元素在这 里起到了布局元素的作用。 对于内容列表区域,从语义上看,它是一个典型的无序列表,因此使用ul 元素描述列 表区域,其结构代码如下。   然后将标题栏代码和内容列表区域代码用一个div 元素包含起来,即得到栏目框的 完整结构代码如下:  
  

基层动态

    更多>>  
 149 提示: 由于网页中一般有多个栏目框,因此对栏目框中的元素一般设置class 属性, 而不设置id 属性,从而使栏目框的样式代码可以被很多风格相似的栏目框共用。 接下来设置栏目框的样式,从外表看,栏目框的文本样式主要是设置文字大小和行 距。栏目框的布局样式主要是使栏目标题和“更多”分布在容器两端。新闻标题和日期 也分布在容器的两端。这称为两端对齐,要实现两端对齐,主要有以下三种方法。 【例5.17】 实现两端对齐的方法一: 左右元素都浮动法。 设置左边的元素左浮动,右边的元素右浮动。这时因为两个盒子都浮动,不占据外围 容器的空间,所以还必须设置外围盒子的高度,使它在视觉上能包含两个浮动的盒子。标 题栏的CSS 样式代码如下。  .news{ width:420px; margin-left: 20px;} .title {   height: 40px;  line-height: 40px; /.设置标题栏高度并使内容垂直居中./   border-bottom: 2px solid #025483;  } .title h2{  height: 40px;   float: left;      /.标题左浮动./   font-size: 18px;  color: #000;   margin:0;    /.去掉h2 标记的默认上下边界./   } .title .more{     float: right;      /.“更多”右浮动./   height: 22px;     padding-right:10px;  }  /.“更多”右边保留一点间距./ .more a{font-size:14px; text-decoration:none; color:#666;} 内容列表区域的CSS 样式代码如下。  .list_one {   min-height: 245px;     /.设置内容区域的最小高度./   margin-top:10px;  /.设置第一条新闻上面的间隙./} .list_one li {   line-height: 30px;height:30/p.x;垂 直 居中./   color: #999;font-size: 14px;   padding-left: 2px;  } .list_one li a {  float: left;   /.标题左浮动./} .list_one li b {  float: right; font-weight:normal;   /.日期右浮动./ } 【例5.18】 实现两端对齐的方法二: 右边元素右对齐法。 这种方法仍然设置左边元素左浮动,但设置右边的元素不浮动,并将它设置为块级元 素,使得该元素的盒子能伸展到整行,再设置它的内容右对齐,而浮动元素位于其左边,则 效果一样。以内容区域为例,关键CSS 代码如下。  .list_one li b {float: right;…} /.删除5-17.html 中的float: right;./ .list_one li {……     text-align:right; }    /.在5-17.html 基础上添加这行./ 说明: 这种方法实际上可将包裹日期的b 元素去掉。