友好连接

2008年12月4日星期四

标记语言——清单

在网络上几乎每个页面都能找到清单. 超链接清单;购物车物品清单;你中意的电影清单...甚至是整个网站的导航清单.可能在某些人看来,清单的建立是随心所欲的,但是我们要去探索发现的正是如何建立清单以及集中几种常用方法的优缺点.稍后,我们会列出几个如何美化普通清单一集他们的优缺点的示例来.

咱们去购物吧

最初,我打算用一个细目清单(洗衣清单)来作为本章的示例,但是很快的,我就意识到,我根本不知道这种清单中应该包括那些细目,所以...看在示例的份上,就用食物来举例吧!

让我们设想,你需要把一个食品清单放到你自己的网站上去,你可能会为为什么要把食物清单放到网站上去而感到不解,厄,这个可能就离题了,我们只是需要一个可以开始为清单思考的理由罢了...

在页面上,假设我们想让清单看起来像......好吧,看起来就像一个清单 — 也就是一长串垂直的列表,里面的每项内容独占一行:

Apples
Spaghetti
Green Beans
Milk

看起来非常简单,不是吗?和页面设计开发的许多方面类似,我们能够通过很多不同的方法达成相同(或者类似)的效果.与这本书后面所有的示例相同的,我将以eXtensilble HyperText Markup Language(XHTML)的观点来展现所有示例 — 并且确认选用的方法都使用正确的标记语法,遵照World Wild Web Consortium (W3C)所制定的各种标准.

我们可以轻松的在每个项目后面加上个< br />标签就搞定了,或者也能使用各种清单项目标签来完成这个工作,现在我们就来看3种完全不同的方法,以及每种方法的特点.

提问时间

下面哪种方法最适合建立食品清单?

方法 A: 用 < br /> 换行

Apples< br />
Spaghetti< br />
Green Beans< br />
Milk< br />

方法A的确是一种被广为传用的方法,可能有数百万个页面使用过,事实上,我相信我们中的每个人都会偶尔因为使用了这种方法而感到内疚,对吧?我们希望在清单中的每一项都独占一行,而加入了换行标签(在这里使用的是符合xhtml标准的自关闭标签< br />)就会在每个项目后面生成断行,这就是他所有的效果了,看起来,挺管用的.

但是,如果我们想要给这个食品清单加上与其他页面元素不同的样式的时候该怎么办呢?比方说:如果想让清单的所有链接的颜色变成红色而不同于默认的蓝色,或者想要改变字体的大小时该怎么办呢?真的我们什么都做不了,我们被为整份html文档设定的字体风格(如果有设定的话)限制住了.同时,如果在清单外面没有任何标签围绕,我们就没办法为清单制定一个独特的css规则.

折行

如果我们在清单中加入一个类似"Five Foot Loaf of Anthony's Italian Bread".根据这个清单在页面里摆放的位置,在水平空间不足或者浏览者的浏览器视窗比较窄的情况下,过长的项目就会冒着折到下一行的风险.

同时我们也要考虑到视力不佳的用户可能会把预设的字体大小改大以便增加可读性,我们认为能够像 图1 - 1 一样把项目轻松的布置在窄栏里,但是很有可能会像 图 1 - 2 这样在意料之外的地方发生断行,读者调大字体时,设计的样式就完全变样了.


图 1 - 1 预设文字大小的范围


图 1 - 2 调大文字大小后的相同内容


唔......现在,我想我应该要买面包是没错,但是在 图 1 - 2 里,面包上面的两行字实在感到疑惑.

在使用小屏幕装置像是移动电话或者PDA阅读长行时,类似的换行问题就会展露它丑恶的嘴脸,骨灰级的科技爱好者可能会随手带着记录购物清单的Palm Pilot(而不是传统意义上的纸和笔)当他在超级市场里面闲逛的时候,最后却在货架中寻找一种叫"Anthony's Italian"的东西.

在这里我要在本质上阐明一个观点 - 使用方法A ,并没有把阅读网页时的这些设计师们所无法控制的变数考虑在内.

方法 B: 会咬人的小圆点

< li>Apples< br />
< li>Spaghetti< br />
< li>Green Beans< br />
< li>Milk< br />

大多数成熟的浏览器在解析< li>标签时都会在清单项目的左侧加上圆点符号,你能通过方法B来达到这个效果,在需要圆点符号时加入< li>标签.但是如果< li>标签没有被包含在适当的父标签中时,那有些浏览器不会显示出圆点符号,适当的父标签包括强大的< ul>以及< li>的另一个父标签< ol>(有序清单),这个会在稍后有更多的讨论.

圆点符号的出现在某种程度上的确能够帮助解决换行问题,每个食品项目在左边会有小圆点符号,如果某个项目过长折行的话,旁边没有小圆点符号应该就可以很明显的看出这并不是全新的项目,但是方法B仍然有显示结果意外的问题:它并不符合标准.

麻烦检查一下

根据W3C的XHTML 1.0规范,所有的标签最后都必须要闭合起来 — 如果我们还是继续使用上面示例中的写法,让所有的< li>保持开放状态的话,那就太丢脸了!

在行末使用< br />标签来模拟正确的无序清单自动换行的显示效果,但其实我们有更好的方法.

一向以来,养成编写正确的标签语法的习惯非常重要,正确的编写标签语法,我们可以不必在未来担心由于没有闭合标签或者不正确的嵌套元素所带来的问题.如果有人阅读这些源代码的话,也可以使他们更加深入的理解源代码想要达成的效果.

记得善用W3C的在线检测工具(http://validator.w3.org/)来检查你提交的URI或者上传的文档,最终你会觉得这样做非常值得.

方法 C: 接近了

< li>Apples< /li>
< li>Spaghetti< /li>
< li>Green Beans< /li>
< li>Milk< /li>

方法C更加的接近完美的解决方案了,但是还是悲惨的失败了,原因还是非常明显:这仍然不符合标准的标记语法.

我们已经把< li>标签关闭了,因为< li>是块级元素(block-level),因此在使用上可以去掉< br />标签,这样每个项目都独占一行,但是,我们却漏了它的外层结构,缺少了一个表示"这群项目是一个清单!"的元素.

从语义化的角度看这个问题也非常重要 — 清单是一组项目归属在一起,因此我们应该为它们加上这样的标签,此外,使用正确的清单标签能清楚告诉浏览器,软件或者显示设备"这组项目是个清单!",语义化标签的意义就在于将内容根据他们所属的类别进行结构性的搭建.

块级(block-level)与行内(inline): HTML元素可以分为块级与行内两大类型,块级元素会从新行开始,最后接着一个断行,而行内元素则会与其他的行内元素显示在同一行内,块级元素可以包括其他块级元素和行内元素,而行内元素里面不能包含块级元素.

块级元素包括:< div>,< h1>-< h6>,< form>等等,行内元素包括:< span>,< strong>,< em>,< q>等等.

如果以纯XML的角度来看我们的食品清单,或许我们会使用这样的方式进

行标注:


< grocerylist>
< item>Apples< /item>
< item>Spaghetti< /item>
< item>Green Beans< /item>
< item>Milk< /item>
< /grocerylist>

整个清单有一个容器元素< grocerylist>,所有的食品项目都包含在里面,以这种方式归类项目,可以基于XML的应用轻松的从清单里面抽取出所有的项目.

举例来说,一个开发者需要编写一份XSLT样式表,将这个清单转成xhtml,纯文字,甚至是pdf文件,因为列表项目的结构表现的非常清晰,所以程序可以轻松的获取信息并作出一些有用的处理.

虽然在这本书里我并不直接处理XML,但是这些原则也适用于XHTML世界,如果文档使用非常语义化的标签结构,将可以提升文档今后的灵活度,不管是为结构清晰的文档加上css样式表还是修改容易理解的文档 — 只要提供正确的结构,就能节省许多今后在维护时可能浪费掉的时间.

接着,我们仔细的看看方法D,看看这些怎么样结合在一起 — 一个能被大多数浏览器和屏幕阅读器识别并显示的文档,同时又允许我们使用各种不同的方法为文档加上样式.

方法 D: 愉快的包装者

< ul>
< li>Apples< /li>
< li>Spaghetti< /li>
< li>Green Beans< /li>
< li>Milk< /li>
< /ul>

是什么让方法D变得如此特别?首先,它的语法完全正确,正确的无序清单具备了< ul>容器元素,同时每个项目都已< li>元素闭合起来.到这里你会想问,我们花费了那么多力气只来示范为了正确而正确?我们来看看这样做能带来的好处:

由于我们正确的标记了我们的食品清单,每个项目都会独占一行(因为块级元素< li>的关系),而且大多数浏览器会给每个项目的左边增加一个小圆点符号,并且进行正确的行内缩进换行.(见图 1 - 3)


图1 - 3

PDA,移动电话,或者其他的小屏幕设备的用户也可以看到清楚的,关系明确的组织方式,由于我们告诉了这些设备这些资料的类型(在这个示例里是清单),因此这些设备能够根据自己的能力决定怎样显示才能达到最好的效果.

如果因为放大字号或者缩小浏览器视窗宽度等原因造成换行,那么被换行的文字会行内缩进到与第一行文字对齐的位置,所以不管浏览器环境如何,都可以轻松的识别每个清单项目.

概要

我们已经针对每种可能的方法进行讨论了,现在让我们快速的回顾一下刚才讨论过的东西:

方法A:
无法为清单加上独特的样式
在狭窄的列里或者小屏幕设备上,较长的内容可能会因为换行而造成误解
缺乏语义性
方法B:
增加小圆点符号来帮助识别每个项目,但是一些浏览器会在缺失父级标签< ul>时可能不显示小圆点符号
没有放在< ul>中,缺少闭合标签< /li>意味着难于加上样式
不标准
方法C:
加上了闭合标签< /li>后就不需要< br />标签了
省略了< ul>元素使得我们难于为这个清单添加特定的样式
不标准
方法D:
符合标准!
使文档语义化,结构性
大多数浏览器都会在每个项目左边显示小圆点符号
在大多数浏览器上都会在换行后行内缩进
很容易就可以定义特定的css样式
正如你所见,你可以从一个看起来很简单的问题上获得不少知识.就算是你已经在你所有的页面上都是用了方法D,还是可以你为什么这样做比较好,我们会在这本书里一直探索"为什么"的问题,让你在各种情况下选用最恰当的方法.

技巧延伸

让我们利用我们构造出来的食品清单来试看看几种用定义css样式的方法,我们将抛开预设样式,加入自定义的圆点符号,接着把它转成横向,把它变作一个导航条.

扔掉圆点

"我真的不喜欢食品清单里的那些个小圆点,我想我还是用回< br />吧."

不需要回到老习惯 — 我们仍然可以使用我们结构化的无序清单,然后使用css关闭掉小圆点符号和行内缩进,关键在于我们保留了清单的结构,然后以css具体的呈现出来.

首先,加上一段去掉圆点符号的css规则:

ul{
list-style:none;
}

显示的结果见图1 - 4


图 1 - 4 去掉小圆点符号

接着我们来去掉行内缩进,根据预设值,所有无序清单左边都会留有一些内补丁(padding),但是不用担心,我们可以随心所欲的裁掉:

ul{
list-style:none;
padding-left:0;
}

显示结果可见图1 - 5


图 1 - 5

虽然图 1 - 5 看起来和使用了几个< br />标签的效果几乎一样,但是它还是符合标准的,结构化的无序列表 — 不管什么浏览器,设备都能正常显示,如果必要的话只需要更新几条css规则就能换上不同的样式了.

使用自定义圆点符号来完成自己的想象

或许你想要在清单里保留小圆点符号,但是不想用浏览器无趣的默认设置,更像用自己的小圆点图案.有两种方法可以达成你想要的 — 而我更推崇第二种方法,因为它可以在各种浏览器之间更好的兼容.

第一种方法是用 list-style-image 属性来指定用来替代默认小圆点的图片名称.

ul{
list-style-image:url(i_hot.gif)
}

这是最简单的方法,但是它会在不同浏览器之间的图片垂直对齐位置上有所不同,有些浏览器会把图片和项目文字中线对齐,也有的会把图片放得稍微高一点,它们之间有一点不一致.

为了避免 list-style-image 造成的几个流行浏览器之间的对齐问题,我比较喜欢用一种替代方法:把图片作为每个< li>元素的背景.

首先,我们要去掉默认的圆点,然后再加上我们自己的背景图片:

ul{
list-style:none;
}
li{
background-image:url(i_hot.gif) no-repeat 0 50%;
padding-left:25px;
}

no-repeat 会告诉浏览器不把背景图片进行平铺操作(默认会平铺),而0 50%会告诉浏览器把背景图片放置在距离左边 0 像素,距离上面 50% 的地方,让背景图片 i_hot.gif 根据中线对齐.我们也可以用精确的像素来指定位置,比如说 0 6px 会让图片放置在距离左边0像素,距离上面 6 像素的位置上.

我们还要在清单项目的左边加上17像素的内补丁(padding),以便我们把宽20像素高11像素的图片能够完整显示出来,同时又留有一点空白,而不会和文字有重叠.这些数据应该根据你所使用的图片尺寸进行调整( 图 1 - 6 )


图 1 - 6 自定义圆点图片的清单

导航清单

在我的个人网站(http://www.simplebits.com/)里我分享了几种将无序清单转化为水平导航条的方法,用普通的,结构化的XHTML就像我们的食品清单示例那样创造一个类似分页标签(Tab)的效果.

我们把那个食品清单转换成一个网上超市的导航条(这个超市只卖几种东西就是了...).

我们想要这个导航条以水平的方式呈现,并且能够在鼠标划过,选中时有某种强调显示,以便我们模拟分页标签的效果.

首先,我们为清单加上一个id,这样我们就可以为它单独定义css样式了,同时我们也将把每个食品项目转成链接.

< ul id="minitabs">
< li>< a href="/apples/">Apples< /a>< /li>
< li>< a href="/spaghetti/">Spaghetti< /a>< /li>
< li>< a href="/greenbeans/">Green Beans< /a>< /li>
< li>< a href="/milk/">Milk< /a>< /li>
< /ul>

现在,开始加上一些辅助的css:



#minitabs{
margin:0;
padding:0 0 20px 10px;
border-bottom:1px solid #696;
}
#minitabs li{
margin:0;
padding:0;
display:inline;
list-style:none;
}

在这里我们已经完成了去掉默认圆点符号和行内缩进的工作,我们也把 display设置成inline,往垂直清单转化成水平清单迈出了第一步,同时我们也加上了底部边框以便区分出整个链接组.

把清单转化成水平导航条的第二步,是将我们的链接全部浮动到左边显示,我们同样为所有的超链接加上简单的样式:定义外边距和内补丁的大小:

#minitabs {
margin: 0;
padding: 0 0 20px 10px;
border-bottom: 1px solid #696;
}
#minitabs li {
margin: 0;
padding: 0;
display: inline;
list-style-type: none;
}
#minitabs a {
float: left;
line-height: 14px;
font-weight: bold;
margin: 0 10px 4px 10px;
text-decoration: none;
color: #9c9;
}

在这里我们将清单中所有的元素都定义float:left,是为了让他们能水平显示排列于一行之内,同时我们也加上了了一些色彩,把链接改成粗体,拿掉了链接底部的下划线.

然后,为鼠标滑过或选中的链接创建一个模拟分页标签的边线:

#minitabs {
margin: 0;
padding: 0 0 20px 10px;
border-bottom: 1px solid #696;
}
#minitabs li {
margin: 0;
padding: 0;
display: inline;
list-style-type: none;
}
#minitabs a {
float: left;
line-height: 14px;
font-weight: bold;
margin: 0 10px 4px 10px;
text-decoration: none;
color: #9c9;
}
#minitabs a.active, #minitabs a:hover {
border-bottom: 4px solid #696;
padding-bottom: 2px;
color: #363;
}
#minitabs a:hover {
color: #696;
}

为了强调链接,我们在鼠标划过或选中时增加一个4像素高的底边,我们也可以使选中的< a>标签保持强调效果,只要加上class="active":

< li>< a href="/spaghetti/" class="active">spaghetti< /a>< /li>

这个 active类别与 a:hover的共用相同的css样式.(图 1 - 7)


图1 - 7

我在自己的网站(http://www.simlpebits.com/)以及2003年7月重构Inc.com(http://www.inc.com/)里面都用到了这个技巧.如果你需要更多的示例代码,可以自由访问这两个网站并查看他们的源代码.

只需要加上一些内补丁和边框,就可以达到各种类似分页标签的效果了,到目前为止,我们甚至连一张图,一句javascript都没有使用,而仅仅只用到了基本的xhtml结构就构成了我们的食品清单,这实在是太棒了!

迷你分页标签的外观

如果你想要和平常的,方方正正的css边框不太一样的效果的话,只需要作出一点点小修改,我们就可以使用图片来创建有趣的导航条了.

我们使用和之前完全一样的无序清单,以及十分类似的css:

#minitabs {
margin: 0;
padding: 0 0 20px 10px;
border-bottom: 1px solid #9FB1BC;
}
#minitabs li {
margin: 0;
padding: 0;
display: inline;
list-style-type: none;
}
#minitabs a {
float: left;
line-height: 14px;
font-weight: bold;
padding: 0 12px 6px 12px;
text-decoration: none;
color: #708491;
}
#minitabs a.active, #minitabs a:hover {
color: #000;
background: url(tab_pyra.gif) no-repeat bottom center;
}

这段css大概看起来和上一个示例中的几乎一样,最主要的区别在我们用 background-image 定义了在鼠标划过或选中的时候显示在链接底部中间的图片来代替了原本的4个像素高的底部边框.(图 1 - 8)


图 1 - 8: 使用背景图的迷你分页标签导航

这里的技巧在于选择一个足够窄的图片,必须能够塞进最短的导航条项目下,这样一来我们只需要一张图片来强调导航链接而不必为各种不同宽度准备不同的图片,当然,在你自己的项目中,你可以选择各种图片使用(图 1 - 9):


图 1 - 9: 使用其他图片的例子

这些迷你分页标签的源码和示例都可以在www.simplebits.com/tips/ 找到,更多的为清单添加样式的方法可以参考 Mark Newhouse在A List Apart杂志上发表的"Taming Lists"的文章(www.alistpart.com/stories/taminglists/)

标记语言——引用

“Misquotations are the only quotations tha are never misquoted” (只有错误的引用永远不会被误用)——Hesketh Pearson

所有类型的网站都经常会使用引用,不管是引用其他网页、作者或出版物的内容,以标准方法标记引用内容是非常有好处的。因为一旦完成结构之后,只需要一些简单的css就能把引用内容变成漂亮的设计元素。

让我们看看下面三种用来标记引言的方法,同时讨论一下每个方法的优缺点,在我们找到最棒的方法之后,再来研究这几个相关元素与样式在标记冗长引用内容时哪种方法最佳。

我们来仔细研究每个方法,并且找到最便于完成任务的“工具”,更重要的是,要弄清楚为什么它是最棒的工具。

方法A:缺乏语义

< p>"Misquotations are the only quotations that are never misquoted."< /p>
< p>— Hesketh Pearson< /p>

在页面内使用引用的时候,通常会希望引用的外观与其他文字不同,最好能提示读者这段内容来自其他地方,同时(使用适当方法)与一般内容的阅读顺序分离。

方法A的标记方法与页面上的其他段落并没有不同,因此我们没有办法为它设定不同的样式,内容里的双引号就变成了引用内容的唯一提示了。

顺便提一下,在这个方法与之后的两个例子中 — 是长破折号(也就是“—”)的HTML字码,这里使用了10进制表示方法。这是支持所有浏览器最可靠的方法。或者,你也可以使用 —

方法B:以class处理?

< div class="quotation">
< p>Misquotations are the only quotations that are never
misquoted.< /p>
< p>— Hesketh Pearson < /p>
< /div>

由于在包围引用内容的< div>标签里加了class="quotation",因此我们能够为它指定独特的css样式,但是HTML拥有专门解决这个问题的完美标签,因此建立这个特别分类似乎有点多余,我们马上就会看到这个完美的HTML标签.

在我们开始使用加上类的< div>之后,如果我们想让整个网站的样式保持一致,在标记各处引用的时候都会被限制在这个方法中,我们必须背下这个标签引用的特别的语法以便未来使用.如果我们管理的是以< div>与分类属性标记各种结构元素的大型网站,那就十分头疼了.因为事情很快就会变得十分散乱,而你将会需要一份记录所有自定分类的名称、用途的表格了。

使用不支持或者关闭css的浏览器访问这个方法标记的引用时也会发生问题。由于< div>只是一般容器,因此里面的内容没有任何预设样式.对使用旧版本浏览器,文字模式浏览器,屏幕阅读器的人来说,看到没有css的引用,和页面里其他内容完全一样.

方法C:< blockquote>最棒

< blockquote>
< p>Misquotations are the only quotations that are never
misquoted.< /p>
< p>— Hesketh Pearson < /p>
< /blockquote>

W3C建议使用< blockquote>标记长引用(区块级内容),这个标签正是为了处理我们正在讨论的状况设计的,借着使用这个标签,我们能为内容加上结构意义,同时能提供独特的标记以便为可视化浏览器设定样式.

没有加上任何样式的话,< blockquote>标签的内容会缩进显示,这是最基本的视觉提示,足以将引用内容和一般文字区别开.然而,这种预设样式却引来了一种恶劣的习惯,我们稍后就会讨论.

用起子钉钉子

或许因为< blockquote>的内容看起来就像内缩过的段落,或者是从前需要缩进某个区块,某段文字的时候,你就会使用< blockquote>搞定.

不幸的,这是个非常糟糕的习惯,补救方法之一,是改用适当的元素加上css的padding-left或margin-left属性,以往< blockquote>常被这样滥用来设定显示效果,而不是用来标记内容结构.

由于有这种坏习惯,因此W3C建议将描述引用符号的责任交给样式表,不希望浏览器主动显示,在本章的"技巧延伸"中,我们会看到如何巧妙的加上漂亮的引用符号.

概要

让我们快速回顾一下,为什么方法C在标记长引用的时候比其他两种方法棒.

方法A:

无法轻易加上不同的样式,使它与页面其他内容区分开来
不提供任何引用的语义,结构标识.

方法B:

加上独特的分类让我们易于指定样式,但是< blockquote>可用,所以根本不需要
如果想要维持页面/网站的风格一致,在标记未来新增引用的时候,我们就会被限制在这个方法里面

方法C:

这是W3C为这个目标所设计的元素,能够标识内容的意义,结构.
容易使用CSS为< blockquote>元素内部的引用加上独特样式.
缺少CSS的时候,< blockquote>预设的表现方式足以让可视化,非可视化浏览器提供暗示.
现在是为< blockquote>打扮一番,寻找样式创意的好机会.

技巧延伸

我们来看看怎么为< blockquote>标签的引用内容上加上一些有创意的样式.不过在这之前,让我们先谈谈cite属性与行内引用.

给好奇宝宝的参考资料

对迂腐的标题感到厌倦了么?很好,我也是.在讨论引用的时候,一定得提到cite属性,根据W3C的规范,cite属性的目的是让设计者参照引用的出处,也就是说,如果引用是从其他网页摘录下来的,我们就可以在cite属性内记录那份网页的url.

让我们看看怎么书写这个属性:

< blockquote cite="http://www.somewebsite.com/path/to/page.html"
< p>Misquotations are the only quotations that are never
misquoted.< /p>
< p>— Hesketh Pearson < /p>
< /blockquote>

在书写这段文字的时候,大多数浏览器都不会特别处理我们刚加上的cite属性,但是在能够处理cite属性的进阶css技巧或者scripting程序出现之后,事情就会开始变得有趣了.引言出处本身也是帮助描述标签内容的额外资讯,未来将会十分具有价值.

试着把加上cite想成把硬币丢进储蓄罐,这些硬币现在值不了多少,但是未来你将会庆幸一路上你有把它们全部存起来.

行内引用

要怎么处理简短,应该是在行内参考的引用呢?举例来说,如果你在这句子中提到其他人说过的话,这时就可以用< q>标签:

I said, < q>Herman, do you like bubblegum?< /q> And he said,< q>Yes, the kind that comes with a comic.< /q>

这在可视化浏览器上多半会显示成这样:

I said, Herman, do you like bubblegum? And he said, Yes, the kind that comes with a comic.

不需要引号

大多数可视化浏览器会在使用< q>和< /q>的时候自动加上引号,因此你不用自己输入,W3C也建议加上lang属性标识所应用的内容语言,某些语言可能会显示不同的引号.

I said, < q lang="en-us">Herman, do you like bubblegum? < /q> And he said, < q lang="en-us">Yes, the kind that comes with a comic.< /q>



可以在W3C的网站上找到所有可用的语言代码.(www.w3.org/TR/html4/struct/dirlang.html#langcodes)


嵌套的行内引用

你也能在引用内容中嵌套引用其他文字,搞混了么?我也是,来看看示例吧:

I said, < q lang="en-us">Herman, do you like bubblegum? < /q> And he said, < q lang="en-us">Yes. Bubblegum is what Harry calls < q lang="en-us">delicious< /q>.< /q>

此时浏览器会在适当的地方使用双引号和单引号,像是这样.

I said, "Herman, do you like bubblegum?" And he said, "Yes. Bubblegum is what Harry calls 'delicious'."

为< blockquote>加上样式

Fast Company从杂志存档里选出每日引言放在首页,已经行之有年了,为了保留FC的印刷体裁和强调效果,因此有很长一段时间这个引言被做成GIF图片,让设计者能以任何方式处理字型,达成期望的效果.

在2003年早秋,差不多是在我看着至爱的红袜队迎向历史性冠军之时,我决定抛弃GIF图片,换上加了样式的< blockquote>标签.

从易用性角度看,以文字显示引用内容很有道理,由于无法重现GIF带来的体裁便利性,因此我们面对着美化引言的挑战.当然,CSS帮了很大的忙.

背景的引用符号

想法十分简单,就是分别制作开引号,闭引号两张图片,选用的色调足以隐没在略为重叠的引用文字后面,引用同时也放在了270像素宽,淡灰色的圆角方块内,以便配合网站整体风格.第三张图片用来完成圆角效果以及引号.这三张图片完全以各个元素debackground属性放在css中.

我们先以photoshop或者你惯用的图形处理程序建立这些图片.这边是个使用特殊字体的好机会,你能选用一般浏览器不支持的字体,在Fast Company的例子里,使用了杂志上的引号字体.

三张图片

图4-1 是刚建立的三张图片,一张是开引号,顶部圆角,一张是闭引号,最后一张是底部的两个圆角.

这三张图片背景都是透明的,以便我们用css来控制背景的颜色.同时我们以白色制作了圆角,灰色制作了引号.



图 4-1 为了制作引号圆角而以Photoshop创建的3张图片

标记元素

目前,你只能以background或者background-image属性为一个元素指定单张背景图,因此,我们将为< blockquote>里的每个段落加上id.

我们会把一段内容标为#quote,另一段内容标为#other,使得最后有三个独特元件能够制定背景图.

来看看我们会在这个示例接下来的步骤里中使用的标记方法:

< blockquote cite="http://www.somesite.com/path/to/page.html">
< p id="quote">< strong>Misquotations< /strong> are the only quotations
that are < strong>never< /strong> misquoted.< /p>
< p id="author">—Hesketh Pearson< /p>
< /blockquote>

这样就完成了使用背景图的预备工作了

三个元素,三张背景图

如先前所述,现在你只能以background或者background-image属性为一个元件指定一张背景图,因此我们将善用示例中的三个元素,也就是< blockquote>,#quote段落和#author段落,以便指定三张背景图完成我们期望的效果.

在新增元素前,看看还有那些元素可以用上,这是个很好的习惯.你经常能在完善,结构化的标记源代码中找到适合加上css的元素,大成你需要的效果.

我们先从< blockquote>元素的css规则开始书写:

blockquote {
width: 270px;
margin: 0;
padding: 0;
font-family: georgia, serif;
font-size: 150%;
letter-spacing: -1px;
line-height: 1em;
text-align: center;
color: #555;
background: #eee url(top.gif) no-repeat top left;
}

我们把整个组件的宽度设为270像素,与提供顶部圆角,开引号效果的top.gif宽度相同,同时我们也照顾了一下文字效果,为它指定了字体,大小和颜色.最后,我们置中所有文字,并以最后一条规则指定了背景色,背景图以及背景图的显示位置.

去掉< blockquote>的内外补丁也很重要,我们该为每个段落元素加上内补丁,这能让我们避免windows版IE5错误解析CSS盒模型的问题.我们会在本书第二部分进一步讨论盒模型的细节.

接着,让我们帮#quote段落设定样式:

blockquote {
width: 270px;
text-align: center;
margin: 0;
padding: 0;
font-family: georgia, serif;
font-size: 150%;
letter-spacing: -1px;
line-height: 1em;
color: #555;
background: #eee url(top.gif) no-repeat top left;
}
#quote {
margin: 0 10px 0 0;
padding: 20px 10px 10px 20px;
background: url(end_quote.gif) no-repeat right bottom;
}

借着指定margin:0 10px 0 0;我们能取消浏览器在段落上下的预设补丁,以便使用精确的内补丁设定值排好版面.然而我们还是在右侧加上了10像素的外边界,以便把闭引号挤开,配合左边的效果.如果我们不留下这10像素的话,开引号就会紧靠整个外边框的最右边.另一种可行方法是直接在图片右边加上适当的留白.

同时也要留意,我们指定把背景图(开引号)放在< blockquote>的右侧(right)底部(bottom).

最后,我们要在作者段落(#author)放上最后一张背景图,也就是引言底部的圆角.

blockquote {
width: 270px;
text-align: center;
margin: 0;
padding: 0;
font-family: georgia, serif;
font-size: 150%;
letter-spacing: -1px;
line-height: 1em;
color: #555;
background: #eee url(top.gif) no-repeat top left;
}
#quote {
margin: 0 10px 0 0;
padding: 20px 20px 10px 20px;
background: url(end_quote.gif) no-repeat right bottom;
}
#author {
margin: 0 10px 0 0;
padding: 0 0 10px 0;
color: #999;
font-size: 60%;
background: url(bottom.gif) no-repeat bottom;
}

我们再度取消段落上下的预设补丁,改在底部加上一些内部补丁.第三张图片已经到位了.为引用内容加上两个圆角,借以padding代替margin设定author部分的排列方式,我们得以让圆角图出现在适当的位置上,也就是最底部.

结果

图4-2是典型的现代浏览器所能看到的结果,圆角外边框十分完整,两个引号则漂亮的藏在文字后方.这个方法最棒的地方是整个外框可以扩大,代表你能放进去任何长度的引用内容,外框会配合引言长度自动放大或缩小(自适应),而且引号与圆角都会停留在适当的位置.这也代表视力不佳的使用者方法字体时,引用于外框的设计不会被破坏.



图 4-2,使用三个背景图与文字的引用样式示例.

强调特殊文字

我为Fast Company额外加上的引用样式之一是在引用范围内使用< strong>标签来强调特定重点文字的效果.这能进一步模仿杂志上使用的排版风格.

借着使用< strong>,我们能确保大多数不支持样式或是非可视化浏览器仍然可以得到粗体或强调的效果(在这个例子中很合理),同时我又能以CSS特别指定改用深色显示< blockquote>范围内的< strong>标签.



标记源代码内容需要略作修改,以< strong>标示几个选定的单字.

< blockquote cite="http://www.somesite.com/path/to/page.html">
< p id="quote">< strong>Misquotations< /strong> are the only quotations
that are < strong>never< /strong> misquoted.< /p>
< p id="author">—Hesketh Pearson< /p>
< /blockquote>

然后这段是需要加上的额外css规则的内容:

#quote strong {
color: #000;
font-weight: normal;
}

此时,任何出现在引用范围之内的< strong>就会变成黑色(不能更黑了),另外由于引用的其他部分使用了一般的font-weight,因此我们以normal取代< strong>预设的粗体样式.

使用< strong>标签的结果可以在图4-3里看到,我们强调了"Misquotation"和"never"这两个字.



图4-3 以< strong>强调特定单字的< blockquote>样式

这回退化到什么程度?

我们知道CSS与几张背景图能把引用美化到什么程度了,但是在不支持CSS的浏览器或设备上会变成什么样呢?这个方法的显示效果会退化到什么程度呢?

恩,幸好我们以原始设计用途使用了< blockquote>元素,因此不支持样式的浏览器,电话,PDA以及屏幕阅读器都能正确的处理他的内容.举例来说,图4-4就是这个页面去掉CSS之后的样子.我在引用前后加上了虚构的文字,以便让你看到完整的效果.



图4-4. 图4-3去掉CSS之后的样子

结论

在仔细研究过几种标识引用的不同方法之后,我们很容易就能找到处理问题的正确工具,也就是< blockquote>,单纯为了缩进文字而使用< blockquote>的时代已经过去了,我们现在用它来标记长引用.

一旦完成了结构,就能轻易为< blockquote>加上样式,使他们区别于一般内容之外,同时仍能让不支持CSS的浏览器或其他设备正常解析内容

标记语言——邪恶的表格?

你知道吗?不知何时开始,使用表格居然变成充满罪恶的举动了?的确,以web标准编写网页的最大迷思就是"不要再使用表格了,永远不要!" 听起来表格就和瘟疫一样必须躲开,必须密封起来丢进满是灰尘的柜子里,当成是网络发展时代早期流传下来的古董保存起来.

如此的厌恶从何而来呢? 或许一开始十分单纯,至少拥有一个好的理由.很多人会理直气壮的宣扬抛弃传统的表格嵌套与补空gif图片的布局方式,改用灵活的结构化的css布局方式的好处.我们可能就开始抽丝剥茧的去掉所有的表格,甚至开始顽固的坚持把所有的表格驱逐出去 — 根本不分场合.

书中稍后我们会看到css布局的方法和这样做带来的所有好处.但是现在我们还是先来看看如何在适当的场合—也就是标记数据列表的时候使用表格.我们会研究几个简单的方法是我们的数据列表变得更容易使用,更漂亮.

完全就是表格

在标记列表数据时,我们绝对没有理由不去用表格标签.但是等等,什么才是列表数据?这边有一些例子:

日历
电子数据表
图表
时间行程表
对这些例子以及许多其他情况来说,必须使用非常复杂严格的css特效才能让资料看起来像表格,或许你能想象,用巧妙的css浮动,定位所有项目之后得到的是不兼容的矛盾的结果,更别提拿掉css之后,准确读出每笔资料大概会成为不可能完成的任务.事实上,我们不必畏惧表格—我们应该用他们设计之初的目标来使用它们.

适合所有人的表格

表格找来谩骂的原因之一是如果没有小心使用的话会存在可用性缺陷.举例来说:屏幕阅读程序难以正确读出内容,而小屏幕设备经常被用来布局的表格扰乱,但是我们有一些简单的方法增加列表数据表格的可用性.同时建立灵活的结构,方便未来以css设定样式.

让我们看看 图3-1 中的简单示例,这是美国棒球联赛的联盟记录:



图 3-1:典型的资料表示例

也许对红袜队球迷来说这是非常郁闷的统计资料,不过图3-1的却是列表资料的完美示范.它有三个表头(year,opponent,season record(w-l)),跟着是四年份的资料.在表格上面的是表格标题,说明了表格的内容.

标记这个资料表格的方式十分直观,我们或许会以这样的代码完成这个工作:

< p align="center">Boston Red Sox World Series Championships< /p>
< table>
< tr>
< td align="center">< b>Year< /b>< /td>
< td align="center">< b>Opponent< /b>< /td>
< td align="center">< b>Season Record (W-L)< /b>< /td>
< /tr>
< tr>
< td>1918< /td>
< td>Chicago Cubs< /td>
< td>75-51< /td>
< /tr>
< tr>
< td>1916< /td>
< td>Brooklyn Robins< /td>
< td>91-63< /td>
< /tr>
< tr>
< td>1915< /td>
< td>Philadelphia Phillies< /td>
< td>101-50< /td>
< /tr>
< tr>
< td>1912< /td>
< td>New York Giants< /td>
< td>105-47< /td>
< /tr>
< /table>

这样显示的结果应该和图3-1十分相似,但是,我们可以在这个基础上加上一些改进.

首先,我们能用更加语义化的< caption>标签来存放"Boston Red Sox World Series Championships".< caption>标签需要紧跟在< table>起始标签后面,通常用来存放表格的标题或者表格资料的说明.

看上去,它更容易让使用者看出表格的主题,同时也能够帮助以其他方式得知网页内容的人.

让我们拿掉开头的那个段落,并加入正确的< caption>:

< table>
< caption>Boston Red Sox World Series Championships< /caption>
< tr>
< td align="center">< b>Year< /b>< /td>
< td align="center">< b>Opponent< /b>< /td>
< td align="center">< b>Season Record (W-L)< /b>< /td>
< /tr>
< tr>
< td>1918< /td>
< td>Chicago Cubs< /td>
< td>75-51< /td>
< /tr>
< tr>
< td>1916< /td>
< td>Brooklyn Robins< /td>
< td>91-63< /td>
< /tr>
< tr>
< td>1915< /td>
< td>Philadelphia Phillies< /td>
< td>101-50< /td>
< /tr>
< tr>
< td>1912< /td>
< td>New York Giants< /td>
< td>105-47< /td>
< /tr>
< /table>

重要的是,标题必须快速传达后面资料的主题,根据默认设置,大多数可视化浏览器将< caption>标签内的文字居中显示在表格的最上面,当然,我们稍后可以使用css来改变默认设置的样式 — 本章的技巧延伸中会讨论这个问题.事实上,现在标题位于独特的标签内,正好让我们之后的修改工作变得轻松简单.

加上摘要

另外,我们也能为< table>标签加上summary属性,进一步解释这个表格的目的和内容,摘要属性对非可视化浏览器尤为重要,这能帮助它们解说表格的内容.

以下是为示例表格加上摘要属性的代码:

< table summary="This table is a chart of all Boston Red Sox World Series wins." >
< caption>Boston Red Sox World Series Championships< /caption>
< tr>
< td align="center">< b>Year< /b>< /td>
< td align="center">< b>Opponent< /b>< /td>
< td align="center">< b>Season Record (W-L)< /b>< /td>
< /tr>
< tr>
< td>1918< /td>
< td>Chicago Cubs< /td>
< td>75-51< /td>
< /tr>
< tr>
< td>1916< /td>
< td>Brooklyn Robins< /td>
< td>91-63< /td>
< /tr>
< tr>
< td>1915< /td>
< td>Philadelphia Phillies< /td>
< td>101-50< /td>
< /tr>
< tr>
< td>1912< /td>
< td>New York Giants< /td>
< td>105-47< /td>
< /tr>
< /table>

表格的表头

在建立数据表格时,善用表头是件很重要的工作.在标记重要单元格时,我们可以发挥< th>标签的作用,而不是使用< b>之类在显示上暗示用户这个单元格是重要的的显示效果标签.就像我们在第二章中使用标题标签标记段落标题一样.

可视化浏览器或许会以粗体居中的效果显示< th>标签中的内容,但是我们依然可以用< th>标签的独特性,稍后再给这些重要的内容加上不同的样式,以便于存放在< td>内的一般资料及进行区别.

除显示效果的优势外,使用< th>标签也能帮助非可视化浏览器 — 这部分我们稍后进行深入讨论.

示例表格中的表头是最上面的那一行: Year,Opponent和Season Record(W-L).我们来把刚才的显示效果标签替换成正确的表头标签:

< table summary="This table is a chart of all Boston Red Sox World Series wins.">
< caption>Boston Red Sox World Series Championships< /caption>
< tr>
< th>Year< /th>
< th>Opponent< /th>
< th>Season Record (W-L)< /th>
< /tr>
< tr>
< td>1918< /td>
< td>Chicago Cubs< /td>
< td>75-51< /td>
< /tr>
< tr>
< td>1916< /td>
< td>Brooklyn Robins< /td>
< td>91-63< /td>
< /tr>
< tr>
< td>1915< /td>
< td>Philadelphia Phillies< /td>
< td>101-50< /td>
< /tr>
< tr>
< td>1912< /td>
< td>New York Giants< /td>
< td>105-47< /td>
< /tr>
< /table>

使用< th>标签来标记表头单元格和图3-1中的效果是一样的,让我们来看看为什么这个方法比较好:

我们不必使用额外的显示效果标签让表头突出显示在资料内容之外.

根据默认设置,大部分可视化浏览器都会以粗体居中的效果展示< th>标签中的内容.让使用者轻易分辨出表头和表格内容的区别.



由于它和< td>标签是相对独立的,因此我们能为表头加上与资料内容不同的样式.

使用表头标签的其他好处我们在接下去的章节中继续讨论.

表头与数据的关系

我们可以利用headers属性把表头和对应的< td>中的数据关联起来,使屏幕阅读器能更容易为需要的人们组织表格内容.在使用了这个属性之后,屏幕阅读器将能更符合逻辑的读出表格内容,而不是像平常一样死板的从每列最左边读到最右边.

我们继续使用红袜队战绩表当作例子来示范使用方法.首先,我们需要为< 表格中的每个< th>加上一个唯一的id,接着再为每个资料单元格加上headers属性,对应正确的表头.

为每个表头加上id很简单,就是这样:

< table summary="This table is a chart of all Boston Red Sox World Series wins.">
< caption>Boston Red Sox World Series Championships< /caption>
< tr>
< th id="year">Year< /th>
< th id="opponent">Opponent< /th>
< th id="record">Season Record (W-L)< /th>
< /tr>
< tr>
< td>1918< /td>
< td>Chicago Cubs< /td>
< td>75-51< /td>
< /tr>
< tr>
< td>1916< /td>
< td>Brooklyn Robins< /td>
< td>91-63< /td>
< /tr>
< tr>
< td>1915< /td>
< td>Philadelphia Phillies< /td>
< td>101-50< /td>
< /tr>
< tr>
< td>1912< /td>
< td>New York Giants< /td>
< td>105-47< /td>
< /tr>
< /table>

我们为每个表头id选择简短的有描述意义的名称,接着我们再为每个资料单元格加上适当的headers属性,让内容匹配正确的表头id:

< table summary="This table is a chart of all Boston Red Sox World Series wins.">
< caption>Boston Red Sox World Series Championships< /caption>
< tr>
< th id="year">Year< /th>
< th id="opponent">Opponent< /th>
< th id="record">Season Record (W-L)< /th>
< /tr>
< tr>
< td headers="year">1918< /td>
< td headers="opponent">Chicago Cubs< /td>
< td headers="record">75-51< /td>
< /tr>
< tr>
< td headers="year">1916< /td>
< td headers="opponent">Brooklyn Robins< /td>
< td headers="record">91-63< /td>
< /tr>
< tr>
< td headers="year">1915< /td>
< td headers="opponent">Philadelphia Phillies< /td>
< td headers="record">101-50< /td>
< /tr>
< tr>
< td headers="year">1912< /td>
< td headers="opponent">New York Giants< /td>
< td headers="record">105-47< /td>
< /tr>
< /table>

在为表头和内容之间建立对应关系后,屏幕阅读器可能会议这样的方式读出表格的每一行内容: "Year:1918,Opponent:Chicago Cubs,Season Record(W-L):75-51",比起从左到右读出每格内容的方法来说,这样就有意义多了.

让每个< th>具有唯一的id还有其他的好处,我们可以使用这个辨别依据,设定特殊的css规则,在本章最后的技巧延伸终究会讨论这个方法.

使用abbr属性

在之前的示例中,或许你会觉得表头中"Season Record (W-L)"用语音合成器来念实在太长了一些,此时,只要加上abbr属性,我们就能缩短发音时的内容,同时又为可视化浏览器保留了< th>单元格中的原始文字.

< table summary="This table is a chart of all Boston Red Sox World Series wins.">
< caption>Boston Red Sox World Series Championships< /caption>
< tr>
< th id="year">Year< /th>
< th id="opponent">Opponent< /th>
< th id="record" abbr="Record">Season Record (W-L)< /th>
< /tr>
< tr>
< td>1918< /td>
< td>Chicago Cubs< /td>
< td>75-51< /td>
< /tr>
< tr>
< td>1916< /td>
< td>Brooklyn Robins< /td>
< td>91-63< /td>
< /tr>
< tr>
< td>1915< /td>
< td>Philadelphia Phillies< /td>
< td>101-50< /td>
< /tr>
< tr>
< td>1912< /td>
< td>New York Giants< /td>
< td>105-47< /td>
< /tr>
< /table>

我们加上了 abbr="Record" 后,屏幕阅读器会读出表头使用简短的版本后的"Record".

< thead>,< tfoot>和< tbody>

在这里我还想提一下三个与表格相关的标签.它们不仅能为表格结构提供更精确的语义,同时也为css提供额外的标签,让你在设计表格行的样式时不用为< tr>标签设计那么多的class.

引用一段W3C在HTML4.01规格中对这些标签的说明(http://www.w3.org/TR/html4/struct/tables.html#h-11.2.3):

引用:
表格行能够以thead,tfoot和tbody标签分成表头,表尾以及数目不限的表格主体.这种分类法让浏览器支持独立卷动表格主体的功能.打印长表格时,表头和表尾也能在包含表格资料的每一页上重复出现.

因此,使用使用这种分类方式也能让支持独立表格主体的浏览器使用者更容易阅读表格内容,特别是长表格.

< thead>与< tfoot>必须出现在< tbody>之前,让浏览器与其他设备能够先载入这些内容,以这种表格行分类方式标记表格看起来是这样的:

< table>
< thead>
< tr>
...table header content...
< /tr>
< /thead>
< tfoot>
< tr>
...table footer content...
< /tr>
< /tfoot>
< tbody>
< tr>
...table data row...
< /tr>
< tr>
...table data row...
< /tr>
< tr>
...table data row...
< /tr>
< /tbody>
< /table>

你会发现,表头和表尾资料以< thead>和< tfoot>标签包围,放在表格数据行之前.

就像我之前所说的那样,这些标签不仅能为表格提供更精确的语义,还能给css提供样式锚点让你为这些特定内容设置css规则,而不必为每个< tr>设计那么多的class.

举例来说,如果我们只想给数据区块(以< tbody>标记)设定与其他区块不同的背景色.那么我们只需要写这样一段css就能达到目的:

tbody {
background-color: gray;
}

如果没有tbody标签的话,我们需要为每个想要加上灰色背景的< tr>标签添加class属性.有意义的标记方式经常能使之后用css设定样式的工作变得十分轻松.这就是个好例子.

表格邪恶吗?

我想,如果我们根据表格标签设计之初的目的好好使用的话,那么答案就肯定是"不!".滥用表格创建复杂嵌套的布局的行为理所当然会遭到谴责,但是表格的确会给资料区块提供它需要的良好的结构.

我们不能在整本书里都叙述创建完美表格所需要的各种技巧,因此就此打住,希望你已经开始知道如何创建简单的又具有可用性的方便css修饰的简单表格.

谈到样式,让我们用几种不同的css技巧修饰一下之前的示例.

技巧延伸

与之前章节一样,我们用灵活的语义化的结构化的标记为基础,然后用css给他加上一些样式

首先,我们先来看看简单的边框技巧,在示例上创建单线边框,然后我们再为表格标题和表头加上独特的样式

建立边框

已经对border默认属性的3维效果感到厌倦了么?我也是.一般来说,为table标签加上border="1"就会与图3-1的效果类似,当然你也能换个方法,这边有一个用css做出漂亮整洁边框的诀窍.首先,我们给每个< th>< td>单元格两侧(右侧和底部)加上一像素的边框:

th, td {
border-right: 1px solid #999;
border-bottom: 1px solid #999;
}

只加上两侧边框,是建立各处边框等宽又同时让大部分流行的浏览器能够正确显示的关键所在.如果我在四周都加上边框,那么边框的顶部和左侧会在单元格排列时造成重叠,在稍后的示例中,我会给出一种只用一条border规则就达成小童效果的方法.



你会发现图3-2中的整个表格只缺少了最顶部和最左侧的边线,为了补齐边框,我们给< table>元素加上样式相同的border-top和border-left属性

table {
border-top: 1px solid #999;
border-left: 1px solid #999;
}
th, td {
border-right: 1px solid #999;
border-bottom: 1px solid #999;
}



图3-2:为th和td加上两侧边线的表格示例



图3-3 补齐边线后的表格示例

去掉间隙

现在我们已经有了个完整的表格了,但是边框之间的间隔是怎么回事?不幸的是,由于大多数浏览器会默认设置一点外补丁,因此就会露出这些令人讨厌的间隙了.

我们能做的是为表格元素加上border-collapse属性来去掉这些间隙,得到我们想要的样式.

table {
border-top: 1px solid #999;
border-left: 1px solid #999;
border-collapse: collapse;
}
th, td {
border-right: 1px solid #999;
border-bottom: 1px solid #999;
}

在为border-collapse加上collapse属性后,我们就能看到精确的单线边框样式了,如图3-4



图3-4:使用了border-collapse属性后的表格示例

不支持IE for Mac的版本

除了Internet Explorer for Mac之外,其他的浏览器都支持把css简写成这样:

table {
border-collapse: collapse;
}
th, td {
border: 1px solid #999;
}

要用哪一种方法,这当然由你来决定了,现在仍然有一些人再使用IE for Mac,而使用这个替代方法的话,会让他们看到一些边线的重复,如果你并不在意这件事情,那就使用简化的办法吧.严格来说,这只是个显示上的问题,表格功能丝毫不受影响.

由于我无法弃Mac狂热者于不顾(任何称职的网页设计师都应该这样),因此再往后的示例中,我还是会用IE for Mac也能正确显示的版本.

扩大空间

现在我们手上有了一个完美的表格,不过它看上去有点局促...让我们为手边的th,td规则加上一点内补丁,给它们呼吸的空间(图3-5)

table {
border-top: 1px solid #999;
border-left: 1px solid #999;
border-collapse: collapse;
}
th, td {
padding: 10px;
border-right: 1px solid #999;
border-bottom: 1px solid #999;
}



图3-5:加上10像素内补丁的表格示例

你知道吗?如果用单一数值设定内补丁的话(比如之前的例子的10px),就需要给元素的四边都加上相同的设定值,你也可以按照顺时针顺序(上右下左)分别指定每一边的设定值.如果你把内部定设定为10px 5px 2px 10px的话,就会在顶部加上10px的内补丁,右侧加上5px的内补丁,底部加上2px的内补丁,左侧加上10px的内补丁.

另一条捷径:如果上下的设定值相同,左右的设定值也相同的话,你就只需要分别设定一次就可以了,如果设定了padding:10px 5px的话,就会在上下部加上10px的内补丁,在左右侧加上5px的内补丁.



图3-6:顺时针设定内补丁和外边界的顺序

调整表头的显示效果

我们可以轻松的给表头加上背景色,选用不同的字体,让表头更加的明显,由于我们是使用了< th>标签而不是直接在行内将内容设为粗体,因此我们不必加上任何其他的标签,就能直接为表头内容设定样式.

我们在标题下面也加上一点内补丁,同时还用不同的字体,颜色(当然是红色)以突出标题内容(图3-7)

table {
border-top: 1px solid #999;
border-left: 1px solid #999;
}
caption {
font-family: Arial, sans-serif;
color: #993333;
padding-bottom: 6px;
}
th, td {
padding: 10px;
border-right: 1px solid #999;
border-bottom: 1px solid #999;
}
th {
font-family: Verdana, sans-serif;
background: #ccc;
}



图3-7:加上样式的标题和< th>

为表头加上背景图片

刚才我们为表格里的< th>元素加上了灰色背景,但是我们其实可以更进一步,用背景图平铺在格子里来作出漂亮的效果,举例来说,我们能用细致的灰色条纹模拟出许多Mac OS X中的窗口样式

小图片

首先我们用photoshop(或者其它你熟悉的绘图工具)建立一个小图片,在这个例子中,我们要制作一个2像素灰色和2像素白色交替出现的效果,因此图片只需要4像素高,宽度多款都无所谓,因为它会在< th>里平铺开来,做出我们想要的条纹效果.为了节省带宽,我们只做1像素宽(图3-8)



图3-8:1X4的像素条纹图片(放大后)

CSS

沿用刚才示例中的代码,我们需要修改的地方只有把背景颜色换成刚制作好的小图片路径,除非另外制定,否则根据默认设置,背景图会自动超每个方向平铺.

table {
border-top: 1px solid #999;
border-left: 1px solid #999;
}
caption {
font-family: Arial, sans-serif;
color: #993333;
padding-bottom: 6px;
}
th, td {
padding: 10px;
border-right: 1px solid #999;
border-bottom: 1px solid #999;
}
th {
font-family: Verdana, sans-serif;
background: url(th_stripe.gif);
}

图3 -9是套用这个样式后的表格,表头部分分线了条纹背景,要实验其他的平铺背景图也很方便,你可以试试怎样才能为表头或资料做出最好看的效果,好好享受这个实验的过程吧.



图3-9:在表头使用平铺背景的示例

为ID指定图标

记得本章开始的时候我们为表格里的每一个< th>加上唯一的ID吗?那时我们把这些id与数据列表中的headers属性匹配起来,帮助非可视化浏览器的使用者了解表格的内容,现在我们能在另一个地方发挥这个id的功能了,那就是为每个< th>指定不同的图标.

图标路径会完全记录在css文件中,让你能够在网站重构,更新时轻易的替换,完全不必修改标签部分.

图标

我用photoshop做了三个独特的图标,分别用在示例中每个表头上:Year, Opponent与Season Record(W-L).图3-10就是这三个图标:



图3-10hotoshop制作的三个表头图标

CSS

加上css并不困难,因为我们为每个< th>都制定了独特的id,因此我们能直接用background属性来指定正确的图标.

table {
border-top: 1px solid #999;
border-left: 1px solid #999;
}
caption {
font-family: Arial, sans-serif;
color: #993333;
padding-bottom: 6px;
}
th, td {
padding: 10px;
border-right: 1px solid #999;
border-bottom: 1px solid #999;
}
th {
font-family: Verdana, sans-serif;
}
#year {
padding-left: 26px;
background: #ccc url(icon_year.gif) no-repeat 10px 50%;
}
#opponent {
padding-left: 26px;
background: #ccc url(icon_opp.gif) no-repeat 10px 50%;
}
#record {
padding-left: 26px;
background: #ccc url(icon_rec.gif) no-repeat 10px 50%;
}

你应该注意到了,我们改用简写方式定义了背景样式,我们从th的定义中取出background:#ccc规则,并把它放到每个表头的图标名称旁边,这会使得我们的图标"坐"在我们指定的灰色背景上面,我们也在每个表头内容的左边留够图标的空间,不让文字覆盖上去,图3-11就是我们想要的效果:





图3-11:为每个< th>制定独特图标的效果

使用简写语法有明显的优点,然而,如果我们只以background属性定义图片,不定义背景色的话,就应该先取消掉先前在< th>中以background定义的背景色.

组合规则,简化内容

能够达到相同功能的另一种写法,是把每个表头里反复出现的规则(在这个例子中是背景图片,内补丁和位置)拿出来写在< th>定义一次就好了(因为它们的设定在每个< th>中的确都一样),然后只在#year,#opponent,#record定义内保留各自不同的设定值(也就是图片路径)

table {
border-top: 1px solid #999;
border-left: 1px solid #999;
}
caption {
font-family: Arial, sans-serif;
color: #993333;
padding-bottom: 6px;
}
th, td {
padding: 10px;
border-right: 1px solid #999;
border-bottom: 1px solid #999;
}
th {
font-family: Verdana, sans-serif;
padding-left: 26px;
background-color: #ccc;
background-repeat: no-repeat;
background-position: 10px 50%;
}
#year {
background-image: url(icon_year.gif);
}
#opponent {
background-image: url(icon_opp.gif);
}
#record {
background: url(icon_rec.gif);
}

这样稍微简洁一些了吧?借着整合相同规则,我们能够省下每次重复定义修改的时间和精力,以这个例子来说,看起来只差六个,半打而已,但是对大一些的样式表来说,节省的量就很可观了.

总结

在本章,我们不仅发现了表格并不邪恶,同时还深入了解表格之后,我们发现,他们很适合用来标记例表数据,而且仍然易于使用

我们更发现,只要加上一些样式,就能控制列表数据的显示方式,让他们变得十分具有吸引力,别再为使用表格而感到恐惧了.

标记语言——标题

总览:

不但所有网页都需要有标题,而且如果标记正确的话,他们能为网页设计和易用性增色不少.

从外观来说,网页的标题通常是使用较大的字号,或许会用和主体文字不同的颜色或者字体.标题的作用是"简要的描述往后章节所讨论的主题",W3C这样描述 — 显示网页内各个段落的概要.

怎样来创建一个页面标题来使得我们要展现的信息得到最有效的利用?在这个章节中,我们将研究几种常用的处理标题的方法,试着从中找出其中一种对我们最有帮助的方式,然后,我们将使用一些css的技巧和窍门来为最棒的方法装饰一番.

创建文档标题的最好方法是什么?

在回答这个问题之前,让我们假设现在正要把标题放置在文档的页首,我们来看看能够达成类似效果的三种方式.

方法A:有意义吗?

< span class="heading">Super Cool Page Title< /span>

虽然< span>标签在某些场合会是个方便的标签,但是对于页面标题来说,它的意义并不大,使用这个方法的唯一好处是我们可以为 heading 类指定一个css样式,以便让文字看起来像是个标题.

.heading {
font-size: 24px;
font-weight: bold;
color: blue;
}

现在,所有标记了heading类的标题都会变大,变粗,变蓝,很棒对吧?但是,如果有人使用一个不支持css的浏览器访问这个页面会怎么样呢?

举例来说,如果我们把css样式放在旧浏览器不支持的外部样式表文件里 — 或者屏幕阅读器为有障碍的用户朗读页面时会怎么样呢?通过这些途径访问这个页面的使用者将看不到(听不到)标题和正文文字的差异.

class="heading"这样的标注方法稍~~微的描述了标签内容的意义,但是< span>只是个一般用途的容器,只是让大部分浏览器改变默认显示样式而已.

搜索引擎在抓取到这个页面时,会跳过< span>标签就像它不曾在那边一样,不会为里面可能包含的关键字提升权重,稍后在本章节内会提到更多搜索引擎和页面标题的关系.

最后,由于< span>标签是一个行内元素,我们大多需要把方法A的内容在放置到另一个块级容器中,比方说< p>或者< div>,以便让它独占一行.这样会生成许多不必要的代码,就算你加上需要的容器,不支持css的浏览器仍然会以他本来的方式显示文字,让用户看不出标题和正文的任何区别.

方法B: P和B的组合

< p>< b>Super Cool Page Title< /b>< /p>

方法B使用了段落标签,这会让我们得到我们想要的块级元素的显示效果,而< b>标签会让文字呈现粗体的样式(在大多数浏览器上) — 但是我们以这样的方式标记重要的标题时,仍然要面对同样缺少语义性的结果.

不像方法A,< b>标签的存在就算缺少css样式的定义,在大多数浏览器中还是会将文字以粗体的样式呈现.但是和< span>标签一样,搜索引擎不会为段落内的粗体文字提升关键字权重.

难以加上样式

使用单纯的p和b的标签组合,让我们无法为这个标题加上和其它段落有所区别的样式,或许我们想以独特的方式强调标题,为页面内容加上定义和结构 — 但是使用了这个方法让它呈现粗体后,我们就没有办法去做这些事情了.

方法C:样式与实质

< h1>Super Cool Page Title< /h1>

哈哈,我们的好朋友标题标签来了,标题标签从一开始就是存在的,但是许多网页设计师还是无法以一致的方式使用它们.如果使用得当,标题标签能够提供页面内容的锚点,提供灵活的,可索引的,可更改样式的结构.

从标签本身的观点来看,你一定会爱上它的简洁,它们不需要额外的容器标签,你甚至能说这个方法能比前两个方法节省了一些字节,可能可以忽略,但是每小一个字节就是改变.

< h1>到< h6>分别代表了6层标题,从最重要的< h1>到最不重要的< h6>,他们本身就是块级元素不需要一个额外的容器就能自成一行,简单而又有效率 — 是完成这项工作的最佳工具.

容易定义样式

因为< h1>标签拥有独特的意义,不像< b>或者< p>标签那样会在文内用到多次,因此我们能用css为它加上各式各样的样式(我们会在本章的"更多技巧"中深入讨论).

更重要的是,就算不加上任何的样式定义,标题标签看起来就很明显是个标题!浏览器会用大字体,粗体字呈现< h1>的内容,就算去掉页面所有的样式定义,仍然可以看到文档的结构,因为正确的标题标签描述的是内容意义,而不是表现方式. (图 2-1)


图 2 - 1: 脱离样式后使用标题标签的页面内容

屏幕阅读器,PDA,移动电话和其他一些视觉的非视觉的浏览器也能识别并正确处理标题标签的内容,把它的重要性突出于页面其他内容之上.使用< span>标签,不支持(或无法支持)css的浏览器就不会认为它有什么特别之处.

讨厌的默认样式

在网页设计史上,设计师们都会避免使用标题标签,完全是因为不加上样式的时候,标题标签看起来就和怪物没什么两样,二者择其一,其中一部分人会因为默认字体大小太大而避免使用< h1>或< h2>而去使用字体大小较小的标号较高的标题标签.

然而,有个重点值得强调,我们可以根据自己的喜好通过定义css轻易的改变这些标题标签的样式 — 举例来说,< h1>未必一定是占据了半块屏幕的庞然大物,稍后,我会示范如何简单的用css样式来定义标题标签,以此来帮助你克服对< h1>的恐惧.

对搜索引擎的友好

这是最大的优点.搜索引擎十分喜欢标题标签,< span>标签或者段落中的粗体对搜索引擎来说并没有多大意义,使用正确的< h1>~< h6>标记标题花不了多少时间,但是却能帮助搜索引擎为你的页面建立索引,让用户更容易找到你的网页.

搜索引擎的机器人非常重视标题标签中的内容,或许,你会想要在里面堆上几个关键字,在他们处理完< title>和< meta>标签之后,紧接着就会处理页面内容中的标题标签,如果你的页面上没有使用标题标签的话,那这些在你的标题中的关键字不会引起他们的重视,被他们忽略.

所以,只需要花少少的时间,就能让其他人更容易通过内容找到你的网页,听起来不错,对吧?

附带一提的标签顺序

在上面的示例中,在页面中最重要的就是标题,因为他是整个文档的标题,因此,我们将使用最重要的标题标签< h1>,根据W3C,有些人认为跳过标题层并不是什么好习惯,举例说明,假设我们有下面这么一份网页:

< h1>Super Cool Page Title< /h1>

那么下一个标题(如果不是另一个< h1>的话),就应该是< h2>,在接下去则使用< h3>等等,你也许不会跳过某级标题,比如说在< h1>之后直接使用< h3>.我比较赞同,并且认为结构和纲要相同,应该按照顺序使用每个级层,这能让你为已经存在的页面方便的添加标题,样式.同时这样也比较不会出现用完所有标题级层的情况.

如同先前所述,设计者可能会使用< h4>代表页面里最重要的标题,只因为它的预设字体大小不如< h1>那样大的恐怖.但是要记住,先写结构,再调整样式,我们可以在任何时候根据我们自己的喜好通过css改变标题标签的字体大小.



概要

让我们大致上回顾一下,为什么使用标题标签(< h1>到< h6>)来标记页面内的标题会比较好.

方法A:

可视化浏览器会在禁用或不支持css功能时,以一般文字相同的样式显示标题,非视觉浏览器则完全不知道标题和内文文字之间的差别.
搜索引擎不会特别重视以< span>标记的标题
我们能制定独特的样式,但是我们在新增标题时,却会被heading类困死.

方法B:

可视化浏览器只会用粗体显示内容,继续使用预设的字体大小.
我们无法为标题加上和内文不同的独特样式
搜索引擎同样不会特别重视以< p>< b>创建的标题的内容.

方法C:

传达了标题标签中的文字确切的含义.
不管是可视化还是非可视化浏览器不管读到什么样式都会正确的处理标题内容
搜索引擎会重视标题标签中的关键字.

技巧延伸

这里我们将采用方法C,并用它来实验一些简单的css样式.我们将完全发挥标题标签独特性的优势.我们可以非常安心的使用标题标签,因为不管在什么浏览器和设备上,都能正确的处理标题内容.接下来我们来给他装扮装扮,然后带它上街(如果你能够带着一个html标签上街的话....)

简单的样式

使用css,最简单最容易实现的效果就是为标题设置不同的字型.我们可以编写一个css规则,然后套用到页面中所有的< h1>标签上(如果你用到了外部样式表,那就可以把样式套用到整个网站上).如果在稍后的时间里想要改变整个网站里每个< h1>的颜色,大小或者字体,那么只需要修改几条css规则就行了,而且修改之后的效果能够马上看到!这听起来很诱人,对吧?

让我们超级酷的标题来告诉我们自己吧:

< h1>Super Cool Page Title< /h1>

让我们用css来改变它的颜色,字体和大小吧:

h1 {
font-family: Arial, sans-serif;
font-size: 24px;
color: #369;
}

就像我们刚才所说的,非常简单,整个页面的所有< h1>都被设置成24像素大小,蓝色的Arial(或者默认的sans-serif)字体,如图 2-2:


图 2-2: 标题样式示例

接下来我们继续在标题文字下面加上1像素宽的灰色边框(如图 2-3):

h1 {
font-family: Arial, sans-serif;
font-size: 24px;
color: #369;
padding-bottom: 4px;
border-bottom: 1px solid #999;
}


图 2-3:加上灰色底边的标题样式示例

我们在文字底部多留了些内补丁,使得下面的边线不至于呼吸困难.因为标题标签是块级元素,因此边框会不止填满文字底部,还会继续向右边延伸,直到填满整个页面宽度.

另外值得一提的是,我们使用了边框的简写法 — 就是在一条声明中同时定义了宽度,样式,颜色.你可以试试看其他的设定值,看看有什么别的效果.

加上背景

背景能给标题加上精巧的效果.只要加上背景色与一些留白,不需要用到图片我们就可以创造出清新的标题风格.举例来说:

h1 {
font-family: Arial, sans-serif;
font-size: 24px;
color: #fff;
padding: 4px;
background-color: #696;
}

我们把标题中的文字变成白色,周围留出4像素的内补丁空间,同时把背景改成绿色.如图2-4那样,会有一条宽大的,颜色如同撞球桌的绿带贯穿整个页面,分割两个段落.


图2-4:设定了内补丁和背景色的标题示例

背景和边框

只要在标题下面加上一条细边框,再配上浅色背景,你就能不用一张图片的情况下做出三维的效果.

这份css与上面的十分类似,只改了几个颜色,在底部加上了2像素的边框

h1 {
font-family: Arial, sans-serif;
font-size: 24px;
color: #666;
padding: 4px;
background-color: #ddd;
border-bottom: 2px solid #ccc;
}

借着使用不同亮度的相同颜色,就能做出如图2-5般逼真的三维效果:


图2-5:设定背景和底边的标题

平铺背景

用上图片的话,就能发挥更多的创意了.就让我们用photoshop创建一个10X10的小图片,最上面是黑色的边框,然后下面是从上到下的灰色梯度(如图2-6):


图2-6 用Photoshop创建的小图片

我们可以用css把这个小图片放到我们的< h1>底部去:

h1 {
font-family: Arial, sans-serif;
font-size: 24px;
color: #369;
padding-bottom: 14px;
background: url(10x10.gif) repeat-x bottom;
}

设定 repeat-x 使浏览器在平铺背景图的时候只在水平方向上排列(相对的repeat-y就是在垂直方向上排列),同时我们设定了将图片放置在标题的底部,并加上一些下部内补丁,以便调整图片和标图文字之间的距离(如图2-7)


图2-7:设定平铺背景的标题示例

方便替换的图标

我们也可以使用cssdebackground属性来设定放在文字左边的小图标以此来代替写死图片标签的方法,为标题加上装饰用的小图标.这个方法能使在未来的日子里改变网站显示效果的工作变得十分轻松—只需要替换那么一个css规则,就能同时改变整个网站的显示效果.

代码和上面的平铺背景大致相同:

h1 {
font-family: Arial, sans-serif;
font-size: 24px;
color: #369;
padding-left: 30px;
background: url(icon.gif) no-repeat 0 50%;
}

我们在文字的左边多留出一块空间以便防止我们想要的图标,然后设定no-repeat指定背景图片不进行平铺(如图2-8),同时我们希望图标的位置在据左边0像素,并且对起垂直中线.


图2-8:设定了图标的标题示例

容易更新

让我们设想这样一个场景:在一个包含了100个页面的网站里,我们没有使用上面的方法,而使用< img>标签写死每个标题旁边的图标,图标和网站风格是相融合的,几个星期后,网站的主人打算换掉网站风格,而新的图标大小和旧的并不一样,哎呦!这下我们就得回去修改整整100份页面里面的< img>标签以更新新图标的路径,真讨厌!想想这些事件会对项目预算造成怎样的影响,对完工期限带来多大的压力?时间就是金钱啊!

如果把这些并不十分重要的,装饰性的图标整合到一个css文件中,只要花上几分钟就能够一次性换掉整站的所有图标,带来崭新的外观!由此你应该可以渐渐明白到结构标记和显示效果分离的好处了吧.

变色龙效果

下来的技巧和我刚才所说的有一些矛盾,但是我认为这个技巧在某些情况下是十分有用的.这是我在2003年4月为Fast Company杂志的网站(http://www.fastcompany.com/)做标准重构时大量使用的技巧.

那时我们在网站里的< h3>标签旁边用了许多13X13的小图标,就像这样:

< h3>< img src="http://images.fastcompany.com/icon/first_imp.gif" width="13" height="13" alt="*" /> FIRST IMPRESSION< /h3>

有两个让我们决定要这样把图标写死在网页里面.首先,根据标题种类的不同,我们会使用到不同的图标(图书俱乐部是一本书,每日引言则是引号等等),第二个理由则是我们每个月会更换一次整个网站的配色,以配合当期杂志的封面主题.当然,这种替换工作因为使用了css而变得十分简单.



为了让图标跟着其他页面元素一起变色(这样才不必一直为了新色彩而重新制作图标),我们只用两种颜色做了一组图标:白色和透明(会显示除每次更改的背景颜色).图2-9就是放在首页引言之前的图标:


图2-9: 13X13的透明图标(放大后)

为了在透明部分填进颜色,我们使用了简单的css的background属性设定颜色,我们希望只希望这个颜色出现在图表的后面而不出现在标题文字后面,我们用到了css选择器只对< h3>标签内的图片使用这条规则,以便达到我们想要的效果:

h3 img {
background: #696;
}

这段css代码表示< h3>标签内的所有< img>标签都把背景设为绿色,背景色会透过透明像素显示出来,但是白色部分仍然还是白色,如此一来,每个月只需要修改这条css规则,换上不同的颜色,就能瞬间改变网站上每个图标的色彩了,就像变魔术一样.

对齐< img>标签

为了使图标和文字正确的对齐(我们希望垂直居中),因此我们加上了这条css规则:

h3 img {
background: #696;
vertical-align: middle;
}

这条规则会使图标和< h3>文字内容垂直居中,图2-20就是设定玩的标题:


图2-10:以css为图标加上背景色的示例

这个例子还能说明另一个重要的概念—以css指定背景色彩会出现在任何页面内指定的图标或是css图标后面.

举例来说,我们回头看看"方便更新的图标"这个示例,为它加上背景色看看:

h1 {
font-family: Arial, sans-serif;
font-size: 24px;
color: #fff;
padding-left: 30px;
background: #696 url(transparent_icon.gif) no-repeat 0 50%;
}

如此以来 transparent_icon.gif 会显示在相同规则中稍早定义的背景色之上(如图2-11) —在这个例子中,背景色是#696,也就是撞球桌的绿色.


图2-11 设定了背景图,背景色的标题示例

当你为了考虑色彩为主的页面上加小圆角,装饰图标时,这个小技巧就十分好用了.这些不重的图片可以完全放进css文件里面,未来打算更新的时候也就可以轻松替换.现在多用点心思.就能节省未来许多的工作.

总结

我希望通过比较集中常用的方法后,你能发觉正确使用标题标签的好处.不管是视觉,非视觉浏览器或者其他设备,都能正确的历届标题的含义,并且以适当的方法展现它们,搜索引擎也会为他们建立索引,你也可以轻松的以css应用和修改需要显示的效果.