最近有一个读者问到,怎样用CSS创建一个居中的页面布局。该读者所追求的,是要达到这样一种效果,就如同在一个1024象素宽的页面上设计出一个800象素宽的表格。这是一种使用很广泛的页面设计方法,按照传统,它要靠嵌套表格才能达到这一效果,因此,这位读者追寻一种用CSS来达到这一效果的方法并不让人惊讶。

用CSS来创建一个居中的页面设计的基本技术相对来说较简单,不过与同类相比,也简单不了太多。让我们看一下,要将这种由来已久的基于表格的设计转变成用CSS,该怎样做。

传统的做法:居中的布局

首先,由于是做比较,让我们来看一个例子,它是一种基于一个居中表格的页面设计。图表A中显示了一个例子,以下是这个例子的编码:

<body> 
<p> </p> 
<table width="80%"  border="0" align="center" cellpadding="0" cellspacing="10"bgcolor="#FFFFFF"> 
  <tr> 
    <td colspan="2"><h2 align="center">Header</h2></td> 
  </tr> 
  <tr> 
    <td width="150px" valign="top"><h4>Navigation</h4> 
      <ul> 
        <li>Let me not to the marriage of true minds</li> 
        <li>Admit impediments; love is not love</li> 
        <li>Which alters when it alteration finds</li> 
      </ul> 
    </td> 
    <td valign="top"><p>Main Content -- Love's not 
 time's fool...</p></td> 
  </tr> 
  <tr> 
    <td colspan="2"><hr /> 
      <p>Footer text -- Admit impediments...</p> 
    </td> 
  </tr> 
</table> 
<p> </p> 
</body>

< table >这个标签包括了以下一些属性,将其宽度定义为页面宽度的80%,并将该表格置于页面的中间。在表格的前面有一个空白段落,这就使得页面的顶端与表格的顶端之间有一些垂直空间。在表格的后面也有一个空白段落,这就使得页面的底端与表格的底端之间也有一些空间。这个表格包括两列三行。顶端的单元被合并了,用来放置页眉,底端的行也合并了,以安置页脚,而中间那些单元则被分为两列,一个供放置主要内容,另一个则是导航工具栏。

这是一个简单的例子,诠释的是一种多年以来广为人们使用的技术。在现今的那些应用软件中,有代表性的主要种包含了嵌套表格,用以创建一种复杂得多的版面设计,不过,它的复杂性虽然被人为加大了,它所采用的基本技术却并没有改变。

将居中的设计转换成使用CSS

要想将这种传统的基于表格的版面设计转换成用CSS,你只要用divs来代替那些表格和表格单元就行了。一个div取代表格本身,另一个取代那些单个的表格单元,这些单个的表格单元定义了主要的版面设计元素,诸如标题,页脚,导航工栏,以及主要内容。每个div都有一个id,且它们的id都是独一无二的,你可以用一个CSS选择器来让它们创建各自不同的样式,每一种样式对应于div中的一种,这种对应关系依据id而建立。那个取代表格的div被标上了id=外部,其它那些div则靠他们各自的功能来鉴别。

这是已校订过的用div代替表格的XHTML的编码:

<body> 
<div id="outer"> 
  <div id="header"> 
    <h2>Header</h2> 
  </div> 
  <div id="nav"> 
    <h4>Navigation</h4> 
    <ul> 
      <li>Let me not to the marriage of true minds</li> 
      <li>Admit impediments; love is not love</li> 
      <li>Which alters when it alteration finds</li> 
    </ul> 
  </div> 
  <div id="main"> 
    <p>Main Content -- Love's not time's fool...</p> 
  </div> 
  <div id="footer"> 
    <p>Footer text -- Admit impediments...</p> 
  </div> 
</div> 
</body>

注意一下所有那些陈述的格式,原来它们被包括在<table>和<td>标签中,现在已经被移走了。而那些位于表格前面和后面的空白段落也都不见了。CSS格式会处理所有的格式化以及空间的问题。

以下是CSS的编码,就是这些编码,将页面设计成一种居中的样式,这种设计与前面所说的基于表格的设计很类似:

body { 
    background-color: #999999; 
    font-size:12px; 
    font-family:Verdana, Arial, Helvetica, sans-serif; 
} 
div#outer { 
    width: 80%; 
    background-color:#FFFFFF; 
    margin-top: 50px; 
    margin-bottom: 50px; 
    margin-left: auto; 
    margin-right: auto; 
    padding: 0px; 
    border: thin solid #000000; 
} 
div#header { 
    padding: 15px; 
    margin: 0px; 
    text-align: center; 
} 
div#nav { 
    width: 25%; 
    padding: 10px; 
    margin-top: 1px; 
    float: left; 
} 
div#main { 
    margin-left: 30%; 
    margin-top: 1px; 
    padding: 10px; 
} 
div#footer { 
    padding: 15px; 
    margin: 0px; 
    border-top: thin solid #000000; 
}

图表B显示了结果,即用CSS执行的一个居中页面的版面设计。

解析CSS编码

与基于表格的版面设计比起来,它的主体样式并没有什么变化。它只不过设置了一下背景颜色,默认正文字体以及尺寸大小。

div#outer是其中的一种样式,它是这一技术的关键。这就是前面提到过的以div取代表格的样式,它创建了居中的盒子,而这个盒子成了包容该页面所有内容的容器。将宽度设置为80%的规则设定了该div的宽度,就跟表格标签的相应属性规定该表格的宽度一样。与此相类似,background-color:#FFFFFF为div建立了一个白色的背景,就如同表格中bgcolor="#FFFFFF"属性为表格设置白色背景一样。margin-top: 50px and margin-bottom: 50px则用顶端和底端的空白来取代表格中用来造成垂直空间的空白段落。

这一技术的关键在于,外部div的中心要安排合适。这里存在一个难题,可以说是我们面临的一个挑战,即div没有像align="center"这样一个属性,这与表格不同,表格中有这样一种属性。你可以在div的母元素(在本案例,指< body >标签)中使用text-align: center来将外部div置于中心位置。尽管除了正文以外,大多数浏览器还会为一些诸如div的块元素使用该队列,但是我们有证据可以证明它是对排列正文这一属性的误用,而且它会使问题复杂化,就如同你创建一些额外的样式来使那些已按正常标准对齐的文字重新回到左边一样。

用CSS来将块元素置于中心位置的正确方法是这样设置:margin-left: auto,margin-right: auto。这就指示浏览器自动计算页面两边合适的空白宽度,从而将div置于中心。border: thin solid #000000这一规则在外部div的周围添加了一个边界,这是因为用CSS添加很容易,而如果用表格的话就很难了。CSS编码中的其它部份则规定了div的页眉,页脚,nav,以及主要内容。

div#header和div#footer则设定了那些div的页边空白以及填料。此外,div#header包含了text-align: center这一规则,它可以将页眉文本置于中心位置,div#footer则包含了border-top: thin solid #000000这一规则,它可以创建一个围绕该div的顶端边缘的边界,而在基于表格的版面设计中,与它相对应的则是位于页脚上方的一些水平线。

在这个居中的盒子的中央,div#nav和div#main建立了两个纵列。在div#nav样式中,float: left这一规则将div推到它的母元素(外部div)的左边,而width: 25%这一规则将该div的宽度设置为它的母元素的25%。由于该nav div被移到了左端,其宽度也被限定了,这就为主要的div留下了活动空间,让它可以移到该nav div的右边,这样就取得了两个纵列的效果。div#main样式包含了左边页面空白30%的规则,以让主要文本排列在一个整齐的纵栏中,而不是分散开来,甚至散到该nav纵栏外面。主要的div左边的空白页面比nav div中左边空白页面的宽度稍稍大一点。在我的“用CSS漂浮来创建一个三栏页面版面设计”一文中,我详细介绍了一种技术,这一技术是用CSS漂浮来创建页面设计中的多个纵列的。