CSS实务排版技巧、秘诀与技术
自从网页标准计划 (The Web Standards Project) 提出浏览器升级方案 (Browser Upgrade Initiative) 后,无数的网站设计师开始采用较为符合标准的网站设计方式:他们用 CSS 来设计版面,以取代传统使用的表格。
"表格已死......"
有些设计师在 Jeffrey Zeldman 的指导下,用撰写教学文件的方式帮助我们解决第一道难题 – 不使用表格,网页会缺乏设计感。起初他们的重心放在撰写几篇以 CSS 的定位能力取代表格的专栏:如此一来,网站设计师就能把网页的架构与内容完整地分离。在 Eric Costello 的 glish 网站及 Rob Chandanais 的 Blue Robot 网站都有许多相关的技术文件。
许多人也一起参与,包括制作 Box lesson 的 Owen Briggs,以及撰写相关讨论的 Eric Costello 与 Tantek Çelik。Dotfile、Web Nouveau (译注:已经无法连结) 列举了数百个利用 CSS 设计版面的网站。
"......表格长存"
当大家可以利用这些资源,只靠着 CSS 的定位能力来设计一般性版面时,我们这些设计师却发现有某些实作上的问题,可以用表格轻易解决,而使用 CSS 时则会遇到一些麻烦。像这样的问题都会以 "Tables are dead ... long live tables." 这个标题发表在 Webdesign-L 网站上。
问题
假设你要将一堆缩图连结到较大尺寸的版本 – 这种网页相当常见。除此之外,你希望每张缩图的正下方都有个简短的标题。接着,为了有效利用浏览器窗口的空间,你希望让缩图跟标题成对地排成一列,并会随浏览器窗口宽度自动分行 (wrap,即流动式设计)。随着最后一个要求,我们放弃表格,进入了 CSS 的王国。
一步步来
让我们一步步来。第一个要求是缩图的正下方要有个标题。作法相当直接了当:在你的 HTML 里放上图片,接着一个断行 (BR),再把标题放在一个段落 (P) 里并且置中 (利用 CSS)。
接着我们要让这些缩图跟标题成对地排列在浏览器窗口里。使用表格排版时,这一对对的缩图跟标题会被分别放置在 TD 里。在使用 CSS 排版时,我们要把它们分别放置在 DIV 里。为了让它们能水平排列在窗口上,我们用 CSS 让这些 DIV 往左浮动 (FLOAT)。
这时候 CSS 看起来应该像这样:
div.float {
float: left;
}
div.float p {
text-align: center;
}
而 HTML:
<div class="float"> <img src="image1.gif" width="100" height="100" alt="图 1" /><br /> <p>标题 1</p> </div> <div class="float"> <img src="image2.gif" width="100" height="100" alt="图 2" /><br /> <p>标题 2</p> </div> <div class="float"> <img src="image3.gif" width="100" height="100" alt="图 3" /><br /> <p>标题 3</p> </div>
而在浏览器里应该会看到:

标题 1

标题 2

标题 3
下一个要求得靠 CSS 解决。我们要让图片跟标题成对地自动换行,以配合浏览窗口的宽度。让 DIV 往左浮动 (FLOAT) 已经解决了这个问题。只要我们多放几张缩图,它们就会在浏览窗口里自动换行 (只要改变浏览窗口的宽度,你就可以看到流动式设计的作用):

标题 1

标题 2

标题 3

标题 1

标题 2

标题 3
现在假设你希望同时在网页上显示好几类的缩图,并利用背景颜色或边界等外观条件帮它们分组。这时候只要用一个容器 (container) DIV 把它们包在一起就好:
div.container {
border: 2px dashed #333;
background-color: #ffe;
}
但这时候麻烦来了。当你在 CSS 里将一个组件浮动 (FLOAT) 以后,它就不再占据任何 "空间",因此背景及边界都会在图片的正下方出现,而不是绕着图片。所以我们必须在容器 DIV 里多放点东西,比方说一个间隔 (spacer) DIV:
div.spacer {
clear: both;
}
其次是 HTML (注意在容器 DIV 的上下方都有个间隔 DIV):
<div class="container"> <div class="spacer"> </div> <div class="float"> <img src="image1.gif" width="100" height="100" alt="图 1" /><br /> <p>标题 1</p> </div> <div class="float"> <img src="image2.gif" width="100" height="100" alt="图 2" /><br /> <p>标题 2</p> </div> <div class="float"> <img src="image3.gif" width="100" height="100" alt="图 3" /><br /> <p>标题 3</p> </div> <div class="spacer"> </div> </div>
结果如下:

标题 1

标题 2

标题 3
根据 sam marshall 的原始码制作。
巢状 DIV 与巢状 TABLE 有什么不一样?
好吧,我们有了一堆的巢状 (nested) DIV,这比巢状表格好在哪里?答案是在于这些卷标的设计观点上。DIV 暗示着一种逻辑或结构上的分组,即使它们以巢状表示,仍然具有标记的结构性。在我们的例子里,我们把缩图跟它们的标题分成一组 (第一层),再将这些成对的缩图跟标题依照相似性分组 (第二层)。这些都是利用 DIV 卷标把结构上的分组处理得相当好的范例。
然而表格暗示的是一种行与列的标头 (header) 跟每个字段资料的关系。当我们利用表格设计版面时,我们就丧失了表格结构的意义。让我们回过头来用 HTML 设计版面,巢状表格只会让问题复杂化。
窗体功能
另一个常见的表格排版应用是排列窗体 (FORM) 里的组件与描述。关于这是不是表格的合适应用尚有很多争论,而就像我们即将看到的,CSS 技术对类似的排版需求也很有用。
一个典型的窗体版面里,在左方的是描述,紧靠着右边界,在右方的是组件,紧靠着左边界。一切事物都在中央交会:
根据 Eric Meyer 的原始码设计概念制作。
上面这个窗体没有使用到表格。我们又再度使用到浮动 (FLOAT) 来达成定位的工作。戏法是这样的:我们用一个 DIV 模仿表格的列。然后我们创造两个 SPAN,一个给描述、另一个给组件。把描述的 SPAN 往左浮动,组件的 SPAN 往右浮动。让描述 SPAN 里的文字往右靠,让组件 SPAN 里的文字往左靠。
所以 CSS 应该长这样:
div.row {
clear: both;
padding-top: 10px;
}
div.row span.label {
float: left;
width: 100px;
text-align: right;
}
div.row span.formw {
float: right;
width: 235px;
text-align: left;
}
上面的 CSS 也设了 SPAN 的宽度。宽度可以像是范例里的绝对值,或者也可以用百分比表示。百分比最多是到 100% 或少一点点,依照你设的留白跟边界而定 (还有你设计的容器)。在范例里我用另一个 DIV 把窗体包起来,以设定边界与背景。
范例 HTML:
<div style="width: 350px; background-color: #cc9;
border: 1px dotted #333; padding: 5px;
margin: 0px auto";>
<form>
<div class="row">
<span class="label">姓名:</span><span
class="formw"><input type="text" size="25" /></span>
</div>
<div class="row">
<span class="label">年龄:</span><span
class="formw"><input type="text" size="25" /></span>
</div>
<div class="row">
<span class="label">鞋子尺寸:</span><span
class="formw"><input type="text" size="25" /></span>
</div>
<div class="row">
<span class="label">附注:</span><span
class="formw">
<textarea cols="25" rows="8">
快! 来写点东西......
</textarea>
</span>
</div>
<div class="spacer">
</div>
</form>
</div>
追求卓越
你也许会注意到,上面容器 DIV 的 STYLE 里有一个属性:margin: 0px auto;。在符合标准的浏览器里,它会让
DIV 往中间对齐。一些浏览器 (如 Windows 底下的 IE5.x) 会忽略这一点,却会错误地让有 text-align:
center 的 DIV 往中间对齐。想让 DIV 在这些浏览器往中间对齐的话,你可以用有 text-align:
center 的 DIV 把另一个有 margin: 0px auto; 的 DIV 包起来 (里面的
TEXT-ALIGN 是 left,所以文字会正常排列)。详见 Rob Chandanais 在 Layout Reservoir 网站撰写的置中对齐技术(1, 2)。
分隔差异
在处理本质上相对的事物时,也常会用到与前面类似的表格排版设计。这次你不是让它们在中央交会,而是让两个组件摆在浏览器窗口的两侧。这也许是一个你想让商标放在页面右上角,而让导览组件放在页面左上角的案例:
在这里我们使用跟窗体范例里一样的 DIV.ROW,但这次会使用不同的 SPAN。左边的 SPAN 往左浮动,而且文字往左靠。右边的 SPAN 往右浮动,而且文字往右靠。
CSS:
div.row span.left {
float: left;
text-align: left;
font-weight: bold;
color: #fff;
width: 49%;
}
div.row span.right {
float: right;
text-align: right;
font-weight: bold;
color: #fff;
width: 49%;
}
HTML:
<div style= "width: 90%; background-color: #666; border: 1px solid #333; padding: 0px; margin: 0px auto;"> <div class="spacer"></div> <div class="row"><span class="left"> 首页 > 产品</span> <span class="right"> [商标]</span></div> <div class="spacer"></div> </div>
CSS 求助
ACRONYM 与 ABBR 卷标虽然只在少数情况派上用场,却有不错的实用价值,可以配合着 TITLE 属性来解释头字语或缩写。但即使网页有提供文字来协助网站参观者了解缩写或头字语的意义,现在大部分的浏览器不会为这个卷标作出任何的警示。所以让我们从 CSS 来着手。
你可以在样式表里为这些卷标加上底线,让它们能引起注意。透过浏览器的支持,你也可以用 CSS 把光标换成 "求助" 符号 (通常用问号表示)。当然你也可以不用被 HTML 卷标限制。创造一个叫 .help 的类别,再用 SPAN 来为那些容易让读者混淆的字词添加信息。
CSS 范例:
abbr, acronym, .help {
border-bottom: 1px dotted #333;
cursor: help;
}
这个 CSS 配合缩写或头字语卷标的 TITLE 属性使用,可以产生跟超级链接不一样的底线效果。把光标改成 "求助" 暗示着这些文字是不能按的,而 TITLE 属性则会解释缩写或头字语。我最早是在 Sander Tekelenburg 的网站上看到这种做法。
请三思而后行......
我最先是在 Bos 跟 Lie 的 Cascading Style Sheets 读到关于将串行 (LIST) 改成行内 (inline) 显示的文章。后来我在 Christopher Schmitt 的 BabbleList 网站率先看到了这个技巧的实际应用。这个戏法让串行水平地显示在一行里;也就是说从:
- 项目一
- 项目二
- 项目三
转换成:
- 项目一
- 项目二
- 项目三
如果加上些留白跟边界的效果:
- 项目一
- 项目二
- 项目三
CSS:
li.inline {
display: inline;
padding-left: 3px;
padding-right: 7px;
border-right: 1px dotted #066;
}
li.last {
display: inline;
padding-left: 3px;
padding-right: 3px;
border-right: 0px;
}
HTML:
<ul> <li class="inline">项目一</li> <li class="inline">项目二</li> <li class="last">项目三</li> </ul>
结束了?或只是刚刚开始......
我希望藉由分享这些技巧、戏法与技术,刺激你在网站上使用更多 CSS 排版技巧,并且继续获得及分享新的技巧、戏法与技术。
—Mark Newhouse
作者
Mark Newhouse是国家天文台的网站设计师,他正慢慢地把网站改成 CSS 为基础的设计。