第7章 重构

我们当然可以随心所欲地空谈站点设计的理论概念,可要突破理论教条的束缚,却必须亲力而为,去尝试解决CSS设计中的实际问题。

为了让读者有真切的实际感受,本章选取了禅意花园中的6部作品,并逐个分析了其中CSS代码的设计过程,希望能对理解CSS设计的流程和技术有所帮助。

7.1 Hedges(树篱)

Kevin Mears,设计师

www.csszengarden.com/031

让任意的前景都能与背景图像完美融合

在禅意花园的众多提交作品中,有关花园的主题层出不穷。但Kevin Mears却从设计师和插画师的角度出发,抛开了围绕植物的传统手法,设计出具有卡通风格的“田园风光”。

在这部作品中,Mears将自己装扮成手推小车的园丁,加之各种有趣的卡通元素的妆点,最终让他的花园充满着亮丽的色彩。

而在这幅以插画为主的作品中,理所当然地运用了大量的图像。我们把其中的图像单独地放置在图7-1-1中。

figure_0247_0306

figure_0248_0307

图7-1-1 Hedge中用到的所有图像

7.1.1 设置边界

在加入这些有趣的图像之前,需要为页面设置一些基础的参数。Mears首先使用了定宽布局,所以尽管页面头部背景横向平铺到了整个窗口,页面中心部分却始终被限制在732像素宽的区域中。其次,#container将在页面中包围所有的其他元素,所以要为其应用如下的样式:

body {

 margin: 0;

 padding: 0;

 color: #888;

 text-align: center;

}

container {

 position: relative;

 padding: 0;

 width: 732px;

 margin: 0 auto;

 text-align: left;

}

container被限定于732像素宽,而将外边距设置为auto则会让#container内容部分水平居中于整个页面中1。由于body元素的text-align属性被设为center,所以我们要将#container的text-align属性设置为left,以覆盖body元素的设定。Windows平台上的IE 5.0和IE 5.5不能辨认当前应用的margin值,因此这是确保#container居中的一个必要手段。在应用了链接样式之后,我们可以看到图7-1-2中的效果。

注释:1 具体作用如下:auto被设置于右外边距,由于左外边距未被设置,它将继承右外边距的auto值,而auto值会导致#container的元素外框撑满body区域,而去除了#container width部分设置的宽度,剩余的空白边界将由左右外边距平分,最终让#container的内容区域居中于body元素中。——译者注

figure_0248_0308

图7-1-2 未加入图像前居中的一栏

7.1.2 打造主体

下一步就是隐藏复杂的头部元素,以免它们影响到创建主体部分的分栏布局:

h1 span, h2 span, h3 span, #quickSummary p.p span {

 display: none;

}

这样,Mear就完成了主内容区的定义,可他在主内容区的三栏设计中却遇到了麻烦——Mear发现禅意花园预先定义的标签还不够灵活——可以看到,在主栏中有#preamble和#supportingText两个标签,但它们却缺少一个可供统一设置样式的共同的父元素。所以我们只能分别定义其样式,并努力让它们在视觉上保证融合:

preamble {

 position: relative;

 left: 195px;

 padding-bottom: 0px;

 width: 400px;

}

supportingText {

 position: relative;

 left: 195px;

 padding-bottom: 0px;

 border-bottom: 2px solid #363;

 width: 400px;

}

可以看到,每个区块的宽度都设置为400像素,并且用195像素的左偏移以形成中间一栏。当然使用margin-left也能产生相同的偏移效果,只是源代码中使用了当前的方法而已。在完成这个步骤之后,效果如图7-1-3所示。

figure_0249_0309

图7-1-3 添加了偏移后的文字为左右两栏留下了足够的空间

接下来要把工具条移动到合适的位置。左侧的列表现在处于页面的底端,因此我们可以借助绝对定位将其挪动到页面上部。

linkList {

 position: absolute;

 top: 200px;

 left: 0;

 width: 190px;

}

quickSummary p.p1 {

 position: absolute;

 top: 12em;

 right: 15px;

 width: 120px;

 margin: 75px 0 0 580px;

 font-size: 80%;

 text-align: right;

}

quickSummary p.p2 {

 position: absolute;

 top: 25em;

 right: 15px;

 width: 120px;

 margin: 0;

 font-size: 93%;

 text-align: center;

 padding-bottom: 90px;

 background: url("barrow.gif") no-repeat bottom;

}

上述CSS设置为作品中的多个元素均应用了样式。例如,为#linkList设置了宽度,并且将其移至页面上部,#container的左侧。还用相同方法将两个标有#quickSummary的段落移至页面的右侧(作为改进,可以为两个段落的父元素#quickSummary设置部分定位属性以减少冗余代码)。完成以上步骤后,显示效果如图7-1-4所示。

figure_0250_0310

图7-1-4 定位完成后的三栏

7.1.3 图像处理中的诀窍

到目前为止,整个布局的框架已经完成。接下来要考虑的就是更为直观的图形区块的处理。Mear先从页首部分开始,他以一行重复的树木作为背景,而后在树木的上方手工绘制出站点标题。这里我们先从相对简单的背景图案入手:

body {

 margin: 0;

 padding: 0;

 background: #FFF url("bg_tree.gif") repeat-x left top;

 color: #888;

 text-align: left;

}

在上面这段代码中,Mear为现有的body样式添加了背景图像,且将background属性设置为repeat-x。简单修改之后,图像即可如我们所愿地水平伸展。

页面顶端的h1元素应用了另一个非重复显示的图像,这张图像将位于前面设定的背景图像之上。还记得先前为所有头部元素的span设置的display:none吗?该设置将会隐藏原始文本,因此背景图像即可不受干扰地呈现出来。接下来就是给h1元素指定合适的尺寸:

pageHeader h1 {

 height: 200px;

 background: url("nutitle.gif") no-repeat;

 padding: 0;

}

由于图像会占用很多水平空间,所以我们允许h1元素填满整个包含它的容器(也就是前面那个宽度设为732px的#container),至于高度并没有太多要求,只要调整到一个较为合适的尺寸即可。注意到先前处理的几栏也会同时向下平移,这是由于刚刚加入的height属性会影响到h1下方元素的缘故。然而左右的两列却不受影响,因为它们应用了绝对定位,从而独立于常规文档流之外。在最终实现的效果中,这两个细微的调整却让整个站点焕然一新(图7-1-5)。

figure_0251_0311

图7-1-5 少量的代码即可让页面焕然一新。图中为完成后的页首部分

由于body元素的背景固定,而页首的位置却是可变的,所以我们无从断定页首的各个图像将重叠于背景中的树木还是天空上。例如图中张开双手的那个人,当缩放浏览器窗口时可以看到他相对于背景的位置也随之变化。好在该图像的上半部分使用了透明的像素,所以能够完美地融合于背景中。无论浏览器的尺寸设为多大,背景和前景图像都能很好地融合在一起(图7-1-6)。

figure_0251_0312

图7-1-6 在浏览器窗口大小变化时,前景中的人物会随之移动,但其总是能很好地与背景图像相融合

7.1.4 格式化文字

由于完成后的作品使用了浏览器的默认字体,所以并不需要太多的额外设置。我们先从中间一栏开始分析:

supportingText p {

 line-height: 1.5em;

}

preamble p {

 width: 350px;

}

footer {

 background: #D9D98B;

 color: #fff;

 padding: 10px 20px;

 border-top: 1px solid #363;

 font: 85% Verdana,Arial,Sans-serif;

 text-align: center;

}

footer a:link, #footer a:visited {

 padding: 0 5px;

 font-weight: normal;

}

第一条规则用line-height改变了文字间的行距。接下来将#preamble的宽度限定于350px,以便为#preamble和右栏留出足够的间隔。

页脚部分需要更多的格式设定。前面我们已经为#supportingText设置了绿色的底部边框,现在则要为#footer设置border-top属性,以便添加新的边框颜色。完成了这些步骤之后,作品效果将如图7-1-7所示。

figure_0252_0313

图7-1-7 近乎完成的作品,唯一缺少的就是页首部分

Tip

和一般的CSS属性不同的是:line-height属性不需要单位——line-height:1.5和line-height:1.5em会得到相同的行间距。

7.1.5 收尾工作

最后,不要忘记对隐藏的头部进行一些处理。

supportingText h3 {

 height: 70px;

}

explanation h3 {

 background-image: url("what.gif");

 background-repeat: no-repeat;

}

linkList h3 {

 height: 41px;

}

lselect h3 {

 background-image: url("select.gif");

}

上述代码非常简单易懂,不过这也没什么值得大惊小怪的——链接列表都由图像组成,自然免除了字体、颜色的设置——在上述代码中,我们仅仅为#supportingText中的h3元素设置了公共高度和各自的背景图像而已,就这样整部作品大功告成。

7.2 Radio Zen

Marc van den Heuvel,设计师

www.csszengarden.com/058

用固定的背景图像实现类似收音机频道调节器的效果

Marc van den Heuvel从他的老式收音机中获得了作品的灵感。通过使用固定背景图像,他模拟出了带有活动指针的频道调节器的效果。由于页首的位置需要改变,且指针也要能够水平移动,所以作者采用了少见的水平滚动布局。

除此之外,van den Heuvel还采用了带有强烈视觉张力的retro字体,加之老式收音机的背景与泛黄的整体色调,让整个作品散发出一种怀旧的气息。

figure_0253_0314

7.2.1 构建基础

除了页首图像之外,Radio Zen在实现过程中只运用了很少的图像资源(图7-2-1),而作品中水平滚动的布局则主要依赖于CSS的定位技术。

figure_0254_0315

图7-2-1 Radio Zen中用到的图像

和很多其他设计师一样,van den Heuvel在开始之前就隐藏了页面两个头部中的文字。因为这些文字最终会用背景图像替代,所以现在理所当然应该将其隐藏:

pageHeader h1 span, #pageHeader h2 span {

 display: none;

}

这样做的另一个目的是为将加入顶部的收音机频道调节器预留出空间(图7-2-2)。这里我们并没有列出所有的样式代码,读者可在原始的CSS文件中获得。

figure_0254_0316

图7-2-2 使用基本文字样式时的Radio Zen

布局框架

在Radio Zen中,多数元素使用了绝对定位,这就意味着此类元素将被排除于文档流之外。而其他在文档流之内的元素并不能知晓绝对定位元素的始末位置,以致元素之间有可能会发生重叠。眼下的解决方法只能是将这些元素的边缘相互对齐,相关的定位规则如下:

quickSummary {

 position: absolute;

 right: 0px;

 text-align: left;

 width: 165px;

 height: 340px;

 top: 95px;

 padding-top: 40px;

}

preamble {

 position: absolute;

 left: 10px;

 text-align: right;

 width: 165px;

 top: 95px;

}

supportingText {

 position: absolute;

 width: 1230px;

 padding: 95px 0 0 185px;

 text-align: justify;

 z-index: 3;

}

linkList {

 font-family: Arial, Helvetica, sans-serif;

 position: absolute;

 top: 0;

 padding-top: 480px;

 text-align: justify;

 z-index: 1;

}

若浏览器的字体能始终保持前面设置的10px,那么这些规则将没有任何问题(图7-2-3)。但很多浏览器支持动态改变字体大小,所以在大字体情况下,文字依然会发生重叠(图7-2-4)。稍后我们将介绍如何解决这个问题。

figure_0255_0317

图7-2-3 设定了基本位置属性后的页面

figure_0255_0318

图7-2-4 大字体会导致文字重叠

7.2.2 分层和附着(Attachment)

我们强烈建议您打开原始网页试着水平滚动(图7-2-5A和图7-2-5B),所看到的情况或许和原先的猜想有所不同。事实上,指针在频道调节器上移动的效果并非由脚本完成。Radio Zen巧妙地使用了分层功能,并利用background-attachment:fixed属性实现了最终的效果。作者将带有FM刻度的频道调节器作为静态图像应用到背景元素之上,从而使在滚动时该图像在窗口中的位置保持固定。而此时,页面其他部分则能相对频道调节器板滚动。我们再仔细分析一下body元素的样式定义,可以发现在一行额外的规则中同时给出了background-image和background-position的设定:

25601

图7-2-5 滚动页面时指针随之移动

body {

 font: 10px Georgia, Arial, Helvetica, sans-serif;

 color: #353638;

 background: #F8F8EE url(schaal.jpg) no-repeat fixed top

 center;

 margin: 0px;

}

Note

在Windows平台上的IE中,固定背景只能用于body元素。

而指针则应用到#supportingText元素中:

supportingText {

 position: absolute;

 width: 1230px;

 padding: 95px 0 0 185px;

 text-align: justify;

 background: url(naald.gif) top center no-repeat;

 z-index: 3;

}

现在终于可以明白为什么要将#supportingText设置为一个如此“巨大”的width值了,这是因为它不但要装入水平排布的众多图像元素,还要强制页面出现水平滚动条,以便让指针有足够大的空间移动到调节器板的左侧。

7.2.3 列的定位

目前为止,body中的文字包含了一系列的宽大段落,这些段落将被水平排布在浏览器窗口中:

preamble {

 position: absolute;

 left: 10px;

 text-align: right;

 width: 165px;

 top: 95px;

}

supportingText h3 {

 margin: 0 8px 0 3px;

}

explanation, #participation {

 float: left;

 width: 290px;

}

benefits {

 float: left;

 width: 150px;

}

requirements {

 float: left;

 width: 500px;

}

这样的布局看上去显得更加美观(图7-2-6)。接下来我们再讨论一下前面所说的字号变化问题。

figure_0256_0319

图7-2-6 原先垂直堆砌的段落现在被水平隔开

字号变化所导致的问题

由于绝对定位将会把元素移出常规文档流,所以在某些情况下,文字将变得过长,甚至遮盖住其他元素。若使用的是如Firefox之类的可动态设置字体大小的浏览器,就能很清楚地看到页面底部的列表部分在字号改变时发生的变化(图7-2-7A~图7-2-7C)。

figure_0257_0320

图7-2-7 字号变化所导致的重叠

虽然目前来说这块区域还没有应用样式,但是如果现在不着手处理的话,也就意味着在未来埋下一颗定时炸弹。我们能会注意到,前面我们将#linkList元素的top属性设置为0,将其定位于页面顶部;之后又设置了480px的padding-top值,将其移动到下方。这个padding的设置可以使作品列表区域暂时位于页面中其他元素的下方,方便我们设计页面。但从本质上说,它和列表内部的div元素定位却没有任何关系,因为这些元素实际上都是通过绝对定位来控制的:

lselect, #larchives, #lresources {

 position: absolute;

 text-align: left;

 padding: 5px;

}

lselect {

 width: 1590px;

 top: 46em;

 background-color: #E8E9CF;

}

larchives {

 width: 300px;

 top: 49em;

 left: 75px;

}

lresources {

 width: 800px;

 left: 400px;

 top: 49em;

}

可以看到,由于div的定位都是以em,而不是px为单位,所以它们的顶端位置会随着字体大小的改变而同样发生变化,这也就避免了重叠问题。而在继续设置如下规则之后,作品列表和作品存档区域将出现在页面底部,如图7-2-8所示:

figure_0258_0321

图7-2-8 应用样式后的页脚

lselect ul, #larchives ul, #lresources ul {

 margin: 0px;

 padding: 0px;

}

lselect h3 {

 margin: 0 10px 0 0;

 color: #555F44;

 font-size: 8pt;

 float: left;

 font-weight: bold;

}

lselect li {

 color:#000000;

 list-style-type: none;

 float: left;

 border-left: 4px solid #F8F8EE;

 padding: 0 5px;

}

lselect a:link, #lselect a:visited {

 border: none;

 text-decoration: none;

 font-size: 8pt;

 font-weight: bold;

}

lselect a:hover, #lselect a:active {

 text-decoration: underline;

}

lselect a.c, #lselect a:link.c , #lselect a:visited.c {

 color: #422222;

 font-weight: normal;

}

Tip

在绝对定位中使用em为单位会导致定位随字体大小改变而自动调整。但若是使用px为单位,虽然可能会导致文字重叠,但却能够对元素位置进行更为精确的控制。

Note

值得一提的是,作者最后使用了图像对作品进行了修饰,例如在页首和页脚加入的收音机图样等。这些在本文中并没有深入阐述,而是作为练习留给了读者。所有的样式定义的终稿都可以在Radio Zen的CSS文件中找到。

7.2.4 探索一切可能

回顾Radio Zen的设计过程:只不过是简单地通过为body元素应用了固定背景,就实现了调板和移动元素之间的有趣交互。可见,只要悉心研究CSS,即使一些简单的CSS样式也能给用户带来相当独特的视觉体验——Radio Zen就是其中一个让人称道的尝试。CSS更多的纷繁复杂的特性始终敞开着大门,等待我们进一步去发掘。

7.3 South of the Border(南部边境)

Rob Shields,设计师

www.csszengarden.com/093

用外边距和定位体现框架之感

咖啡在某种程度上是一种普遍的创意源泉,可在South of the Border中引发Rob Shields灵感的则是一杯热茶。对Shields而言,无论酝酿什么样的作品,总能找到50多个初始的创意,其中每个创意包含的一系列关键字都能帮助他勾画出不同的站点主题。

Shields在这部作品中使用了他的第三个创意,这是个关于美国西南部风情的主题。为了把握住这转瞬即逝的灵感,Shields在灵感乍现后,急速地打开了Adobe Photoshop处理图像,完成了图7-3-1中的组合效果。进一步修饰之后,Shields开始着手CSS代码的编写,直到最终完成了主题鲜明的South of the Border。

figure_0259_0322

figure_0260_0323

图7-3-1 South of the Border中用到的图像

7.3.1 由基础开始

Shields的设计中使用了独特的色彩基调,他的灵感来自于一件带有蓝色条纹的褐色外衣。为了模拟出这种色彩基调,Shields将body元素的背景颜色设置为蓝色,又用浅褐色和深蓝色制作链接,而主要文字部分则使用了白色,与深蓝色背景形成足够的反差:

body {

 font: 83%/150%;

 color: #fff;

 background: #EDEDED url(background.gif) repeat-y

 fixed bottom

 center;

 margin: 0px;

 padding: 0px;

}

可以看到,Shields特意将字体大小用百分比表示,以确保它们可被自由缩放。下一页将给出字体和背景的效果。

7.3.2 为容器设置样式

在基本样式定义完成之后(可在源文件中找到这里跳过的部分CSS代码),接下来就是定义#container div的样式。下面声明中的样式定义了容器的背景图像、外边距和宽度:

container {

 position: relative;

 background: url(bg-central.gif) repeat top left;

 margin: 0px auto 0px auto;

 width: 655px;

}

container元素的position被设定为relative。由于并没有再定义其top和left属性,所以#container div还是会留在常规文档流中。许多CSS新手都会被relative一词所迷惑,以为相对定位是指元素的定位会相对于另外某个元素的位置。如此解释这个英语单词自然非常合理,但它在CSS中却不是这个意思。

相对定位让设计者能够在定位某元素的同时,仍保证其位于常规文档流中。这和使用如绝对定位等其他定位方式有很大的差别,我们将很快提到。

以前,我们的目标是创造一个在视觉上囊括所有其他元素的容器——#container。而既然现在已成功设定了#container的样式(详细样式可在CSS源文件中看到),我们即可着手为其中的子元素设置更多的样式了(图7-3-2)。

figure_0261_0324

图7-3-2 设定了位置、宽度、外边距后的#container div

Note

常规文档流是指在没有任何强制定位元素时,浏览器对页面的解释和布局。若移除了禅意花园中的所有样式,我们可以看到所有的文字和标题都会以从左到右自上至下的方式排布,并且浏览器也会根据不同的分辨率做相应的调整。

7.3.3 驾驭文本

当然,现在的首要任务就是把位于#container中的文本拉回到容器范围内。我们可以通过为各个div元素设置外边距来实现该目的:

intro {

 margin:0px;

}

quickSummary, #preamble {

 margin: 0px 200px 0px 68px;

}

pageHeader {

 margin: 0px;

}

supportingText {

 margin:0px 200px 0px 68px;

}

上面代码中定义的这些外边距即可将文本拉至容器的范围内(图7-3-3)。

figure_0261_0325

图7-3-3 为body中的文字设定外边距

7.3.4 加上标题

添加图形化的标题,尤其对于#pageHeader中的h1来讲,将大大有助于平衡文字和标题的整体视觉效果:

pageHeader h1 {

 margin: 0px 0px 0px 0px;

 background: transparent url(top.gif) no-repeat topleft;

 width: 655px;

 height: 206px;

}

图7-3-4显示了#pageHeader中h1样式所设置的体现主题的背景图像。

figure_0262_0326

图7-3-4 #pageHeader图像确定了整个作品的基调

这里我们摘录了一部分标题的样式,用来说明这部分是如何通过设置外边距、背景图像和长宽来有效装载图像和文字的:

preamble h3 {

 background: transparent url(ch1.gif) no-repeat topleft;

 margin: 10px 0px 5px 0px;

 width: 388px;

 height: 44px;

}

benefits h3 {

 background: transparent url(ch4.gif) no-repeat topleft;

 margin: 10px 0px 5px 0px;

 width: 388px;

 height: 44px;

}

requirements h3 {

 background: transparent url(ch5.gif) no-repeat topleft;

 margin: 10px 0px 5px 0px;

 width: 388px;

 height: 44px;

}

现在标题部分和页面其他部分协调得非常不错(图7-3-5)。

figure_0262_0327

图7-3-5 标题图像中带红辣椒的图案,以配合美国西南部的主题

这里我们再查看蓝色边框的样式:

benefits {

 border-bottom: 1px dashed #8095AF;

}

preamble {

 border-bottom: 1px dashed #8095AF;

}

这样设置之后,边框将呈点划线状,起到分割各个文字块的作用(图7-3-6)。

figure_0262_0328

图7-3-6 边界线分开了各个文字区域

7.3.5 转到页脚

在中心部分顺利完成之后,我们现在需要将页脚部分布置到正确的位置。页脚的内容非常简单,仅仅是一些用于验证的链接和一具装饰性的牛头骨而已:

footer {

 text-align: center;

 background: transparent url(bottom.gif) no-repeat topleft;

 height: 37px;

 margin: 0px -200px 0px -68px;

 padding-top: 88px;

}

footer a:link, #footer a:visited {

 margin-right: 20px;

}

注意到样式中使用了负的左右外边距,让页脚能够更好地置于包含它的元素中(图7-3-7)。

figure_0263_0329

图7-3-7 将页脚设定到正确位置

7.3.6 绝对定位

还记得先前的#container div使用的是相对定位吗?这里的链接列表却在相对定位的#container div中使用了绝对定位:

linkList {

 position: absolute;

 top: 207px;

 right: 6px;

 width: 181px;

}

这条样式会将列表布局在正文旁边。和相对定位不同的是,绝对定位以定位容器元素为参照设置位置。若没有定位容器的话,绝对定位的元素会以根元素html为参照。

若想实际感受一下该效果,可以暂时将相对定位的属性从#container div中移除(图7-3-8)。

figure_0264_0330

图7-3-8 和#container div失去定位关系后的#linkList

绝对定位的本质是这样的:一个绝对定位元素会参照它的定位容器元素来定位,如果没有定位容器元素,则会以html根元素为参照。但由于设置了相对定位,绝对定位的#linkList就会定位在该元素内。所以一旦将#container div的position属性的值重新设为relative1,就会再次回到我们期望中的布局。

注释:1 将某元素的position设定为relative将使之成为其中绝对定位元素的定位容器元素。——译者注

7.3.7 修饰链接的样式

解决完#linkList的定位问题,我们可以开始考虑链接的样式了。第一步需要做的就是将列表的内外边距设为0:

linkList ul {

 margin: 0px;

 padding: 0px;

}

这给导航条的进一步精确配置铺平了道路。接下来的代码设置了单个列表项的样式:

linkList li {

 list-style-type: none;

 background: transparent url(li-bg.gif) repeat topcenter;

 padding:8px 6px 8px 6px;

 margin:0px;

 border-top: 1px solid #5D4831;

 border-bottom: 1px solid #221609;

 display: block;

}

这些额外的对链接的标题、色彩、内外边距的设置为整个作品添加了不少有趣的细节,这些代码同样可以在CSS源文件中找到。

Tip

定位选项在布局中十分有效。它能够直接改变绝对定位的参照点。如果绝对定位元素的任意一个祖先元素都没有应用某种定位,那这个元素的参照点将从根元素html的边界开始。然而若是某个祖先元素已经应用了某种定位,那绝对定位就将以这个祖先元素的位置为参照点。

如何利用这个功能来处理父元素没有设置定位属性的情况呢?只需要为父元素设置position:relative而不为其设置top或者left值即可。这样既不会改变该父元素的原始位置,同时又能将其设为当前元素定位的参考点。关于该功能的更多细节,请参考Doug Bowman的 文 章 “ Making the Absol ute,Relative”(www.stopdes ign.com/articles/absolute)。

7.3.8 完成

外边距是控制文字和图像最有效的工具。相对定位也能让我们在元素中加入绝对定位的子元素,从而有效地处理那些棘手的布局问题。本节中的South of the Border就用简单直观的样式表现出了极其生动的主题,这也从一个侧面证明了CSS的强大功能。

7.4 Corporate ZenWorks

Derek Hansen,设计师

www.csszengarden.com/095

从竞争到和谐

在第一次接触CSS禅意花园时,Derek Hansen就深深折服于人们在其中付出的努力及其体现出的创意。此时他正致力于发掘出一种标准化的网页制作方案,自然很快想到了向禅意花园提交自己的作品。

在灵感的指引下,Hansen使用了一组崭新的创意为禅意花园带来了新的亮点。他首先从仔细地研究花园中的现有作品开始。在被各种主题所深深震撼的同时,他决定让自己的作品讲述一个故事,力求将其打造成禅意花园中的另一部标新立异之作。

figure_0265_0331

7.4.1 从一封信开始

就如所有典雅精致的文案一样,Corporate ZenWorks有着简洁工整的页面布局(图7-4-1),使用了银色的页面背景和简洁的字体作为基调:

figure_0266_0332

图7-4-1 Corporate ZenWorks中的图像

body {

 background: #999 url(bk.jpg) repeat-x fixed;

 margin: 0;

 padding: 0;

 color: #33140E;

 font-family: Georgia, Times, serif;

 font-size: 80%;

}

h1,h2,h3,h4,h5,h6 {

 border: 0;

 margin: 0;

 padding: 0;

 font-family: "Lucida Grande", "Lucida Sans Unicode",Verdana,

 sans-serif;

 font-weight: normal;

}

h3 {

 text-transform: uppercase;

 font-size: 90%;

 word-spacing: 2px;

 letter-spacing: 2px;

 margin-left: -10px;

 font-weight: bold;

}

注意到h3元素使用了负的外边距(图7-4-2)。看上去虽然有些怪,但它却给最终的作品带来了亮色,至于其中的原因,我们将在稍后阐释。

figure_0266_0333

图7-4-2 背景和字体一角。可以看到由于负外边距的缘故,文字非常靠近窗口的边缘,标题的一部分则已经被边缘截去

Note

标题使用了Lucida Grande字体、正文则用Georgia字体,这让Corporate ZenWorks的文字显得简洁而优雅。Hansen解释说,他之所以偏重用字体而不是图像实现设计效果,是因为感觉到了一丝约束——担心由于过度使用图像而导致页面文件过大。而正是得益于这些限制,作品中的字体才更真实地切合企业文书中的真实风格。

7.4.2 纸张的设计

下一步开始着手纸面部分,将文字排列成合适的顺序。我们可以通过为#container div定义如下的样式定义来完成:

container {

 width: 750px;

 background: url(paper_mid.gif) repeat-y;

 margin: 50px 0 0 25px;

 padding-bottom: 20px;

}

以上样式将container区块设置为750像素宽,同时加入了纸张的图像并将其设置为横向平铺的背景图案,另外也为#container设置了外边距和内边距以留有一定的空白。不过外边距的使用也导致了h3元素过于靠近纸面的边缘(图7-4-3),我们将在稍后修正这个问题。

figure_0267_0334

图7-4-3 应用了背景、宽度、内外边距的#cont-ainer div

7.4.3 企业标识

由于页面模仿信纸的样式,所以还需要提供公司标志和相关的图案。作品中把标志置于#pageHeader的h1元素上:

pageHeader {

 height: 100px;

 padding: 20px 0 20px 50px;

}

pageHeader h1 {

 height: 90px;

 width: 340px;

 background: url(zen_logo.gif) no-repeat;

}

随后,下面的CSS将文字隐藏,从而只显示出标志图案:

pageHeader h2 span, #pageHeader h1 span {

 display: none;

}

此时正好可以为标题和正文添加外边距,将其移至页面的中心部位:

linkList, #supportingText, #preamble {

 margin: 10px 100px 10px 200px;

}

这样,企业标志也恰好位于我们想要的地方,即页面的左上角(图7-4-4)。在标志旁显示了那条关于CSS的引用。而这也是通过为#quickSummary应用样式实现的,包括设置引用的位置、样式,并且隐藏了默认的文字:

figure_0268_0335

图7-4-4 添加了企业标识的页面。图中也可能看到,#quickSummary区域还没有应用样式

quickSummary {

 position: absolute;

 top: 50px;

 left: 450px;

 background: url(subtext.gif) no-repeat;

 height: 100px;

 width: 280px;

}

quickSummary p.p1 {

 display: none;

}

quickSummary p.p2 {

 padding: 78px 0 0 15px;

 font-size: 10px;

 font-family: "Lucida Grande", "Lucida Sans Unicode", Arial,

 sans-serif;

}

在应用了如上的图像和样式后,页面的整体感觉就如同一张正式的企业信函(图7-4-5)。不过美中不足的是信纸的顶部边缘略显僵硬。所以Hansen又通过html源文件中定义的额外的div为僵硬的边缘增添了一些活泼:

figure_0268_0336

图7-4-5 强化后的信纸头部

extraDiv1 {

 position: absolute;

 top: 10px;

 left: 23px;

 width: 750px;

 height: 50px;

 background: url(paper_top.gif) no-repeat;

}

注意,绝对定位保证了信纸能和页面其他内容正确对齐(图7-4-6),而作为标识部分的结束,#footer部分被移动到了页首图像的下方:

figure_0269_0337

图7-4-6 添加表现信纸顶部边缘的图像

footer {

 position: absolute;

 top: 160px;

 left: 150px;

 font-size: 80%;

 border-top: 1px solid #6E512F;

 padding-top: 3px;

 width: 575px;

 text-transform: uppercase;

 text-decoration: none;

 font-family: "Lucida Grande", "Lucida Sans Unicode",

 Arial,

 sans-serif;

}

上述样式为#footer添加了链接和分割线,也为作品的标识部分画上了句号(图7-4-7)。

figure_0269_0338

图7-4-7 让#footer作为页首的一部分

Note

如果能够修改页面的XHTML,那么最好将#footer改名为一个符合它实际功能的标记。在该作品中,之所以#footer元素奇怪地出现在页面的顶部,纯粹是因为禅意花园的HTML源代码就是这样组织的。不过这也从侧面说明了使用CSS可以把元素定位在页面的任何一个位置。

7.4.4 加入链接

Hansen决定让每个链接区域表现出不同的视觉效果。由于已经设定过#linkList的外边距,所以我们可以直接为其添加“Select a Design”的样式。读者可以通过在CSS源文件中查找#lselect ul和#larchives ul选择器找到这部分代码。这些样式让页脚部分的作品列表和作品存档链接显得极其引人注目(图7-4-8)。

figure_0269_0339

图7-4-8 应用了样式之后的作品存档链接

7.4.5 人性化气息

谁说以企业为主题就必须要极端庄重?Hansen就在他的作品中加入了一些人性化的设计。他首先用#pageHeader h2选择器在页面中加入了一张小纸片:

pageHeader h2 {

 background: url(paper_clip.gif) no-repeat;

 width: 320px;

 height: 262px;

 position: absolute;

 top: 250px;

 left: -6px;

 z-index: 5;

}

Hansen又一次使用绝对定位来将纸片精确定位在他选择的地方。而在纸片下还有一张便条纸,用来提供资源链接。便条纸的样式定义可以在CSS源文件中找到,下面的代码仅仅用来演示便条纸是如何加入到页面中的:

lresources {

 position: absolute;

 top: 600px;

 left: 10px;

 width: 200px;

 height: 257px;

 background: url(sticky.gif) no-repeat;

 font-family: "Lucida Grande", "Lucida Sans Unicode",

 Arial,

 sans-serif;

 color: #000;

}

现在,页面的左侧加入了两项绝对定位元素,极大地增强了页面的真实感(图7-4-9)。而最后加入的钢笔则使作品的整体形象更为丰满,钢笔本身是通过#extraDiv2选择器绝对定位于页面右部的(图7-4-10)。

figure_0270_0340

图7-4-9 使用绝对定位的纸片和便条纸

figure_0270_0341

图7-4-10 钢笔的造型打破了作品中的严肃气氛

extraDiv2 {

 position: absolute;

 top: 900px;

 left: 700px;

 background: url(pen.gif) no-repeat;

 width: 140px;

 height: 547px;

}

7.4.6 完稿

Corporate ZenWorks依靠浓重的主题色彩构建出了一个绝无仅有的独特站点。尽管之前Derek Hansen曾遇到过诸如字体限制、GIF图像质量和PNG文件兼容性等问题,但作品的最终整体效果仍非常精致优雅。

7.5 Open Window(敞开窗口)

Ray Henry,设计师

www.csszengarden.com/090

同一设计,三种布局

Ray Henry在抓拍景色的那一刹突然捕获了创作Open Window的灵感。为了避免作品落入俗套,Ray Henry在创作过程中选择了另辟蹊径。他摒弃了固定导航菜单、广告条幅等传统模式,尝试将关键元素置于页面底部,从而造就了一种令人耳目一新的风格。

但由于Windows平台上的IE浏览器不支持固定定位,所以Henry在创作中不得不花费额外的精力以解决浏览器兼容性问题,为了确保作品在各种现代浏览器都能正常显示,最终他还是不得不使用了一些CSS hack(图7-5-1)。

figure_0271_0342

figure_0272_0343

图7-5-1 Open Window中使用的图像。包括那张带给作者创意灵感的照片

7.5.1 基本部分

Henry从body和container元素入手勾画整部作品。他首先禁用了默认的body内外边距和字体设置:

body#css-zen-garden {

 background:#A1B4CD;

 margin:0;

 padding:0;

 font-family:verdana, arial, sans-serif;

 font-size:11px;

}

之后,Henry将#container的width设置为100%,实现能够填满整个窗口的流式布局:

container {

 width:100%;

 text-align:left;

}

在开始下面的内容之前,页面布局在各个浏览器下的样式都是一致的(图7-5-2)。

figure_0272_0344

图7-5-2 在完成基本设置之后,所有的浏览器中的样式都能保持一致

7.5.2 修正导言部分

在对#intro进行布局之后,作品的设计过程开始变得耐人寻味起来:

intro {

 width:100%;

 height:276px;

}

html>body div#intro {

 position:fixed;

 bottom:0px;

 right:0;

}

html*#intro {

 border-bottom:3px solid #fff;

 position:fixed;

 bottom:-10px;

}

intro {

 height:286px;

 voice-family: "\"}\"";

 voice-family: inherit;

 height:auto;

}

在上面这些CSS代码中,我们可以看到很多专为某个特定浏览器设计的特殊样式。第一条样式中的#intro选择器对所有浏览器都有效。接下去的两条样式则只对支持固定定位的“高级”浏览器有效。第三条定义了border属性,Windows平台上的IE 6也能正常支持。而在最后一个样式中,Henry使用了一些盒模型的hack,用来修正IE 5对#intro区块height属性的错误理解。

可以看到,目前在IE中#intro区块位于页面上方(图7-5-3),而在Mozilla和Safari中,#intro却位于页面的底端(图7-5-4)。

figure_0273_0345

图7-5-3 在IE中,#intro出现页面的头部,且底部有一条白色边线

figure_0273_0346

图7-5-4 在Mozilla(和Safari)中,#intro固定于页面底部,可以看到它目前遮挡住了部分其他文字

7.5.3 上、下、左、右

目前为止,页面的顶部和底部均已定义完成。当然,事实上顶部和底部是同一个部分,只不过通过使用一些过滤规则让其在不同浏览器中出现在不同的位置而已。

1.页面右侧

在制作页面右侧内容时,Henry首先加入了一张图像,以确定页面的色彩基调和图像布局:

pageHeader {

 background:url(pageHead_bg.jpg) no-repeat top left;

 width:332px;

 height:283px;

 position:absolute;

 right:0;

 top:0;

}

以上代码在IE(图7-5-5)和Mozilla中都能正常地定位#pag-eHeader元素,不过其具体位置则取决于浏览器对固定元素的支持程度(图7-5-6)。Opera则尚不能显示这张图像,我们还需要继续努力。

figure_0274_0347

图7-5-5 图像在IE浏览器中位于页面右上方

figure_0274_0348

图7-5-6 图像在Mozilla中也位于右上方,尚不能完全显示出来

2.页面左侧

下面的CSS代码定义了#preamble的样式,这里我们对次要细节进行了删减,意在重点演示内容部分的布局方法:

preamble {

 background:#A1B4CD url(preamble_bg.gif) repeat-y topright;

 height:283px;

 width:312px;

 margin:0;

 padding:0;

 position:absolute;

 left:0;

 top:0;

}

html>body #preamble {

 position:absolute;

 left:0;

}

可以看到,其中第一个#preamble选择器设置了区块的位置(图7-5-7)。之后的那条样式使用了子选择器,因此在支持子选择器的浏览器中, #preamble将会被绝对定位于页面的左侧。(图7-5-8)。

figure_0274_0349

图7-5-7 #preamble区块在IE中位于页面的左上方

figure_0274_0350

图7-5-8 图像在Mozilla(和Safari)中位于页面的左下角。#pageHeader部分尚无法完全显示

3.页面中部

随后,Henry又将#quickSummary区块放置在#pageHeader和#preamble之间:

quickSummary {

 background:url(quickSum_bg.gif) repeat-x top right;

 border-right:3px solid #fff;

 margin:0 332px 0 312px;

 padding:52px 0 0 0;

 height:283px;

 voice-family: "\"}\"";

 voice-family: inherit;

 height:231px;

}

这里用到的唯一技巧就是#quickSummary声明中出现的盒模型hack,用来修正无法正确支持盒模型的浏览器中对宽度的解析。

在使用了盒模型hack后,3种布局的显示问题得到了初步解决。可以看到:在IE中,图像将显示在页面的顶端(图7-5-9),而Mozilla中将显示于页面底部(图7-5-10)。你同样会发现,在Opera中,问题也似乎有了好转的迹象(图7-5-11 )。

figure_0275_0351

图7-5-9 IE中的效果,注意标题位于页面顶端

figure_0275_0352

图7-5-10 在Mozilla中,相应的区域则显示在页面底部

figure_0275_0353

图7-5-11 Opera中则只出现了中间的一小部分

Note

若想了解更多“Box Model Hack”的细节,请参考http://tantek.com/CS S/Examples/boxmodelhack.html。

7.5.4 为内容和链接应用样式

接下去需要为页面的内容和链接部分应用样式。读者可以在禅意花园的站点上下载到这部分的完整样式规则,书中限于篇幅,只能列出一部分最有价值的代码。其中的第一条使用了浮动特性,将内容部分置于页面的左侧。

supportingText {

 width:100%;

 float:left;

 margin-right:-332px;

 margin-top:-3px;

}

还有一处值得关注的地方就是有关外边距的设置。在上面的样式中我们可以发现,即便宽度被设为100%,仍可以用负的外边距调整文字区域的显示样式。负的右外边距的作用和正的右内边距相同,都可以保证文字不会超过右侧图像的左边缘。但在这里,我们却不能将右内边距应用于width为100%的情况,否则将导致#supportText的宽度为100% + 332px。接下来是#footer的样式,可以看到其中也考虑到了浏览器兼容问题:

footer {

 background:#d6e0ee;

 margin:0 332px 0 0;

 border-right:3px solid #fff;

 border-top:3px solid #fff;

 border-bottom:3px solid #fff;

 padding:15px 0;

 text-align:center;

}

html>body #footer {

 background:transparent;

 position:fixed;

 right:0;

 bottom:261px;

 padding:0;

 margin:0 160px 0 0;

 border-right:0;

 border-top:0;

 border-bottom:0;

 text-align:left;

}

这个样式在IE中会将页脚部分定位于页面的底端(图7-5-12),而在Mozilla中则会将其定位于页面的底部(图7-5-13)。

figure_0276_0354

图7-5-12 在IE中,#footer位于正文部分的底端

figure_0276_0355

图7-5-13 在Mozilla中,#footer是固定底部的一部分

7.5.5 解决Opera中的问题

目前为止,整个设计在IE、Mozilla和Safari中都没什么问题。但前面曾提到过,我们还要为Opera进行一些调整,以便让顶部区域能够正常显示。下面这段CSS代码就是专门为Opera准备的:

@media all and (min-width: 0px){

 div#intro {

  position: absolute;

  right:0;

  width:100%;

  height:283px;

  top:0;

  z-index: 0;

  border-bottom:3px solid #fff;

   {

 }

这里用到了CSS3规范中的“Media Queries”技术,直接向Opera 7发送了属性设置。可以看到在应用了这段代码之后,作品在Opera中的效果也非常令人满意。

Note

若想了解Opera 7中CSS 3 @media技术的更多信息,请参考www.virtuelvis.com/archives/2004/01/css-for-opera-7。

7.5.6 三位一体

Henry的最初目标是使作品在Mozilla和Safari中能正确显示;然后又用一些技巧满足了IE的要求;最后还为Opera找到了折衷的方案,将图像顺利地置于顶部。不过还有一点需要注意的是,Opera版本的正文只是在顶部图像的下方滚动,图像本身的位置则始终保持固定,这和IE中的情况又有所不同。这也正是Henry在实验中发现的一种令人耳目一新的布局方法,并最终让他确定了作品的名称——Open Window。

7.6 mnemonic(记忆)

Dave Shea,设计师

www.csszengarden.com/025

流式布局和高级效果的技巧

明亮的线条和几何造型交织流动于背景中,束状的细线覆盖于水平的条带之上组成了标题,设计师Dave Shea正是用这样一组明快的亮色构成了作品mnemonic的基调。

Shea试图用这部作品带来一些新的设计理念,而他的作品也的确展现了一种独特的布局。或许mnemonic并不像其他作品那样有特别深刻的内在美,但其中一致的视觉观感和显眼的主体内容使作品仍称得上相当优秀。

在这部作品的设计和编码过程中体现了作者很多灵感和创意。在这里,我们强烈推荐阅读带有注释的原始CSS文件(www.csszengarden.com/025/025-comments.css)。至于作品中所需的图像,可在图7-6-1中找到。

figure_0277_0356

figure_0278_0357

图7-6-1 mnemonic中用到的所有图像

7.6.1 解决问题

在完成基本样式(下面的代码没有列出这部分样式,但读者可以在图7-6-2中看到应用样式后的效果)之后,第一个问题随之出现——这里我们需要2张不同的主体背景,一张水平平铺的背景和另一张叠放于其上的垂直平铺背景。

figure_0278_0358

图7-6-2 基本样式,包括链接颜色和字体

body {

 font-size: small;

 font-family: arial, sans-serif;

 background: #B0A40B url(bg-1.gif) top left repeat-x;

 margin: 0px;

 padding: 0px;

}

在应用上述CSS之后,body元素即被赋予了水平平铺的背景(图7-6-3)。但CSS不支持为同一元素设置多个背景图像,所以唯一的选择只能是使用两个元素。所幸的是,#container元素恰好位于body内且包围着其余元素,非常适合放置第二张图像:

figure_0278_0359

图7-6-3 应用于body元素的背景图像

container {

 background: transparent url(bg-2.gif) top right repeat-y;

 }

这样也就成功地完成了该技巧。在这部作品中,页首部分聚集了大量的图像,所以下一个挑战就是如何将这些图像聚合成一条位于页面顶端的、可伸展的条带,且同时还必须保证所有图像都有统一的视觉效果。

制作图像

通过观察最终的作品,我们可以发现mnemonic中包含了大量视觉元素。那么究竟是该选择绝对定位方式将每个元素置于其他元素之上,还是把所有的元素合并为在同一张大图像中呢?

要想解决这个问题,我们就必须在两个极端中做出选择——要么找出相关元素合并成一个JPG文件,要么就将不同元素分别存为各自的GIF文件。这个问题的最终取舍取决于个人喜好和站点的限制,而没有什么绝对“正确”的答案,因此不同的设计师很有可能得出迥然不同的结果。

我们知道,禅意花园的HTML文件不可更改,所以mnemonic只能使用#pageHeader中的两个标题元素(h1、h2等)和一个div元素载入图像。由于总共只有这3个元素,所以我们最多也只能放入3张图像。考虑到这些,作者将顶部左侧的图样(除去左上角)保存于一张图像中,将顶部的右侧存为另一张图像,而第三张则是个较窄的GIF图像,用于页首部分的重复背景。

有一点可能让人疑惑,就是mnemonic如何通过使用固定尺寸元素创建变宽布局。一般情况下,固定尺寸元素更适合固定宽度布局,而对于流式布局的mnemonic,位于页面左右两侧的定宽图像会在中间形成一段空白间隙。Shea聪明地使用了条带状的第三张背景图像填充了这条空隙(图7-6-4),这样也就保证了流式布局不会被破坏。

figure_0279_0360

图7-6-4 mnemonic中的页首图像

在确定了使用哪些图像之后,接下来就是将它们合成起来。其中页首重复的图案应被布置在其他元素之后(图7-6-5):

figure_0279_0361

图7-6-5 首先加入重复背景

pageHeader {

 height: 171px;

 padding: 0px;

 background: transparent url(bg-4.gif) top left repeat-x;

}

虽然禅意花园预先定制HTML对图像的应用会产生或多或少的限制,但在将一些图像合并之后,我们依然能够留出足够多的用于装载图像的HTML元素。由于在mnemonic的设计中,#pageHeader里的h1和h2的文字只需绘于一幅图像(位于头部的右侧的那幅)中即可,所以另一个标题元素就能节省下来以放置其他图像。在该作品中,作者用它放置页面左侧的图像(图7-6-6和图7-6-7):

figure_0279_0362

图7-6-6 页首左侧的图像被放置于一个闲置的标题元素中

figure_0280_0363

图7-6-7 h1和h2中的文字被置于同一个元素中

Note

在开始mnemonic这样复杂的设计之前,要有着良好的布局规划。如果到CSS编码阶段才考虑布局问题,将难免需要不停返工,做大量的更改。

pageHeader h1 {

 padding: 0px;

 margin: 0px;

 float: left;

 width: 396px;

 height: 171px;

 background: transparent url(cr-tl.jpg) top right no-repeat;

}

pageHeader h1 span {

 display: none;

}

在加入左侧图像后,Shea将右侧带有文字的图像置于h2元素中:

pageHeader h2 {

 padding: 0px;

 margin: 0px;

 position: absolute;

 top: 0px;

 right: 0px;

 width: 350px;

 height: 171px;

 background: transparent url(cr-tr.gif) top right no-repeat;

}

pageHeader h2 span {

 display: none;

}

7.6.2 向前推进

在这里我们略去了布局构建的详细过程,而直接转向作品中应用的高级效果。如果曾查看过作品CSS源文件的话,可以发现在文件的尾部有一处注释标识了高级效果的开始。若是移除了该标识后的代码,页面效果将如图7-6-8所示。事实上,这也是作品在IE中的最终效果。而如果使用的是Firefox或者Safari,那看到的效果将如图7-6-9所示。

figure_0280_0364

图7-6-8 去除了特殊效果的作品。这和IE浏览器中的最终效果是一致的

figure_0280_0365

图7-6-9 包含特殊效果的作品

1.问题的本质

对于某些没有赋予class或者id的元素,可以使用CSS2中新增的各种选择器为它们设置样式,当然并不是所有的浏览器都支持这类功能。但Shea在创作中使用这种技术的原因也很简单——他无法用CSS1中的常规选择器选中某个元素。若是能够修改禅意花园的HTML源文件的话,则只需为HTML元素加入更多标识符,问题即可迎刃而解。

因而在撰写HTML时,需要在简洁的HTML代码和足够多的标识符之间找到平衡点。禅意花园在设计HTML文件之初已经尽力为选择元素留下了相当高的灵活性,但事后人们却发现这样的灵活性在某些情况下依然不能满足需求。当然,在通常的项目中,HTML和CSS的设计是同步的,读者可以自行把握标识符的多少,以实现最终效果。

2.作品列表

从图7-6-10中可以看到,IE中作品列表呈垂直排列,而在Firefox和Opera中则成对排列且略带倾斜(图7-6-11)。若想实现第二种效果,我们就必须逐个选择每个列表项,然后将其分组排列。作者所使用的方式是一组逐渐增长的子选择器和邻接选择器。这两种选择器均已定义于CSS2中,但不为IE所支持:

figure_0281_0366

图7-6-10 IE中显示的作品列表

figure_0281_0367

图7-6-11 Safari和Firefox中显示的作品列表

Note

省略号代表之后还有部分代码。

lselect .ul>li {

 position: relative; left: -14px;

}

lselect ul>li+li {

 position: relative; left: -12px;

}

lselect ul>li+li+li {

 position: relative; left: -10px;

}

在上述代码中,第1个选择器选择了#lselect中的ul元素的任意li子元素。第2个选择器和第一个没有太大区别,只是规定这个li元素必须有一个li元素作为前驱。第3个则规定必须有2个li元素作为前驱,第4个需要3个li前驱……依此类推。就是通过这样一组层叠的设置,将每条设置覆盖前一条设置中的属性,最终为8个li元素逐个定位。回过头来看,不得不说这个复杂的方案仅仅是用来解决一个原本应该极其简单的问题——因为在多数情况下,都可以用加入额外的id和class解决该问题,而无须如此冗长的CSS结构。我们也不建议在实际开发中书写类似的CSS。

  1. Previous/Next链接

作品中遇到的最后一个难题是,如何用一图像表示的文字替换作品列表中呆板的默认链接(图7-6-12和图7-6-13)。而这个需求也同样面临着缺少元素标记的问题,因此,作品最终的实现已不仅限于子选择器和邻接选择器,还使用了一些更加高级的属性选择器。在禅意花园的HTML源代码中,可以看到Previous/Next链接都被赋予了不同的HTML accesskey:

figure_0282_0368

图7-6-12 IE中“Next Design”和“View All Design”的显示效果

figure_0282_0369

图7-6-13 “Prior”、“Next”和“View All”在Safari和Firefox中的显示效果

<a href="http://www.mezzoblue.com/zengarden/alldesigns/"title="View every submission to the Zen Garden. AccessKey:w" accesskey="w">

找到了这样的特征之后,问题即可迎刃而解。下面是其具体的实现方式:

larchives ul>li+li a[accesskey="w"] {

 display: block;

 width: 35px;

 height: 0;

 overflow: hidden;

 padding-top: 18px;

 background: transparent url(archive-b3a.gif) top left

 no-repeat;

 position: absolute;

 top: 16px;

 left: 170px;

 color: #958500;

}

顾名思义,属性选择器用于选择具有指定属性值的元素。由于需要应用样式的a元素的accesskey属性值为w,所以上述代码即可轻松地找到相应元素并随后应用样式。

这时,细心的读者或许会产生这样的疑惑:之前的作品列表同样也有类似的accesskey,可为什么还是使用了一串冗长的子选择器呢?如果您能想到这一点,那实在太棒了。事实上,用accesskey选择元素也确实更为合理。

7.6.3 做出最恰当的选择

mnemonic的设计就是一个选择的过程。为了达到同样的效果,Shea完全可以在Photoshop中做出不同的图像切分,或者用其他什么方法来选取作品列表中的元素。而在网页设计的过程中,也总是充满了类似的选择和岔路,如果能明察所有的选项,那么定会做出最恰当的选择。