HWeb-标准的创造性-一-

105 阅读1小时+

HWeb 标准的创造性(一)

原文:Web Standards Creativity

协议:CC BY-NC-SA 4.0

一、语义结构,肮脏漂亮的呈现

西蒙·科里森

www.collylogic.com

在 2006 年开始厄斯金设计之前,西蒙·科利森是 Agenzia ( www.agenzia.co.uk)的首席网页开发员,在那里他为唱片公司做了许多网页项目。Simon 热情地确保他构建的所有东西都是可访问的,并且符合当前的网络标准。

西蒙与人合著了博客设计解决方案CSS 掌握(均由 ed 之友出版)。他的第一本个人书籍开始 CSS Web 开发 ( www.csswebdevelopment.com)于 2006 年由 Apress 出版。

在办公室之外,Simon 经营着一个很受欢迎的博客 Colly Logic ( www.collylogic.com),他是一个所谓的 Britpacka 集体的活跃成员,这个集体由懒散的设计师和开发人员组成,他们都热衷于负责任的网页设计。当西蒙离开笔记本电脑时,他很可能出现在酒吧或音乐会上,不停地谈论好音乐、足球或饼干。

Semantic Structure, Dirty Pretty Presentation Semantic Structure, Dirty Pretty Presentation

西蒙曾在许多城市生活过,包括伦敦和雷克雅未克,但现在他回到了他心爱的诺丁汉,那里的草是绿色的,女孩也很漂亮。

简述

对于唱片公司来说,建立一个符合网络标准的网站是一个挑战。多年来,Flash 一直是乐队网站的必备工具。此外,还有深不可测的导航挑战、点唱机插件、框架、可疑的调色板和无处不在的Loading栏。虽然网络看起来很流行,但在音乐行业,它仍然是 1999 年。正如丹·鲁宾将在本书第二章中阐述的那样,情况正在好转,但是好的网站仍然少之又少。

对于 Dirty beautiful Things 网站(www.dirtyprettythingsband.com),我和我在 Agenzia 的设计师同事有机会在 2004 年夏天重新推出的 Libertines ( www.thelibertines.org.uk)网站的基础上再接再厉(见图 1-1") )。我们按照 Web 标准构建了 Libertines 网站,以负责任的方式使用 Flash 元素。我们不顾一切地将内容和表现分开,以利用越来越多的用户通过移动设备访问网站,并确保核心内容的持久性,不管未来的重新设计如何。碰巧的是,英国摇滚的巨大希望在过度和不良行为的漩涡中解散了,但该网站仍然拥有不断增长的用户群体。

18 个月过去了,Libertines 的联合创始人 Carl Barat 组建了一个新的乐队,音乐媒体和乐迷们对此寄予厚望。由于各种错误的原因,前放荡不羁的名人皮特·多赫提充斥着各种小报,现在轮到卡尔和他的公司把欢乐带给成千上万把灵魂出卖给放荡不羁者的粉丝了。从一开始,很明显,任何新网站都将是受欢迎的一方,根据我们从 Libertines 网站获得的经验,很容易说服唱片公司,网络标准是唯一的出路。

Hannah Bays 为乐队创作的大量原创作品扔给了我们,虽然独特而又酷,但似乎没有一件适合网页设计。事实上,整合设计是一个漫长的过程,当我们开始只用 XHTML 和 PHP/MySQL 构建网站的核心内容时,这个过程就被搁置了。

The final version of the Libertines website (www.thelibertines.org.uk)

图 1.1。浪子网站的最终版本(www.thelibertines.org.uk )

本章将加入我们完成 XHTML 和数据库的过程,并返回到表示方法,看看这是如何通过使用 CSS 的一个单独的层来实现的。重点将放在应用外观的视觉接触,如自定义背景,标题和 CSS 的其他部件,留下核心内容不妥协。图 1-2, launched in January 2006") 显示了网站的最终版本。

The completed Dirty Pretty Things website (www.dirtyprettythingsband.com), launched in January 2006

图 1.2。完成的脏漂亮的东西网站(www.dirtyprettythingsband.com),于 2006 年 1 月推出

语义结构

我们在这里举着 Web 标准的旗帜,所以我们需要确保文档(XHTML plus 内容)与表示(CSS 和装饰性图像)是分离的。通过使用外部样式表应用所有装饰性的表示丰富性,文档(XHTML)保持纯净和集中。由于所有的表示材质都与标记分开保存,所以站点范围内的样式变化可以轻而易举地完成。我们只需要修改一个 CSS 文件,而不是更新网站中的每个页面,这使得大规模的重新设计变得轻而易举。同样重要的是,如果需要,用户可以通过将自己的样式表应用到网站来控制内容。

一个重要的步骤是给添加到核心内容的任何部分(divs)起一个有意义的名字,而不是表象的名字。比如刊头叫masthead,主栏叫content_main,等等。这种方法也适用于较小的细节,比如用于改变元素颜色或强调的 id 和类名。创建一个名为green_heading的类是没有意义的,如果这个类以后可能会被 CSS 用来将标题渲染成蓝色。取而代之的是,类被赋予一个描述元素角色的名字,而不是它的风格,比如date_heading。在大多数情况下,甚至不需要这样的挂钩,因为样式表中的后代选择器用于选择其他元素的子元素。您将在本章后面的“内容”一节中看到它是如何工作的。

图 1-3 as styled purely by the browser's default style sheet") 显示了由浏览器自己的默认样式表设计的网站截图。该站点是一个功能完整的数据库驱动的站点,它完成了构建的第一阶段,并展示了即使样式表不可用,一切都可以很好地运行。

随着构建阶段的结束,团队现在可以开始认真考虑表示,以及如何将核心内容用作网站外观和感觉的框架。是时候变脏,变漂亮了。

The document (XHTML plus content) as styled purely by the browser's default style sheet

图 1.3。文档(XHTML plus 内容)的样式完全由浏览器的默认样式表决定

The document (XHTML plus content) as styled purely by the browser's default style sheet

肮脏漂亮的展示

当纯粹用 XHTML 构建时,明智的做法是对站点的布局有一个好的想法。很自然地,我们会考虑列和核心区域,比如页眉和页脚,并且这通常会通过 Photoshop 布局(或者甚至是使用铅笔和纸的草图)来传达。)来自团队里的一个设计师。但在《肮脏美丽的事物》网站上,情况并非如此,因为我们都还没有达成一个我们自己都同意的布局,更不用说唱片公司的人了。

通过对功能齐全的 XHTML 站点应用外部样式表,我们有机地解决了这个问题。这意味着,当我们失去了一个一致同意的设计,我们开始通过 CSS 的实验来建立一个外观和感觉。通过创建和修改 CSS 规则,我们测试了从布局(流动、固定或弹性)到字体选择的一切。这种方法很慢,并且需要 Photoshop 一直打开来创建和调整背景图像,这些图像可能会也可能不会进入最终的设计,但这是一个令人兴奋的过程,它消除了已交付的、一成不变的设计的约束。

有了 Hannah Bays 的所有原创作品,并慢慢开发高度、宽度、边距和填充等参数,一个令人满意的设计很快就会实现。由于样式表应用于站点的所有页面,所以很容易看出什么在站点范围内起作用。艺术品的哪些区域可以作为背景?某些区域可以作为背景瓷砖吗?从收集的源材质中,文本和核心元素的通用调色板是否可以实现?

下一步是与同事讨论设计,包括抚摸下巴和喝咖啡,然后确保客户对目前的进展感到满意。然后,我们一点一点地琢磨这些成分,使设计更加严谨,然后再进行可用性测试。最后,网站启动了,收集到的 Agenzians 人可以去酒吧。

背景图片

也许从 XHTML 到精心设计的漂亮风格的最戏剧性的变化发生在主背景图像与报头及其后代相遇的地方。大量精心的 Photoshop 工作使用了一系列背景图像,如图 1-4 所示。

Split into several layers, various background images are juxtaposed.

图 1.4。拆分成几层,各种背景图片并置。

注意

在你开始拼命使用背景图片之前,重要的是要考虑这会如何影响最终用户。虽然没有以前那么重要,但你仍然需要意识到,有些人正在使用非常慢的调制解调器下载网页。一个典型的网页可能包含大约 15KB 的文本,因此下载速度非常快。再加上 35KB 的背景图片,你就大大降低了访问者的浏览速度,至少在浏览器缓存图片之前是如此。保持图像使用光线,只有在真正必要时,或者当你为你知道将使用超高速宽带连接的观众设计时,才过度使用光线。

在任何情况下,如果图像不显示或被用户手动禁用,我们都不会使用背景图像来传达重要信息。例如,我们不使用背景图像来显示网站的标题、任何导航项目或任何类型的扁平文本内容,除非我们在图像关闭的情况下也使用标准文本来提供这些信息。背景图像是装饰性的装饰品,当然不能被认为是“内容”,这就是为什么它们在样式表中作为单独的表示元素被引用。

背景、标题和菜单

我们将从背景、标题和主菜单这三个主要层在现有 XHTML 上的样式开始。

一个内嵌图像已经出现:主要的脏漂亮的东西标志。徽标(图 1-5 )是一个动画 GIF,当页面第一次加载时,它会一个字母一个字母地拼出乐队名称。该徽标在文档流中,位于刊头的左上方。

The Dirty Pretty Things logo becomes an animated GIF, with a jagged background.

图 1.5。Dirty beautiful Things 徽标变成了一个带有锯齿状背景的动画 GIF。

查看这一部分的 XHTML,您会看到波段名也在<h1>元素中指定,该元素使用display:none隐藏。这是为了确保如果图像和 CSS 被禁用,该网站仍然是品牌。

<div id="wrapper">
  <div id="masthead">
    <a href="home"><img src="logo.gif" alt="Dirty Pretty Things" /></a>
    <h1>Dirty Pretty Things - Official Website</h1>
  </div>
    ...rest of content...
</div>

The Dirty Pretty Things logo becomes an animated GIF, with a jagged background.

背景

接下来,我们将主背景图像(图 1-6 )应用到<body>元素。虽然比理想的要大得多,但是 JPG 的图像将会像瓷砖一样工作。我更喜欢使用 GIF 格式的背景图像,但是这个大背景图像的细节层次和图像层次要求 JPG 格式有更大的灵活性。

The main background image, which will be placed in the center and tiled horizontally

图 1.6。主背景图像,将被放置在中心并水平平铺

我们在 CSS 中使用背景速记将平铺显示放在顶部中央,并确保它只水平平铺。查看正文选择器的 CSS,您会看到除了主字体规则和其他项目之外,所有背景规则都使用 CSS 简写进行组合,顺序为background-colorbackground-imagebackground-positionbackground-attachmentbackground-repeat

body {
  margin: 0;
  padding: 0;
  font-size: 95%;
  font-family: Georgia, 'Lucida Grande', Verdana, sans-serif;
  text-align:center;
  color: #333;
  background: #C6C2B6 url(img/background.jpg) center top fixed repeat-x;
}

注意

由于图像是水平重复的(repeat-x),无论浏览器窗口有多宽,它都会占据整个网站的宽度。但是,页面background-color是在背景拼贴底部的平面颜色上采样的。与这种颜色结合的图像将完成整个背景,并给人一种背景图像高得多的印象。

在速记中,我们使用了background-attachment:fixed来防止背景与页面的其余部分一起滚动,并使用background-position:center top来确保第一个背景图像平铺的中点与浏览器窗口的中点保持一致。填充宽度所需的所有其他图块将放置在该初始居中图像的左侧和右侧。

刊头

下一个任务是控制包装和报头。刊头背景图片(图 1-7 )是在 Photoshop 中创建的,其中有一个徽标的展平版本。在导出图像之前,徽标已被移除并替换为黑色。我们知道,只要没有对刊头应用填充,动画徽标就会出现在刊头背景的左上角。

The masthead background image

图 1.7。报头背景图像

现在可以为模板定义一些关键规则了。已经定义了body选择器,并将所有元素设置为居中对齐(text-align:center)以便我们的内容区域居中,重要的是将下一个主要元素(用 ID wrapper定义)设置为text-align:left,这是一个所有后代都将继承的值。边距值(0 auto 0 auto)将确保wrapper的左右边距相等,无论浏览器窗口的宽度是多少。

#wrapper {
  width:779px;
  margin:0 auto 0 auto;
  text-align:left;
}

现在,基于报头背景图像的宽度和高度,在报头声明中指定了相等的值。使用试错法来指定边距值,以便在固定背景的顶部对齐我们想要的标题。通过指定 15px 的上边距,我们可以确保当内容开始在固定背景上滚动时,在刊头上方刚好有足够的主背景图像可见。background-color是从刊头所在的主背景区域取样的。这个区域包含了几种颜色,但是做了一个粗略的匹配,所以如果用户在等待报头图像的加载,事情看起来还可以。

#masthead {
  width:768px;
  height:254px;
  margin:15px 0 0 8px;
  color:#030;
  background: #ECE4D9 url(img/masthead.jpg) no-repeat
}

最后,主内容选择器返回到wrapper中定义的full-width,允许所有剩余内容重新开始,并指定新的背景图像。这个新图像向各个方向平铺,尽管内容区域的宽度仅够显示垂直平铺。此拼贴扩展了刊头背景中使用的边缘,给人一种又长又旧的页面的感觉。

#content {
  width:779px;
  background: url(img/content.gif)
}

The masthead background image

导航菜单

下一步是将主导航菜单添加到报头中(见图 1-8 在做出最终决定之前,我们尝试了各种报头想法)。在 XHTML 阶段,我们知道我们想要将导航分成两部分,因为我们已经为 Libertines 网站做了类似的事情,并且发现这是一种充分利用报头空间的极好方式。

Various masthead ideas

图 1.8。各种报头创意

标记如下所示。请注意,两个列表都有相同数量的列表项,并且每个菜单列表都有唯一的 ID ( m1m2)。

<ul id="m1">
  <li><a href="#" id="nav_a">Home</a></li>
  <li><a href="#" id="nav_b">News Archive</a></li>
  <li><a href="#" id="nav_c">Band Diary</a></li>
  <li><a href="#" id="nav_d">Gigs</a></li>
  <li><a href="#" id="nav_e">Downloads</a></li>
</ul>
<ul id="m2">
  <li><a href="#" id="nav_f">Discography</a></li>
  <li><a href="#" id="nav_g">Gallery</a></li>
  <li><a href="#">Merchandise</a></li>
  <li><a href="#" id="nav_h">Members Area</a></li>
 li><a href="#" id="nav_j">Forums</a></li>
</ul>

我们还知道每个菜单项可能有独特的处理方式,所以每个链接都有自己独特的 ID,很快就会派上用场。

如果没有 CSS,这两个列表将以正常的流程出现,一个在另一个下面。因此,我们使用 margin 值来推动和拉动每一个位置。第一个(m1)被简单地给定了 20px 的左边距,使其远离报头的左边缘。第二个(m2)从刊头的左边缘移动 130 像素,从其自然位置移动 160 像素。因此,m2被移到了另一个菜单的右下方,然后拉高到足以与它对齐,这要感谢大的负顶部边距。不需要定位或浮动。

#masthead ul#m1 {
  margin: 0 0 0 20px;
  padding-top:5px;
}
#masthead ul#m2 {
  margin:-160px 0 0 130px;
}

Various masthead ideas

有了我们想要的无序列表,我们可以开始考虑列表项了。每个都被赋予一个heightwidth,加上一些其他的自定义值,所有的都将共享。

#masthead ul li {
  width:135px;
  height:25px;
  list-style-type: none;
  padding-top:4px;
  font-size: 12px;
  letter-spacing:0.07em;
}

接下来,我们选择每个列表项中的链接。大多数是跨各种状态的常见链接方法,但我们发现包含display:block以防止应用于每个链接的各种边距值导致链接聚集在一起并造成巨大破坏是至关重要的。

#masthead ul li a {
  display:block;
  padding-left:11px;
  text-decoration:none;
  font-weight:bold
}
#masthead ul li a:link, #masthead ul li a:visited, #masthead ul li a:active {
  color:#FFF;
}
#masthead ul li a:hover {
  color:#F00;
}

有了所有这些,两个菜单被准确地放置在我们想要的位置,现在我们可以考虑单独处理每个链接了。

前面我提到过,我们已经给了每个链接一个唯一的 ID。这些钩子现在可以让我们玩得开心了。在 Photoshop 中,我创建了三个不同的背景图像,它们都适合我们的<li>元素的给定宽度。我们现在可以随机地将这三种背景中的任何一种应用于每个 ID,并为每个 ID 设置一个唯一的左边距,这给了我们稍微随机的对齐,以及不同的背景。

下面的 CSS 显示了十个 id 中的三个是如何在样式表中定义的:

#nav_a {;
  background: url(img/buttonback1.gif) no-repeat;
}
#nav_b {
  margin-left:6px;
  background: url(img/buttonback2.gif) no-repeat;
}
#nav_c {
  margin-left:4px;
  background: url(img/buttonback3.gif) no-repeat;
}
...etc...

除非你仔细研究最终结果,否则似乎每个列表项都有一个独特的背景,而实际上我们只是简单地交替使用这三个。

在每个模板上,一个 ID 被添加到<body>元素中,目的是用 CSS 应用程序的一个小技巧轻松地突出显示主菜单中的当前页面。

<body id="home">

在 CSS 中,<body>中的id选择器和附加在每个菜单链接上的id之间的关系被粘合。第一部分#home,将动作指向元素选择器为home的实例。第二部分#m1 a#homebutton,在#m1列表中查找被标识为homebutton的链接。如果找到匹配,则执行该操作。注意,为了节省空间,这里只显示了三个匹配。

/* Highlight the current page */
#home #m1 a#homebutton, #news #m1 a#newsbutton, #diary #m1 a#diarybutton {
  color: #F00;
}

因此,每当用户查看主页时,链接颜色将被设置为红色,但在滚动时仍然是白色。从 CSS 来看,应该清楚新闻模板用的是<body id="news">,日记模板用的是<body id="diary">。剩下的唯一工作是为每个需要与模板对应的唯一链接 ID 复制 CSS,将目标分组到一个整洁的无所不包的定义中。

Various masthead ideas

内容亮点

有了背景、标题和主导航之后,我们可以更仔细地看看主要内容区域中发生的一些有趣的事情。我们将探究标题、表格和定义列表。

标题

Dirty beautiful Things 网站大量使用了 2 级(<h2>)和 3 级(<h3>)标题。最值得注意的是,二级标题用在所有页面的主要内容区域和侧边栏的顶部,但是有不同的外观。这是通过在样式表中使用后代选择器实现的。

下面的标记反映了一个简化的侧栏。注意,主内容中的<h2>元素也没有惟一的 ID 或类。

<div id="sidebar">
  <h2>The Band</h2>
  <p>Dirty Pretty Things are Carl Barat, Anthony Rossomando, Didz Hammond and Gary Powell.</p>
</div>

图 1-9 显示了用于两个<h2>元素的两个背景图像。

Two jagged background images are used for the two differently sized level 2 headings.

图 1.9。两个参差不齐的背景图像用于两个不同大小的级别 2 标题。

主内容区域中使用的<h2>的 CSS 规则相对简单。注意blackhead.gif被指定为不重复的背景图像,并且使用了足够的填充来确保整个背景可见。

h2 {
  margin:0 0 2px 10px;
  padding: 6px 0 5px 13px;
  font:14px/165% italic Georgia, Arial, Helvetica, sans-serif;
  letter-spacing:0.2em;
  color:#FFF;
  background: #EAE5D8 url(img/blackhead.gif) left bottom no-repeat
}

现在,我们继续讨论侧边栏的<h2>。巧妙的部分是用后代选择器完成的。当<h2>元素在侧边栏中时,选择器#sidebar h2告诉浏览器应用这些规则。如果找到匹配,则使用不同的背景图像blackheadside.gif,并缩小页边距和font-size

#sidebar h2 {
  margin-top:3px;
  font-size:12px;
  background: #EAE5D8 url(img/blackheadside.gif) left bottom no-repeat;
}

注意

后代选择器对于避免不必要的类和 id 是必不可少的,否则它们可能会破坏 XHTML 文档。通过使用后代选择器,CSS 规则可以变得更加具体,并且后代选择器可以沿着树向下移动多远——可能是父代的子代的子代?

表格

从本质上讲,表是用于表格数据的,而且仅仅是表格数据。大多数负责任的设计师仍然使用表格。您可能无法避免它们,但重要的是只在必要时使用它们。

注意

表格数据不能单独由 CSS 布局来组织,或者如果你试图这样做,它将没有什么意义。许多设计人员想出了用纯 CSS 布局和定位来呈现复杂表格数据(如日历、时间表等)的方法。这很好,当然也算是一项成就,但是如果去掉样式表,一切都会分崩离析。该表的美妙之处在于它在语义上呈现信息,为 CSS 样式提供大量元素,并且在样式表不可用的情况下仍然非常有意义。

对于 Dirty beautiful Things disco graphy,一个表中包含了与每首歌曲相关的多行信息。如果一首歌曲分配了歌词、音频、视频、吉他标签或图像,则会在相应的单元格中放置一个小复选图像。标记相当简单,没有任何额外的 id 或类。

<table>
  <thead>
    <tr>
      <th>Title</th><th width="11%">Released</th>
      <th><abbr title="Lyrics">L</abbr></th>
      <th><abbr title="Audio">A</abbr></th>
      <th><abbr title="Video">V</abbr></th>
      <th><abbr title="Guitar">G</abbr></th>
      <th><abbr title="Images">I</abbr></th>
      <th>Comments</th>
    </tr>
  </thead>
    <tr>
      <td><a href="if_you_were_wondering/">Wondering</a></td>
      <td>08/05/06</td>
      <td><img src="img/discotick.gif" alt="Y" /></td>
      <td><img src="img/discotick.gif" alt="Y" /></td>
      <td><img src="img/discotick.gif" alt="Y" /></td>
      <td><img src="img/discotick.gif" alt="Y" /></td>
      <td>-</td>
      <td>26</td>
    </tr>
</table>

这就产生了图 1-10 中所示的基本表格。

The discography's tabular data as styled by the browser's default style sheet

图 1.10。由浏览器的默认样式表样式化的 discography 的表格数据

使用一些非常简单的 CSS 就彻底改变了这一点。由于表格下的页面背景,许多工作已经完成,但是进一步定义行和表格标题是有用的。

首先,我们控制表格本身,关闭默认边框(border:0),设置字体大小(font-size:11px),并确保表格将填充可用空间(width:100%)。

table {
  width:100%;
  margin: 10px 0 20px 0;
  border:0;
  font-size:11px;
}

然后,我们在每一行的顶部放置一个虚线边框,并添加特定的填充,消除对过时的表示标记的需要,如cellpaddingcellspacing

td, th {
  margin: 0px;
  border-top:1px dashed #999;
  padding: 3px 5px 3px 5px;
}

注意

值得注意的是,cellspacing没有可靠的 CSS 等价物,所以很多设计师仍然利用这个表象属性

这些非常简单的规则,以及桌子被放置在一个吸引人的背景上的事实,给了我们一个更加有趣的如图 1-11 所示的桌子。

Thanks to some very simple CSS, the discography table is radically transformed.

图 1.11。由于一些非常简单的 CSS,discography 表发生了根本性的变化。

定义列表

使用还是不使用定义列表?这是一个永恒的、无处不在的、越来越沉闷的问题。我们到底应该用它们做什么?就我个人而言,每当我需要比传统无序列表多一点的结构时,我都会使用它们,但不需要表的复杂性。

所有的定义列表都由两个主要部分组成:术语和描述。定义列表是使用三个基本元素构建的:容器(<dl>)、定义术语(<dt>)和定义描述(<dd>)。这个简单的结构适合我们对侧栏标题和游览日期的需求,其中日期充当定义术语,标题或地点是描述。结果是逻辑配对提供了所有必要的样式挂钩。

<h2>Forthcoming Gigs</h2>
<dl>
  <dt>25/11<dt>
  <dd><a href="liverpool_academy">Liverpool Academy...</a></dd>
  <dt>26/11</dt>
  <dd><a href="birmingham_academy">Birmingham Academy...</a></dd>
  <dt>27/11</dt>
  <dd><a href="nottingham_rock_city">Nottingham Rock City...</a></dd>
  <dt>28/11</dt>
  <dd><a href="leeds_university_refectory">Leeds University Refectory...</a></dd>
</dl>

注意

虽然我觉得这种配对是对定义列表的恰当使用,但是要注意屏幕阅读器会在每一项之前说出标签“术语”或“定义”

图 1-12 显示了浏览器中未样式化的结果。每个定义术语和定义描述由换行符和默认左边距分隔。

The definition list styled by the browser's default style sheet

图 1.12。由浏览器默认样式表设计的定义列表

现在,可以使用元素选择器来设计整个定义列表的样式。以选择器dldtdd为例,可以应用非常相似的样式将整个部分组合在一起。我们发现没有必要修改定义列表元素本身,尽管如果我们愿意的话,我们可以为dl选择器添加声明。我们的第一步是让术语定义变得更难。主要的工作是将定义术语浮动到左边,这将允许定义描述被重新定位到它的右边并内嵌。

dt {
  float:left;
  padding:2px 0 7px 0;
  line-height:130%;
  font-weight:bold;
}

接下来,定义描述元素被样式化。非常简单,关键任务是移除默认边距,该边距将它从包含的<dl>元素的左边缘推开。

dd {
  margin:0;
  padding:2px 0 7px 0;
  line-height:130%;
}

这给我们带来了一个完整的、巨大变化的定义列表。请注意,它足够灵活,可以扩展和适应我们放置它的任何容器,这使它成为侧边栏导航的理想组件。所有这一切的美妙之处在于,在(X)html 中不需要额外的标记,CSS 会处理好一切。最终结果见图 1-13 。

CSS to the rescue once more. The definition list is clearer and aligned much better thanks to a few CSS rules.

图 1.13。CSS 再次出手相救。多亏了一些 CSS 规则,定义列表更加清晰,也更加一致。

这样,由于样式表的强大功能,内容区域的关键组件都被控制住了。内容本身保持纯净和清白,网页设计师可以睡得很香。

结论

当然,构建肮脏美好事物网站并不像本章所说的那么简单,还有更多问题(包括代码和现实世界相关的)有时会让生活变得非常困难。这个故事的重要寓意是,由于网络标准,尽管用户数量巨大,该网站使用的带宽相对较少(我没有将视频下载计入该带宽),尽管装饰复杂且包罗万象,但它仍然可以在移动和打印设备上访问。

我很乐意分享更多我在这次构建中的经历,但是没有空间让其他人讲述他们的故事,所以我邀请你查看源代码(注意,自从我管理这个站点以来,代码可能已经改变)并在这个站点中挖掘。没有更好的方法来弄清楚事物是如何工作的,非常欢迎您来探索。

Conclusion

二、使用 CSS、Flash 和 JavaScript 驯服野生 CMS

丹·鲁宾

www.webgraph.com

丹·鲁宾(Dan Rubin)整天将音乐、设计和字体设计融入南佛罗里达的阳光海滩。从声乐指导和表演到平面设计(几乎是字面意义上的)以及这两者之间的一切,丹尽可能地将他的才华尽可能地分散开来,同时仍然留出时间来喝一杯好茶和偶尔小睡一会儿。

他对所有创造性和艺术性事物的热情也不仅仅是自私的努力。你不需要逗留太久,就会发现他对无伴奏爵士乐和理发店和声(他对roundersquartet.com的设计只是这两个世界碰撞的一个例子)、界面设计、可用性、网络标准、排版和一般平面设计进行了教育。除了对 Blogger、CSS Zen Garden、Yahoo!小企业和微软的门户网站,Dan 是《层叠样式表:将内容与表示分离》一书的特约作者,也是《CSS Web 开发入门》一书的技术评论员,同时也是《CSS 技术入门》一书的合著者他在自己的博客superfluousbanter.org上写关于网络标准、设计和生活的文章,并在livefromthe101.com上发布播客。他的专业作品可以在他的公司网站webgraph.com上找到。

Taming a Wild CMS with CSS, Flash, and JavaScript Taming a Wild CMS with CSS, Flash, and JavaScript

设置场景

你的客户要求你重新设计公司的网站,但有一个主要限制:你不能定制用于输出内容的标记,因为它是由一个内容管理系统生成的。“等等!”你会说,“CMS 不是应该把内容和输出格式分开吗?”不幸的是,似乎在大多数情况下,特别是对于企业级 CMS,不管是出于无知还是精心的计划,定义 CMS 用来呈现内容的标记的模板是设计者的禁区。"但是我怎么可能在如此陈旧的限制下设计出吸引人的东西呢?"虽然说服您的客户允许定制输出模板是最好的途径,但事实是有时这是不可能的,您只能使用您所给的。正是在这些艰难的时刻,网络标准,特别是 CSS,以及它们的得力助手 JavaScript 和 Flash,来拯救你了。

这是 Geffen/Universal Media 向我提出的挑战,当时该公司要求我重新设计疯狂流行乐队生命之屋乐队的宣传网站。我将向你展示我如何使用 CSS,一些聪明的设计,和一些很酷的工具和技术来击败 CMS 输出到提交。我还将向您展示如何在您自己的项目中使用这些相同的实际方法。

在我们开始我们的旅程之前,让我们比较一下原始网站和我的重新设计(见图 2-1 )。你可以在原著中看到一些“模板心态”的设计公式在起作用。

On the left, the original design, including blocks of template content in all three columns

图 2.1。左边是原始设计,包括所有三列中的模板内容块

就市场部而言,一旦我们提出一个可以接受的设计,我们的工作就完成了。像素已经画在屏幕上了,就没别的事了吧?啊,但是我们知道的更多,不是吗?

当然,创建网站模板不仅仅是设计。不知何故,我们必须从概念到草图到视觉合成到标记到风格。然后,经过一些浏览器测试,我们完成了一个成品。这个过程本身通常就足够了。在这种情况下,我还需要考虑 CMS 规定的特定标记要求。我将马上回顾每一个步骤,但首先,对于门外汉来说,这是一个 CMS 速成班。如果您已经熟悉 CMS 的基本功能,请随意将这本书递给附近需要这方面教育的同事,并在他阅读接下来的几段并看着漂亮的图片时,自己喝一杯茶。

CMS 速成班

一般来说,CMS 就像他们的名字所暗示的那样:帮助管理内容。更广义地说,它们允许内容制作者在数据库中存储和组织他们网站的内容。当访问者请求站点中的特定“页面”时,将从 CMS 中检索适当的内容并显示在用户的浏览器中。

通常,CMS 是一个安全的 web 应用程序,由站点管理员、内容创建者、编辑者或任何负责发布或编辑站点内容的人使用。它可以处理文本、标记、链接、图像、音频、视频几乎任何类型的可以存储在数据库中的内容。

通常,一个简单的 CMS 可能会与你的布局模板交互,如图 2-2 所示。

A basic CMS in the big picture. In this example, one template defines the layout and pulls content from the CMS.

图 2.2。大局中的一个基础 CMS。在本例中,一个模板定义了布局并从 CMS 中提取内容。

一些更复杂的 CMS 在存储的内容和显示给用户的内容之间增加了额外的层,如图 2-3 所示。

This CMS adds an extra layer of templates to define blocks of content separately from page layouts.

图 2.3。这个 CMS 添加了一个额外的模板层来定义与页面布局分开的内容块。

本章讨论如何使用多层模板解决第二类系统产生的问题。这些层通常结合起来创建每个页面样式的基本框架。设计者通常可以访问布局模板。内容模板包含各种类型内容的大量标记,通常是设计者的禁区。更重要的是,由于对内容模板的访问受限或不灵活的输出要求,这些内容块通常包含不受您控制的标记。

CMS 挑战

不需要太多的网页浏览就能在各种网站上找到内容的通用视觉格式。这种通用模式通常由这些网站背后的特定 CMS 的内容模板中的限制规定。你可以在受欢迎的博客 CMSs 管理的网站、运行昂贵的商业软件包的网站,甚至是定制的系统上看到这些共同的元素。

Geffen/Universal Media 用来管理其艺术家网站的定制 CMS 就是这种情况。为了简化内容格式的大规模更新,所有网站都使用相同的数据类别,如新闻、媒体、照片、事件等。在此 CMS 上运行的网站共享一组内容模板。虽然这使得对给定内容块的调整更容易实现,但这种方法导致许多网站具有相似的外观。这在很大程度上是由于设计者认为内容需要看起来一样,因为标记不能在一个站点一个站点的基础上定制。

对于我的生命之屋乐队网站重新设计项目,Geffen/Universal Media 没有提出任何具体目标,只是希望设计能比现有网站更好地反映乐队的形象和当前的宣传摄影。从设计的角度来看,这就像一张白纸,这基本上是我得到的指示,但有一个很大的限制:我制作的任何东西都必须与现有的 CMS 内容模板一起工作。

这不是我为该公司工作的第一个艺术家网站,所以我已经熟悉了 CMS 模板的集中结构所施加的大多数限制。这意味着我已经确切地知道设计必须适应什么类别和类型的内容,以及在我面前有什么限制。

像我早期的项目一样,这次重新设计有一个紧张的截止日期和预算,这以前导致了一个快速和肮脏的设计过程:采用一组基本的内容和布局模板一个带有页眉和页脚的标准两列布局,并在不超出预算的情况下,将它们的外观设计得尽可能不像模板。如果我没有变得如此讨厌这种方法对我的设计的限制作用,生命之屋乐队网站的重新设计也会是一样的。

因此,面对另一个无聊的设计项目,我提出了一个实验:让我看看在不改变预算或时间表的情况下,我能在多大程度上调整内容和布局,以打破基本的模板模式。收到客户的许可后,是时候进入正题,开始快速设计一些东西了。

一毛钱的设计

我的主要目标是制作一个不像默认 CMS 布局模板的布局。当然,由于它必须支持的内容类型与所有其他艺术家网站相同,新布局需要与默认布局有一些共同之处。我认为结合这些需求的最简单的方法是使用相同的元素,但是定位要稍微不同,这样,对于不经意的观察者来说,这个网站看起来就不会和其他的一样。这也为一个必须在几周内完成的项目提供了一个很好的起点。

视觉元素

我已经从唱片公司的市场部收到了乐队的宣传资料。结合所需的内容和导航,这些给了我以下的视觉元素到设计中:

  • 该乐队的标志艺术品

  • 来自乐队最新照片拍摄的高分辨率照片

  • 当前专辑封面

  • 十个类别的主要导航

  • 各种内容块(事件、视频、新闻、邮件列表注册等)

我还决定在主页上突出显示新闻部分的一篇专题文章。因为这是 CMS 不支持的,这就产生了另一个挑战。因此,有了这张清单、一支铅笔、一张白纸和一张已经在我脑海中形成的图片,我开始快速勾画一些缩略图,直到我找到一个“感觉正确的”(见图 2-4 )。

Eenie, meenie, miney, mo!

图 2.4。埃涅!米涅!米涅!米奈!莫!

注意

我强烈地感觉到设计过程必须是有机的。仅仅因为我们是为一个技术媒介而设计,并不意味着我们的过程也必须是冷酷的和经过计算的。我喜欢使用缩略图草图,因为这是一种很好的方式,可以在纸上表达我的想法,而不用担心太多的细节。我几乎每一个设计都是从花几分钟画出小布局开始的,这是我所知道的最好也是最快的方法,几乎可以立即比较多个布局创意。你可以在www.sinelogic.com的“预算设计”中找到更多这样的设计捷径。

下一步是花一些时间在 Photoshop 中把草图变成像素。配色方案借鉴了乐队最新专辑封面上的照片,加上一些灰色调。经过一段时间激烈的像素推进,我完成了图 2-5 所示的合成图。

The initial Photoshop composite

图 2.5。最初的 Photoshop 合成

在这个阶段,一些有趣的视觉元素融入了设计:

  • “预告”文章的透明背景(显示下面的照片)

  • 挑逗性的标题与乐队的标志字体相同(富兰克林哥特式压缩)

  • 页脚列出了最近的新闻标题(这看起来很容易复制,只是 CMS 不支持)

  • 整个布局中的垂直文本标题(也以富兰克林哥特式压缩字体呈现)

到目前为止,您可能已经迫不及待地想要了解“技巧和诀窍”这一部分了,所以如果您对标记不感兴趣,请继续阅读。但是在开始样式化之前,我们真的需要打下 XHTML 的基础。

标记只是一个外壳

由于 CMS 控制着大部分内容块周围的标记,最简单的方法就是创建一个 shell 布局,用<div>来包含每个数据模块。该设计基本上是两列加一个页脚,徽标和导航位于左列。折腾了几个比特的样本内容,我得到了这个:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html  xml:lang="en" lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <meta http-equiv="Content-Language" content="en-us" />
  <title>Lifehouse [homepage]</title>
  <link rel="stylesheet" type="text/css" href="c/styles.css" media="all" />
</head>
<body class="homepage">
  <div id="wrapper">
    <div id="content">

      <h1 id="logo">
        <a href="/" title="link to the homepage">Lifehouse</a>
      </h1>

      <div id="content-primary">

        <div id="sidebar-tab"><!-- for presentation only --></div>

        <div id="teaser">
          <h2>latest news</h2>
          <a href="#">
            <img src="p/thumbnail_teaser.jpg" width="122" height="122" alt="" class="fullsize" />
          </a>
          <h3><a href="#">Article heading</a></h3>
          <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,
            sed do eiusmod tempor incididunt ut labore et dolore magna
            aliqua. Ut enim ad minim veniam, quis nostrud exercitation
            ullamco laboris nisi ut...</p>
          <p class="entry-footer">Published on 5/14/2006 |
            <a href="#">Link</a> |
            <a href="#">Comments (0)</a>
          </p>
          <a class="readmore" href="#">read more...</a>
        </div><!-- #teaser -->
      </div><!-- #content-primary -->

      <div id="nav">
        <ul>
          <li id="nav-home"><a href="#">Home</a></li>
          <li id="nav-news"><a href="#">News</a></li>
          <li id="nav-dates"><a href="#">Dates</a></li>
          <li id="nav-music"><a href="#">Music</a></li>
<li id="nav-videos"><a href="#">Videos</a></li>
          <li id="nav-photos"><a href="#">Photos</a></li>
          <li id="nav-extras"><a href="#">Extras</a></li>
          <li id="nav-links"><a href="#">Links</a></li>
          <li id="nav-forum"><a href="#">Forum</a></li>
          <li id="nav-store"><a href="#">Store</a></li>
        </ul>
      </div><!-- #nav -->

    </div><!-- #content -->

    <div id="sidebar-wrapper">
      <div id="sidebar">

        <div class="module" id="mod-events">
          <h3>events</h3>
        </div><!-- .module -->

        <div class="module" id="mod-videos">
          <h3>videos</h3>
        </div><!-- .module -->

        <div class="module module-alt" id="mod-members">
          <h3>members</h3>
        </div><!-- .module -->

        <div class="module" id="mod-online">
          <h3>online</h3>
        </div><!-- .module -->

      </div><!-- #sidebar -->
    </div><!-- #sidebar-wrapper -->

    <div id="footer-wrapper">
      <div id="footer" class="clearfix">
        <div id="morenews">
          <h2>more news</h2>
          <ul>
            <li><a href="#"><strong>5/14/2006</strong> Article heading</a></li>
            <li><a href="#"><strong>5/14/2006</strong> Article heading</a></li>
            <li><a href="#"><strong>5/14/2006</strong> Article heading</a></li>
            <li><a href="#"><strong>5/14/2006</strong> Article heading</a></li>
            <li><a href="#"><strong>5/14/2006</strong> Article heading</a></li>
            <li><a href="#"><strong>5/14/2006</strong> Article heading</a></li>
            <li><a href="#"><strong>5/14/2006</strong> Article heading</a></li>
            <li><a href="#"><strong>5/14/2006</strong> Article heading</a></li>
          </ul>
          <a class="more" href="#">more...</a>
        </div>

        <div id="extras">
          <h2>extras</h2>
<a href="#" class="thumbnail"><img src="p/thumbnail
            wallpaper.jpg" width="150" height="112" alt="" /></a>
          <h3>Lifehouse wallpaper - 800x600</h3>
          <p><a href="#"> Download</a></p>
          <p>5/14/2006 | <a href="#">Link</a> | <a href="#"> Comments (2)</a></p>
          <div id="external-links">
            <a id="logo-geffen" href="http://geffen.com/">Geffen</a>
            <a id="privacypolicy" href="#">Privacy Policy</a>

            <a id="myspace" href="#">visit our <span>myspace</span></a>
          </div>
        </div>
      </div><!-- #footer -->
    </div><!-- #footer-wrapper -->

  </div><!-- #wrapper -->

</body>
</html>

当在浏览器中查看时,它以原始的、无样式的形式呈现得相当好,如图 2-6 所示。

无样式页面中内容的顺序很重要,尽管不是这个站点的首要任务,因为目标受众在普通电脑上使用现代浏览器。然而,所有的内容至少在没有样式的情况下被适当地格式化了,所以网站在基本层面上是可访问的,这比最初的设计要好得多。

The naked lunch ...er, content

图 2.6。裸体午餐...呃,内容

注意

有没有发现自己在处理生成的标记时迷失在一片混乱中?如果您坚持使用一个会生成本章所讨论的那么多嵌套 div 的 CMS。通过用相应的开始标记的 ID 或类来注释每个 div 的结束标记,可以使您的标记更容易阅读(对于您和其他人)。看一看示例标记。看看与没有注释的标签相比,将有注释的 div 的结束标签配对起来有多容易?

注意侧边栏中的“模块”(方便地分配了类.module)是空的。这些只是容器,实际的 CMS 生成的内容将很快放入其中,所以现在,我们不去管它们。重要的是它们是存在的,由于它们唯一的 id,它们可以被单独定位,并且它们在文档流中的顺序是可以互换的。

虽然这些标记中的大部分应该是不言自明的,但是我将在下一节讨论少数的.clearfix类。稍后,在“分析和润色”部分,我将回顾我用来为主导航设置无序列表样式的技术(导航不是由 CMS 生成的)。

注意

我说过 CMS 内容模板不包括列表选项,那么页脚的<ul>是怎么回事?由于项目的时间限制。我能够说服当权者给内容模板添加一个列表选项。这给了我设计列表样式所需的适当挂钩,并为该样式使用更合适的标记。清理标记,然后施展你的 CSS 魔法,这比处理混乱要好得多。拥挤的加价。也就是说。该外观也可能是使用原始的非列表标记重新创建的。它只是需要更多的 CSS 技巧来完成类似的结果,这会不必要地使项目复杂化并延长时间表。

布局和风格

现在我们进入了重要的内容,所以你可能想让你的家人知道,除了在下一节给你端茶倒水之外,他们在相当长的一段时间内不会看到或听到你的消息。毕竟,你确实需要大脑补充能量。实际上,我们不会对布局本身进行深入的讨论,它并没有那么时髦,但是我们回顾创建它所需的基本风格。

注意

我发现在一个规则块中组织 CSS 属性很有帮助,特别是在浏览器测试中检查/调整样式表时,或者在启动后必须进行调整时。以下是我更喜欢的顺序:

  • 显示方法(显示:或浮动:)

  • 背景设置

  • 定位方法(位置:)

  • 位置(x,y)

  • 宽度/高度

  • 边距/填充

  • 颜色

  • 文本设置(字体/行高/对齐)

  • 边界

这是又一个简单的节省时间和烦恼的方法,应该会让你的生活变得轻松一点。任何给你的标记或样式增加一些结构和顺序的东西都会给你带来回报。

定位元件

虽然我们并不试图用整体布局来完成任何开创性的工作,但在我们进入实质之前,有必要回顾一下每个主要元素是如何定位的。首先,清除浮动:

.clearfix:after
{content:".";
display:block;
height:0;
clear:both;
visibility:hidden;
}

.clearfix {display:inline-block;}
/* Hides from IE-mac \*/
.clearfix {display:block;}
/* End hide from IE-mac */"

body {
background:#111 url(../i/bg_body.gif) repeat-x;
margin:0;padding:0;
font-family:'lucida grande', tahoma, sans-serif;
font-size:small;
}

#wrapper {
width:800px;
}

#content被设置为float:left,使其包含它所包含的两个浮点(#content-primary#sidebar-wrapper):

#content {
float:left;
}

#content-primary也被设置为position:relative,允许#sidebar-tab#teaser被绝对定位,但在其包含元素的范围内。请参阅道格·鲍曼的《制造绝对相对》(http://stopdesign.com/articles/absolute/)来很好地概述这一技术。

The layout and styles

#content-primary {
float:left;
background:url(../p/homepage_photo.jpg) no-repeat;
position:relative;
height:549px;
width:520px;
padding:0;
color:#fff;
}

h1#logo {
position:absolute;
z-index:100;
left:29px;
top:39px;
margin:0;padding:0;
}
h1#logo a {
display:block;
background:url(../i/logo_lifehouse.gif) no-repeat;
width:38px;
height:175px;
text-indent:-5000px;
}

#sidebar-tab {
background:url(../i/bg_sidebartab_events.png) no-repeat;
position:absolute;
right:0;
top:0;
width:20px;
height:194px;
}

#teaser {
background:url(../i/bg_teaser.png) no-repeat;
position:absolute;
left:0;
bottom:0;
width:507px;
padding:20px 0 30px;
color:#EFB32F;
font-family:'lucida grande', verdana;
line-height:1.3;
}

#nav被清除,以确保其落在#content-primary之下。类似地,.module被清除以允许每个模块中的任何内容被浮动,因为每个后续的.module将清除任何这样的浮动。

#nav {
background:url(../i/bg_nav.gif) repeat-x;
width:520px;
height:53px;
margin-top:0;
border-top:3px solid #111;
clear:both;
}

#sidebar-wrapper {
float:right;
background:#1C1C1C url(../i/bg_sidebar_wrapper.gif) no-repeat left bottom;
width:277px;
margin:0 0 3px;
padding:0 0 10px;
}
#sidebar .module {
color:#A07029;
padding:15px 15px 15px 0;
border-top:1px solid #111;
clear:both;
}

#footer-wrapper {
background:#1B1B1B url(../i/bg_footer_wrapper.gif) repeat-x;
padding-right:10px;
clear:both;
border-top:1px solid #333;
}
#footer {
background:#262626 url(../i/bg_footer.gif) repeat-x;
padding:20px 0 20px;
}

这没有什么奇怪的。它是容器(或包装器)、一些列的浮动和一些绝对定位的混合物。因为这一章的目的不是教你 CSS 的基本原理,我在这里就不赘述了。如果你觉得自己在任何基础知识上落后了,我推荐阅读西蒙·科利森的初学 CSS Web 开发(出版社,ISBN: 1-59059-689-7)。

注意

我喜欢根据约定俗成的 type_id_label 来给图片命名,这样更容易记住每张图片的用途(比如logo_footer_geffen.gif)。此外,文件命名约定使第三方或您的客户更容易确定与您的设计和代码相关的“是什么和为什么”。虽然样式指南也可以完成这项任务,但项目的预算或时间表通常不允许创建样式指南,或者即使存在样式指南,也可能无法供将来进行更改的人使用。

瞄准 CSS 选择器

我之前展示的基本 shell 标记中包含的生成标记的一个大问题是,在决定使用哪种标记时,我没有发言权。在描述中包含嵌套段落的定义列表可能是最合适的,但我可能会被迫处理一些嵌套的包含到处都是<span><div>。您可以通过查看现场的源代码来了解这一点。啊。再喝一杯(浓茶)来帮助你克服这个心理印象。

谢天谢地,尽管这听起来很糟糕,但有一种相对简单的方法可以挖出来。CSS 选择器有许多形状和大小。许多设计师习惯于只做基础工作:

  • ID s:在 CSS 中作为#footer出现,在(X)HTML 中作为元素上的属性值出现,比如<div id="footer">,其中div是元素,id是属性,footer是值。

  • :在 CSS 中作为.readmore出现,在(X)HTML 中作为元素上的属性值出现,比如<p class="readmore">,其中p是元素,class是属性,readmore是值。

  • 元素选择器:目标任意(X)个 HTML 元素。例子有ulpdivbodytable,甚至html

然而,除了这些基本的选择器之外,我们还有更多的选择,这就是外壳标记发挥作用的地方。

通过查看 CMS 生成的标记,我们可以创建后代选择器,专门针对我们想要关注的内容,而不去管其他内容。后代选择器允许我们对嵌套在标记的特定层次结构中的元素进行样式化。例如,选择器#sidebar #mod-media img.fullsize的目标是包含在 ID 为mod-media的元素中的fullsize类的任何img,该元素也包含在 ID 为sidebar的元素中,如果你问我的话,这是非常具体的。

还记得侧边栏模块上的 id 吗?他们的目的现在将被阐明。例如,查看侧栏中的视频模块的标记和内容块,在本例中做了一些清理(但只是一点点),由 CMS 生成:

<h2><a href="/videos/default.aspx"><span>Videos</span></a></h2>
<div class="item summary stream">
  <img srcimg/video.jpg" alt="Blind" class="fullsize">
  <h4>Blind</h4>
  <p class="url">Windows: <a href=
    "http://music.yahoo.com/video/24649242/?">300K</a><br /></p>
  <p><span class="subtype">[Videos] </span>"Blind" Music Video</p>
  <p class="byline"><span class="date">10/20/2005</span>
    <span class="permalink"> |
    <a href=" /videos/default.aspx?mid=2333">Permalink</a>
      </span><span class="comment-icon"> |
    <img srcimg/comment_icon.gif" alt="Comment" /></span>
    <a href="/forum/topic.aspx/cid/133/tid/70679">
      Comments (197)</a></p>
  <div class="clear"> </div>
</div>

不是你见过的最差的 ?? 价格,对吗?我喜欢的类太多了,注释图标可以用 CSS 显示,而不是使用内嵌图像(那<br />在那里做什么?).但同样,围绕这些内容的标记意味着在标签的 CMS 管理的每个艺术家网站上使用*,所以额外的挂钩在这种情况下是有意义的。有更好的方法来提供一些钩子,但是那是一个单独的讨论。*

这种标记完全不受我的控制,但我仍然需要对它进行样式化。并且很可能给生成的<div><img>标签上的类属性分配了通用的类名,我的钩子(类itemsummarystream)在整个站点的许多其他地方使用。这意味着我需要一些方法来定位这个部分中的类,以便处理视频模块的任何特定需求。因为 CMS 的内容模板生成的标记中没有提供这些挂钩,所以我在布局模板中创建它们,将它们包装在调用生成内容的代码中:

<div class="module" id="mod-media">
  . . .
</div>

这个<div>包装了标记并提供了两个重要的工具:

  • class="module"将被分配给每个包装器,比如这个,它允许你在每个块之间共享一些基本的格式(边距、边框等等)。

  • id="mod-media"允许您单独定位此块,并指定适合显示此内容的特定样式。

所以,假设对于侧边栏中的大多数模块,我想将分配给class="fullsize"的任何<img>标记设置为在模块中向右浮动,在左侧和底部有 5 个像素的边距,没有边框。有了新的挂钩,通用样式现在应该是这样的:

#sidebar .module img.fullsize {
float:right;
margin:0 0 5px 5px;
border:none;
}

这个选择器使用我分配给我的包装器的类<div>#sidebar,所以如果我决定在布局中的任何地方使用module类,这个规则将不适用。

这样,我现在可以设置视频模块的样式,使图像向左浮动,而不是向右浮动,并相应地调整边距:

#sidebar #mod-media img.fullsize {
float:left;
margin:0 5px 5px 0;
}

通过将选择器中的类(.module)替换为 ID ( #mod-media),我指示浏览器首先应用通用样式,然后覆盖浮动和边距设置。

注意

id 比类具有更高的特异性。关于特异性如何计算的详细解释,请参见http://molly.com/2005/10/06/css2-and-css21-specificityclarified/;更轻松的概述,请参见http://stuffandnonsense.co.uk/archives/css_specificity_wars.html

同样的方法可以让你摆脱 CMS 生成的标记为你挖的几乎所有的洞。虽然我们没有人真的想使用像body#events #content .item .module .summary #membership p.permalink span {}这样难看的选择器,但是如果你陷入困境,需要完成工作,将选择器与一两个包装器<div>组合并分层会让你的生活压力小很多。

排版

我是一个字体设计迷,字体通常在我的设计中占据显著位置。HTML 文本很难控制。即使使用 CSS,字体选择也仅限于安装在用户操作系统上的字体,而且排版控制实际上是不可能的。然而,我的设计使用了乐队选择的字体,富兰克林哥特式压缩。我不想妨碍网站的基本可访问性。我并不想在这方面追求完美,但同时,使用糟糕的标记将人们完全拒之门外也是不负责任的。但不知何故,我需要让那种类型显示出来。为固定标题输入 CSS 图像替换,为需要定期更改的文本输入 sIFR,例如由 CMS 生成的文章标题。

让我们从垂直的文本标题开始。它们是需要特殊处理的最明显的候选者,因为仅仅使用 HTML 文本是没有办法模仿它们的。

制造竖排文字的假象

应该垂直的标题都是静态的。由于它们不需要定期更新,我可以使用 Photoshop 中渲染的图像。竖排文字的效果不容易用其他方式复制。我可以用 Flash 做到这一点,但用这种方法更容易*,因为 sIFR 方法(接下来讨论)不支持旋转文本,Flash 项目可能更难定位。我可以使用 CSS background-image属性将每个图像分配给一个容器<div>,但是在 HTML 文件中没有实际的标题,如果标记是可访问的,即使是基本的,这也不是理想的情况。*

好消息是,让一个 HTML 标题(<h1><h2>等等)完全按照我想要的那样做也很容易,出于某种显而易见的原因,这种方法被称为图像替换*。有多少种处理图像替换的方法,就有多少种带有奇怪 CSS 错误的 Internet Explorer 版本,但我更喜欢迈克·伦德尔设计的一种方法,称为 Phark 方法(以他的个人网站http://phark.net命名)。让我们以侧边栏标题(包装在模块<div>中)为例:

<div class="module" id="mod-videos">
  <h3>videos</h3>
</div><!-- .module -->

注意

关于图像替换技术的更多内容,Dave Shea 为你收集了一个很好的对比来做书签和参考:http://mezzoblue.com/tests/revised-image-replacement/

如果没有任何特定的样式,这个标题将会像您预期的那样显示。但是我们的想法是隐藏默认的文本输出,并用在图形编辑器中创建的文本图像替换它,下面的 CSS 规则就是我所需要的:

#sidebar .module h3 {
background:url(i/header_module_events.gif) no-repeat;
width:18px;
height:58px;
margin:0;
text-indent:-5000px;
}

该规则处理以下内容:

  • 设置背景图像并指示浏览器不要平铺图像。

  • 定义尺寸(此处设置为等于背景图像的宽度和高度)。

  • 扼杀利润。替换标题时,最好将页边距设为零,然后根据需要调整位置。

  • 最后,巧妙的部分是:将文本在标题位置的左边缩进 5000 像素。这很重要,因为否则标题的文本仍然会显示在渲染的背景图像之上。

图 2-7, after the background image is applied (middle), and after setting text-indent:-5000px; (right)") 显示了应用 CSS 规则之前、期间和之后的标题。

The heading in its default state (left), after the background image is applied (middle), and after setting text-indent:-5000px; (right)

图 2.7。默认状态下的标题(左),应用背景图像后的标题(中),以及设置文本缩进后的标题:-5000 px;(右)

这样就解决了垂直文本的问题,乍一看,这似乎是两种替换情况中更具挑战性的一种。然而,现实情况是,第二种情况——对必须保持可编辑的文本使用特定的字体——实际上更具挑战性,您将在下面看到。

sIFR 我的木材

当您处理 CMS 生成的内容时,每个页面上的大部分内容都在不断变化。在这种特殊情况下,假设乐队成员愿意或能够为他们通过 CMS 发布到网站的每个新闻项目创建自定义的图形文本标题是不公平的。然而,作为一名设计师,我更希望主页上的主要文章标题采用与乐队标志相同的字体。幸运的是,在很大程度上由于一些天才程序员的非凡努力,sIFR 拯救了我。

sIFR 代表可伸缩的因曼闪存替换(因曼,就像肖恩·因曼,他构思了最初的 DOM 替换方法,启发了 sIFR)。用 Mike Davidson 的话来说,sIFR 是“一种在不牺牲可访问性、搜索引擎友好性或标记语义的情况下将丰富的版式插入网页的方法”,Mike Davidson 是 sIFR 的创始人之一,也是网页版式质量的全面倡导者唷。更简单地说,sIFR 是一种在现代可视化浏览器中使用特定字体来替换 HTML 文本的方法,结合了 Flash 和 JavaScript。它不妨碍可访问性,没有 Flash(或关闭了 JavaScript)的访问者将看到普通的 HTML 文本,应用了 CSS。哦,我有没有提到它是免费的

要利用 sIFR 开发商的无私慷慨,您必须首先准备好以下物品:

  • Macromedia(现在是 Adobe) Flash 版本 6 或更新版本(完整版本,不是插件)

  • 您想要使用 sIFR 渲染的字体

  • 一些空闲时间

一旦你满足了这些要求,将 sIFR 融入任何项目的过程都相当简单:

  1. www.mikeindustries.com/sifr/下载最新版本(撰写本文时为 2.0.2)。

  2. http://wiki.novemberborn.net/sifr/阅读文档。

好的,所以没有那么简单,但是所有的步骤都在文档中有概述。如果你按照说明做,它会顺利地工作。尽管如此,我还是会给你一个简单的概述,以及一个例子。

选择字体后,第一步是导出 Flash ( .swf)文件。sIFR 的创建者友好地将 Flash 文档(.fla)与其余的文件放在一起,所以您只需在 Flash 中打开该文件,双击该文件中心的文本框,并指定字体。导出文件(在这个例子中,文件被命名为franklingothiccondensed.swf)。我们练习的 Flash 部分到此结束。

sIFR 下载还包括两个 CSS 样式表一个用于屏幕,一个用于打印和一个 JavaScript 文件(这就是神奇之处)。您可以将这些样式复制并粘贴到您自己的屏幕上,并打印样式表,正如 sIFR 文档中所建议的那样,或者在您的文档的<head>中链接到它们以及 JavaScript 文件:

<link rel="stylesheet" type="text/css" href="sIFR/sIFR-screen.css" media="screen" />
<link rel="stylesheet" type="text/css" href="sIFR/sIFR-print.css" media="print" />
<script src="sIFR/sifr.js" type="text/javascript"></script>

现在你必须从你的 HTML 文件中调用 sIFR,并告诉脚本替换什么。您也可以将这些“替换语句”放在 JavaScript 文件本身中;有关详细信息,请参见 sIFR 文档。

<script type="text/javascript">
if(typeof sIFR == "function"){
  sIFR.replaceElement(named({sSelector:"#teaser h3",
    sFlashSrc:"/sIFR/franklingothiccondensed.swf",sColor:"#EFB32F",
      sLinkColor:"#EFB32F", sFlashVars:"offsetLeft=0&offsetTop=0",
      sWmode:"transparent"}));
};
</script>

第一个参数定义了 CSS 选择器,因此脚本知道要替换哪个文本。下一个参数告诉脚本在哪里可以找到字体的 Flash 文件。接下来是文本的颜色(一个用于没有链接的标题,另一个用于有链接的标题,在本例中颜色相同),替换文本的位置,以及使 Flash 文本背景透明的设置。注意,对于sFlashSrc参数,我为.swf文件使用了一个相对于根目录的 URL。您可能需要尝试使用根目录相对或绝对 URL 来使事情正常运行。对于这个项目,我在本地开发时使用了一个相对 URL,但是当它上传到服务器时就停止了工作,需要对 URL 进行调整。

在我们进入展示和讲述阶段之前,让我们先快速回顾一下我们在这次替换中使用的标记,这些标记来自现场:

<h3><a href="/news/default.aspx/nid/8514" target="_self">
  Norfolk Virginia</a></h3>

这是 CMS 生成的实际代码行,它嵌套在#teaser <div>.中。如果你对周围的其他标记感兴趣,只需在实时网站的主页上查看源代码,但这并不影响 sIFR 的使用。

只剩下一个步骤,这就是被 sIFR 的创作者称为调音的过程。在这里,您可以使用font-sizeletter-spacingline-heightheight CSS 属性指定“诱饵”样式,sIFR 脚本使用这些样式来确定最终呈现文本的大小和间距。这是可行的,但是你应该做好反复试验的准备,甚至可能偶尔咒骂你选择的文本编辑器,直到你替换的文本看起来大小和间距都合适。我们示例中调整后的 CSS 如下所示:

.sIFR-hasFlash #teaser h3 {
visibility:hidden;
letter-spacing:0;
font-size:24px;
line-height:22px;
}

最后,我们有了最终结果,如图 2-8 所示。

On the left, the regular HTML heading (also what users without Flash will see), and on the right, the beautiful sIFRized version

图 2.8。左边是普通的 HTML 标题(也是没有 Flash 的用户会看到的),右边是漂亮的 sIFRized 版本

注意

图像替换和 sIFR 有他们的位置。它们为我们提供了改进设计排版的方法。而不牺牲可访问性。但是你必须谨慎使用它们。尤其是图像替换。在大型网站上,为每个标题创建一个自定义图像可能不太实际,尤其是当这些标题经常变化的时候。

吐槽擦亮

如果我不特别提及,还有一些额外的细节可能会被忽略。例如,布局左上角的徽标可以很容易地包含在主乐队照片中,从而减少制作页面所需的图像数量。然而,将徽标制作成一个单独的图像文件允许我将其设置为<h1>标签的背景,并使标签(以及徽标)链接到主页:

下面是 XHTML:

<h1 id="logo">
  <a href="/" title="link to the homepage">Lifehouse</a>
</h1>

这是 CSS:

h1#logo {
position:absolute;
z-index:100;
left:29px;
top:39px;
margin:0;padding:0;
}
h1#logo a {
display:block;
background:url(../i/logo_lifehouse.gif) no-repeat;
width:38px;
height:175px;
text-indent:-5000px;
}

瞧,我现在有了一个可点击的标志。

用火狐?您可能已经注意到,这种图像替换技术(前面提到的 Mike Rundle 的 Phark 方法)会导致单击时浏览器的虚线链接边框一直延伸到浏览器窗口的左边缘,这不是很吸引人。幸运的是,这可以通过将a {outline:none;}放到样式表中很容易地解决。图 2-9 and after (left) using {outline:none;} in the style sheet, when viewed in Firefox") 展示了前后效果。

另一项值得注意的是主导航(<div id="nav">...</div>),它被标记为一个简单的无序列表。幸运的是,导航不是由 CMS 生成的,但可以手动标记,并包含在网站所有页面的服务器端,因为正如我前面提到的,CMS 输出模板不包含列表。导航条使用一种被称为导航矩阵(Navigation Matrix Reloaded,http://superfluousbanter.org/archives/2004/05/navigation-matrix/)的技术的简化变体来创建基于图像的导航和悬停效果。整个导航仅使用 CSS 中引用的一个图像(nav_matrix.gif)创建,如图 2-10 中的所示。

Before (right) and after (left) using {outline:none;} in the style sheet, when viewed in Firefox

图 2.9。在 Firefox 中查看时,在样式表中使用{outline:none;}的前(右)和后(左)

Navigation bar styled with the Navigation Matrix Reloaded technique

图 2.10。采用导航矩阵重载技术的导航条

设计的问题

在实现我所设想的设计时,我面临的一个更大的挑战是 Internet Explorer/Windows 和#teaser <div>的透明背景。我有两个选择:

  • 通过导出一个带有透明区域和照片的图像来伪造所有浏览器的透明度。

  • 使用透明的 PNG 作为背景图像,并使用 JavaScript 或 Internet Explorer 条件注释来“修复”Internet Explorer 版本 6 和更早版本的 PNG 透明度(Internet Explorer 7 包括对 PNG 透明度的本机支持;更透明的 PNG 善良见第五章。

我选择了第二个选项,让乐队成员更容易自己替换主页图像。更具体地说,我决定使用 Internet Explorer 条件注释来允许 Internet Explorer 使用其专有的 AlphaImageLoader 过滤器正确处理 PNG 几个好方法见http://alistapart.com/articles/pngopacity/。必要的代码放在文档的<head>中,如下所示:

<!-- fixes IE 5.5/6 png transparency -->
  <!--[if gte IE 5.5]>
    <![if lt IE 7]>
      <style type="text/css">
        #sidebar-tab { filter:progid:DXImageTransform.Microsoft.
        AlphaImageLoader(src='i/bg_sidebartab_events.png');
        background-image:none; }
        #teaser {
        background-image:none;
        z-index:10; }
        #teaser-ie { filter:progid:DXImageTransform.Microsoft.
        AlphaImageLoader(src='i/bg_teaser.png',sizingMethod='crop');
        position:absolute;
        left:0;
        bottom:0;
        width:507px;
        height:230px;
        bottom:-1px;
        z-index:0; }
      </style>
    <![endif]>
<![endif]-->

我还使用这个块来调整每个受影响的<div>的 CSS,这样标记都在一个地方。理想情况下,这个“一个地方”应该是外部样式表。不幸的是,Internet Explorer 条件注释只能在 HTML 文档中工作,尽管您可以将特定于 Internet Explorer 的样式放在一个单独的样式表中,并在条件注释中链接它。在准备一张新照片时,唯一需要定制的,并且如果客户忘记也不会“破坏”设计的,是照片底部边缘的阴影。但是,如果您不想在 Internet Explorer 6 和更早版本中使用 JavaScript 或专有解决方法来支持 PNG 透明度,并且如果在您的生产环境中创建特殊图像不成问题,那么伪造透明度仍然是一个可行的选择。

这样的#挑逗

设计完#teaser <div>后,我意识到我只考虑了一个单行的<h3>标题(有或没有 sIFR)。由于<div>的高度和背景图像已经指定,如果使用更长的文章标题,这肯定会引起问题。所以我决定完全移除#teaser的指定高度,并增加<div>的底部填充。因为入口页脚和read more按钮是绝对定位的,所以不受这个变化的影响;只有<h3>标题和<p>会与填充互动。我调整了透明背景图片(bg_teaser.png)使其更高(300px 比较合理),并重新保存了底部带有阴影的乐队照片。这张照片原本是放在#teaser的背景图片上,但是现在<div>的高度是可变的,这样就不行了。然而,我仍然可以在bg_teaser.png上保留左边的阴影。这给出了一个在#teaser <div>中使用多行标题的解决方案,如图图 2-11 所示。

It's a subtle difference, but the shadow at the bottom of the main photo allows the base of the image to blend into the background color of the navigation bar below, and works nicely with the transparent background of the #teaser <div>.

图 2.11。这是一个微妙的区别,但主照片底部的阴影允许图像的底部融入下面导航栏的背景色,并与#teaser <div>的透明背景配合得很好。

使用 Internet Explorer

在 Internet Explorer 6 中还可以看到一些奇怪的东西(不足为奇),但这些几乎都通过使用 Star-HTML hack 得到了解决,这是 Holly hack 的一部分,以 Holly Bergevinand 命名,并重新声明了问题元素的规则。Star-HTML hack 利用了 Internet Explorer 版本 6 和更早版本的渲染引擎所识别的额外元素。这个通用选择器 ( *)在<html>之外,由于它被任何非 Internet Explorer 浏览器忽略,所以可以用来向 Internet Explorer 发送特定的样式。

以主页上显示的乐队标志 CSS 为例:

h1#logo {
position:absolute;
left:15px;
top:20px;
margin:0;padding:0;
}

body.homepage h1#logo {
z-index:100;
left:29px;
top:39px;
}

Internet Explorer 版本 6 对绝对定位和z-index不太友好,因此徽标被呈现为不可见的。它仍然在那里,但浏览器选择不在我们可以看到的地方显示它。因此,不要花费大量的时间来制定一个在所有浏览器上都能正常工作的解决方案——这是理想的情况,但是请记住,紧张的预算和时间表——改变<h1>在 Internet Explorer 中的显示方式才是正确的做法。Star-HTML hack 允许我们将不同的风格发送到 only Internet Explorer:

* html body.homepage h1#logo {
position:relative;
margin-bottom:-170px;
}

所以我把定位从position:absolute改为position:relative,然后调整底部边距,直到 logo 定位到我想要的位置(本例中为 170 像素)。黑客之所以能成功,是因为它有更高的特异性(* html body.homepage h1#logobody.homepage h1#logo更具体),所以它不仅是唯一能理解这一规则的浏览器,还赋予了它比之前的规则更高的优先权。

还有一件事:因为允许这种攻击工作的缺陷在 Internet Explorer 7 中已经被修复,所以最好将这种攻击和任何其他针对 Internet Explorer 的攻击放在一个单独的样式表中,并在条件注释中链接它,这将在版本 7 中隐藏它,如下所示:

<!--[if lte IE 6]>
  <link rel="stylesheet" href="css/iehacks.css" type="text/css" media="screen" />
<![endif]>

当时间至关重要时,hacks 可以保护您的理智和您的项目免受 Internet Explorer 6 和更早版本中糟糕的标准支持的影响。但是一旦新的版本出现,这种情况就不一定了。如果您使用 hacks,那么您必须做好准备,如果将来 hacks 中断,您可能不得不重新访问旧的项目。

注意

尽管 Internet Explorer 在渲染错误方面受到了很多负面的关注。事实是所有的浏览器都有 bug。我们只需要找到最好的方法来解决那些给我们带来最多问题的问题。

结论

如果你检查现场站点的源代码,你会注意到有多少不必要的标记仍然存在于他们的 CMS 结构中。优化输出是一项持续的工作,我将继续向标签的开发团队提出建议。最后,如果您因为某种原因必须使用不受您完全控制的 CMS,重要的是要记住,仍然有许多技巧和工具可供您使用,以帮助您避免陷入在生成的标记的寒冷和狭窄的范围内创建无聊设计的窠臼。作为一名设计师,挑战 CMS 是值得的,而不是为了满足技术要求而简化你的设计。当网站上线时,你一定会睡得更好*

三、纽约杂志:天哪,多么优雅的<body>

ethan marcotte

www.vertua.com

伊森·马科特从事在线设计和开发已经近十年了,他仍然对有这么多东西需要学习感到惊讶和兴奋。他是 Vertua Studios ( www.vertua.com)的联合创始人和设计主管,这是一家熟悉标准的设计工作室,致力于构建优雅、可用的网站。

Ethan 已经成为基于标准的网页设计领域备受尊敬的声音。他是网页设计世界和西南偏南互动会议的重要发言人,他还经营着一个流行的(如果不经常更新的话)sidesh0w.com博客。他的客户包括《??》杂志、哈佛大学、华特·迪士尼公司和道富银行。

长大后,伊森想成为一名不可阻挡的机器人忍者(www.unstoppablerobotninja.com)。哔。

New York Magazine: My, What a Classy <body>

莫‘新城,莫’风格

老实说,重新设计《??》杂志网站对我来说是一种改变。我的小公司 Vertua ( www.vertua.com)通常标榜自己是一家提供全面服务的网店,或者至少是一家“一人军团”工作室所能提供的全面服务。然而,这个项目是一个受欢迎的改变,因为它本质上是一个“纯代码”的工作:该杂志与另一家工作室合作设计新网站,并正在寻找一个人来构建基于标准的模板。(我想在这里开一个“龙争虎斗”的玩笑,但我认为这很愚蠢。)

重新设计的模板列表令人印象深刻:该杂志在网站上有多年的遗留内容,都以不同的布局和模板呈现。此外,该杂志的内容管理系统(CMS)功能强大,但相当轻便——许多页面内容是由一组技术熟练但基本上无技术含量的内容制作者手工制作的。那么,基于标准的设计如何让杂志员工的生活更轻松呢?

在这一章中,我将讨论如何将多个class值赋给一个元素(在这种情况下,body可以真正简化你的代码,使你的级联样式表(CSS)更加模块化。通过编写 CSS 代码来检测您在body元素的class中写入的不同“切换”,您的样式表可以在页面上以截然不同的方式设计相同的标记。结果是所需的 HTML 模板数量大幅减少,并且能够对页面设计进行彻底的更改。

对于本章的大部分内容,我们将集中在通用文章模板上,如图 3-1 所示。

闲聊结束后,让我们一步一步地看一下如何将这些放在一起。

The finished article template

图 3.1。成品文章模板

开始使用

文章模板的交付要求它是一个灵活宽度的设计,在右边有一个固定宽度的侧边栏。图 3-2 向我们展示了页面需要如何伸缩。

The page layout requirements. The left column is flexible; the right column is fixed.

图 3.2。页面布局要求。左列灵活;右列是固定的。

为了给 New York 杂志创建一个带有固定宽度侧边栏的流动宽度内容区域,我使用了 Ryan Brill 的负边距技术,这在http://alistapart.com/articles/negativemargins有详细介绍。在研究了这种方法之后,我们可以创建一个空的标记外壳,准备接收内容的设计:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html >
<head>

<title>Article Template</title>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<link type="text/css" rel="style sheet" href="/style/screen.css"
  media="screen, projection" />
<!--[if lt IE 7]>
<link type="text/css" rel="style sheet" href="/style/patches-ie.css"
  media="screen, projection" />
<![endif]-->

</head>

<body id="www-newyorkmag-com">

<div id="wrap">
  <div id="content">
    <div id="content-layout">
      <div id="content-primary-wrap">
        <div id="content-primary">

        </div><!-- /end #content-primary -->
      </div><!-- /end #content-primary-wrap -->

      <div id="content-secondary">

      </div><!-- /end #content-secondary -->
    </div><!-- /end #content-layout -->
  </div><!-- /end #content -->
</div><!-- /end #wrap -->

</body>
</html>

根据 Brill 文章中概述的方法,我们不仅需要两个内容区域的两个div(发明名称为content-primarycontent-secondary),还需要一个围绕content-primary的包装器div,姑且称之为content-primary-wrap。忠实的信徒们,请继续关注:稍后我们会在这个包装上看到更多内容。

构建 CSS

在内容区域上方,您可能会注意到文档的head中有两个link元素:一个用于screen.css,另一个用于patches-ie.css。在我们的linked样式表screen.css中,我放置了以下内容:

import url("core.css");

/*\*//*/
import url("patches-mac.ie5.css");
/03/

在第一行中,import规则(www.w3.org/TR/CSS21/cascade.html#at-import)引用了另一个外部 CSS 文件core.css。这个样式表包含了我们的大部分 CSS 规则,没有任何特定于浏览器的样式表补丁。core.css所有浏览器都可以看到,包含我们纯粹的、无黑客的风格规则。

说到黑客,这正是第二条import语句所包含的内容。那一系列看起来奇怪的 CSS 注释实际上是 IE5/Mac 带通滤波器(www.stopdesign.com/examples/ie5mac-bpf),它可以防止除了麦金塔上的 Internet Explorer 5 (IE5)之外的任何浏览器看到其中的代码。所以现在,有了我们的半隐藏的patches-mac.ie5.css,我们可以在浏览器中放置任何样式规则来解决 CSS 错误。

为什么要为这种 CSS 中的 CSS 方法费心呢?这种方法的好处之一是易于维护:如果我们需要停止支持 IE5/Mac,通过分离这些代码,我们可以更容易地删除这些 CSS“补丁”。我们不需要筛选一个样式表的几百行代码,相反,我们可以将这些修复隔离在一个单独的文件中。一旦我们真的需要停止对那个浏览器的支持,我们可以简单地删除我们的screen.css文件中的那个import语句,就和 IE5 说拜拜了。

回到我们的 HTML 模板,我们看到patches-ie.css被一些奇怪的注释包围着:

<!--[if lt IE 7]>
  <link type="text/css" rel="style sheet" href="/style/2/ie-width.css"
    media="screen, projection" />
<![endif]-->

这些被称为条件注释,它们是一个仅用于 IE 的 HTML 扩展,允许我们在标记中构建编程逻辑。我们可以为 Windows 上的特定版本的 Internet Explorer 提供大量标记,在这个特殊的注释语法中指定版本号和其他条件。

注意

条件注释是专有的。HTML 的非标准扩展,因此。这些年来,它们一直是争议不小的话题。你可以在微软的网站(http://msdn.microsoft.com/workshop/author/dhtml/overview/ccoment _ ovw . ASP)以及众多的行业博客上找到更多关于条件评论的信息,比如 mezzoblue ( www.mezzoblue.com/archives/2005/11/03/ie7_conditio)。

在这里,我们使用那些条件注释来隐藏我们的第二个链接,它来自于比版本 7 ( <!--[if lt IE 7]>)更早的 IE ,然后链接到patches-ie.css中的另外两个样式表,就像这样:

import url("patches-win.iex.css");

media tty {
  i{content:"\";/*" "*/}} import 'patches-win.ie5.css'; /*";}
}/* */

与我们的 IE5/Mac 特定的 CSS 文件一样,这两个import规则引入了外部样式表,用于修补不同版本的 IE/Windows 中的错误:第一个规则适用于 Windows 上所有版本的 Internet Explorer,第二个规则仅适用于 IE5/Windows。更好的是,地球上所有其他非 IE 浏览器都不知道这些特定于浏览器的变通办法,因为这些条件注释被符合标准的浏览器视为常规 HTML 注释。因此,到patches-ie.css的链接对大多数浏览器来说是不可见的,可以被 IE/Windows 轻松解析。

在这一点上,你可能想知道(阅读:“疯狂地对着天花板尖叫”)为什么你要这样麻烦地分叉你的 CSS。为什么要链接到两个单独的样式表,它们只存在于import 其他 CSS 文件中,其中一些除了不同浏览器特定的 CSS 错误的变通方法之外什么都没有?(参见图 3-3 。)

正如你可能意识到的,你有很多方法可以在你的其他 CSS 规则旁边插入浏览器特定的 CSS 补丁(见http://cssdiscuss.incutio.com/?page=CssHack中的一些例子)。虽然将所有 CSS 保存在一个文件中只会让您担心一个 CSS 文件,但跟踪和更新各个浏览器的修复程序很快就会变成一场噩梦。使用多样式表方法,您可以智能地将 CSS 补丁隔离到特定于浏览器的样式表中,这将使未来的更新变得轻而易举。当你停止支持一个浏览器时会发生什么?好吧,不用在超过 2000 行的样式表中搜索你写在主 CSS 文件中的每个 IE5/Mac hack,你可以简单地删除在一个link ed 样式表中对该浏览器 CSS 补丁的import引用。努夫说。

有了这个 hack 管理框架,我们现在可以开始做一些有趣的事情了:对文档的标记应用一些基本的样式。是的,我知道是时候了。

Our CSS architecture

图 3.3。我们的 CSS 架构

注意

这里概述的方法受到了 Molly Holzschlag 的优秀文章“集成 Web 设计:长期 CSS 黑客管理的策略”(www.informit.com/articles/article.asp?p=170511&rl=1)的启发。这篇文章写于将近两年前,今天读起来和它第一次发表时一样好。阅读它,标记它,冲洗,重复。

添加图层样式

好了,关于浏览器 bug 和 CSS 补丁说够了。让我们给core.css添加一些基本的样式:

body {
  background: #FFF;
  color: #000;
  font: 62.5%/1.5 Arial, Helvetica, Verdana, Geneva, sans-serif;
  margin: 0;
  padding: 0;
}

#wrap {
  margin: 0 auto;
  min-width: 770px;
  max-width: 980px;
}

#content {
  background-color: #EBEAE8;
  border-top: 1px solid #D6D5D3;
  padding: 7px 8px 9px;
}

#content-layout {
  background: #FFF;
}

通过这几行代码,我们彻底改变了稀疏的 XHTML 的外观。我们在body上建立一些基本的字体和颜色属性;给#content来点。。。嗯,灰色;通过在我们的“包装材质”div上放置自动镶边来突出我们的设计。在图 3-4 中,你可以看到我们已经走了多远:我们的两个即将建成的柱子被很好地框住了,尽管它们是直接叠在一起的。

The default stacking order for the divs

图 3.4。div s 的默认堆叠顺序

此外,我们将min-widthmax-width值应用于#wrap,确保我们的设计符合客户的目标。模板的宽度将扩大到 980 像素,然后缩小到 770 像素。看起来不错,不是吗?

嗯,差不多了。通常会有一个蓝色“E”形的小问题:Internet Explorer 及以下版本不支持max-widthmin-width属性。对于 Windows 上的 IE,我们有很多解决方法。然而,对于《??》杂志来说,我选择了下面这段 CSS:

#wrap {
  width:expression(document.body.clientWidth > 980 ? "980px" : 
    (document.body.clientWidth < 772 ? "770px": "auto"));
}

expression()是一个动态属性,是微软的专有发明(http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/setexpression.asp),只能在 Windows 上的 Internet Explorer 中工作。它混淆了样式表和脚本之间原本清晰的界限,正如你所看到的,我已经直接在#wrap规则中写了一小段 JavaScript。当由 Internet Explorer 加载时,这个 JavaScript 检测页面的宽度(使用document.body.clientWidth,另一个 IE 专用的代码),如果窗口变得比我们的目标宽度大或小,就限制#wrap div的宽度。

在这一点上,观众中的标准化者可能会问,“但是 Ethan,你为什么要在一个符合标准的模板中使用非标准代码呢?你住在哪里,好让我朝你讨厌 W3C 的房子扔尖棍子?”

正是在这一点上,我们众多的 CSS“补丁”文件派上了用场。由于这只是针对 IE/Windows 的修复,我们可以安全地将无效代码放在我们的patches-win.iex.css文件中。藏在这个单独的文件中,我们的非标准代码对符合标准的浏览器和设备是隐藏的,是的,这包括受人喜爱的 W3C CSS 验证器。

负的边距和分栏等等!天啊。

有了一些标记和 CSS 基础,是时候完成我们的专栏了。瑞安·布里尔的负边际技术(http://alistapart.com/articles/negativemargins)是通过三个简单的步骤实现的:

  1. 在固定宽度的侧边栏上设置宽度(这里是content-secondary)。

  2. 向左浮动content-primary-wrap容器,将其宽度设置为 100%。

  3. 在容器上设置一个负数margin-right,它的宽度应该等于第一步中工具条的宽度。

所需的 CSS 就像听起来一样简单。首先,我们需要浮动我们的两列,就像这样:

#content-primary-wrap {
  float: left;
  width: 100%;
}

#content-primary {
  padding: 0 12px 0 13px;
}

#content-secondary {
  float: right;
}

在这一点上,快速预览我们的代码显示没有太多变化,除了我们丢失了部分灰色边框(图 3-5 )。

你可能会问,以蒂姆·伯纳斯·李的名义,这是怎么回事?或者你可能不是。我们真的不知道。

The layout is unchanged, but where's our border off to?

图 3.5。布局没变,但是我们的边界在哪里?

清算时间

尽管我们的两个内容div看起来与之前的没有太大的不同,但它们仍然是浮动元素,因此,它们将从它们的非浮动容器content-layout div中“逃离”。所以我们在文档顶部看到的边界实际上是content-layout的整个边界:它包含的两个浮动的div已经从它们的父容器中流出,有效地完全折叠了我们可怜的容器。所以content-layout现在没有非浮动元素来给它一些高度,我们可爱的四边边框看起来只是一条粗灰线。这自然不行。但不要一开始就咬牙切齿、揪头发。谢天谢地,有一个解决方案。

确保我们的集装箱。。。嗯,包含两列,我们用http://positioniseverything.net/easyclearing.html写的“简易清除法”。首先,我们将以下内容放在我们的core.css文件中:

#content-layout:after {
  content: ".";
  display: block;
  height: 0;
  clear: both;
  visibility: hidden;
}

这里我们使用了:after伪元素(www.w3.org/TR/CSS21/generate.html#x5)在容器的末尾,在所有其他元素之后生成额外的内容(即一个句点)。这些额外的内容对用户来说是隐藏的,但是变成了一个块级的元素,它将clear标记中在它之前的所有其他浮动。不幸的是,这一规则在 IE 的任何当前版本中都不起作用。更重要的是,为了安抚 IE 的 Windows 版本,我们实际上需要两个解决方案:一个是最新版本的 7,在撰写本文时这是一个公共测试版(但应该会在书上架时正式发布),另一个是对目前使用的早期版本的黑客攻击。

为了让 IE7 运行得更好,我们只需在我们的:after规则后插入以下内容:

#content-layout {
  display: inline-block;
  display: block;
}

值得称赞的是,网页设计师和标准大师 Roger Johansson ( www.456bereastreet.com)是第一个发布这个解决方案的人。display: inline-block;触发 IE7 中的非标准hasLayout属性,强制容器自动包含其中的任何浮动元素。

注意

更多关于 hasLayout 的信息,请阅读 Ingo Chao 关于该主题的优秀文章:www.satzansatz.de/cssd/onhavinglayout.html。当然,这样做很可能会让你的眼睛斜视和/或头发脱落,所以如果你完全相信这一点,也许是最好的。

为了在旧版本的 IE/Windows 中触发hasLayout,让我们将以下规则添加到我们的patches-win.iex.css文件中:

#content-layout {
  height: 1%;
}

最后,让我们打开我们的patches-mac.ie5.css文件,添加以下内容:

#content-layout {
  display: inline-table;
}

正如法国设计师所言, le voil 图 3-6 向我们展示了我们的彩车再次被遏制,我们的边境线坚强、灰暗、骄傲地屹立着。

With some clearing implemented, our border's back again.

图 3.6。随着一些清理的实现,我们的边界又回来了。

我从没说过我擅长这个“隐喻”的东西。继续前进。

获得列-tastic(最终)

现在我们的容器已经回到正轨,我们需要做的就是给我们的div应用适当的边距:给content-primary-wrap一个负的右边距,给content-primary一个右边距。这些边距中使用的值应该等于或大于我们现在要设置的content-secondary的宽度。

对于 190 像素宽的窄右列,我们可以使用以下代码:

/*
  Set the column offset on the content divs
*/
#content-primary-wrap {
  margin-right: 200px;
}

#content-primary {
  margin-right: 200px;
}

/*
  Set the right-hand column width
*/
#content-secondary {
  width: 190px;
}

至此,我们的列效果完成,如图图 3-7 所示。

Finally, our two-column layout takes shape.

图 3.7。最后,我们的两列布局成型。

正如你在图 3-8 中所看到的,这种灵活宽度的布局在较小的窗口宽度中令人钦佩地缩小了,这应该会让我们的客户非常非常高兴。

Our flexible-width design shrinks down admirably to smaller window widths. Hurrah!

图 3.8。我们灵活的宽度设计令人钦佩地缩小到更小的窗口宽度。万岁!

简单,是吗?但是请记住,我们有两个右边的列宽需要考虑:一个是我们刚刚编码的窄列宽,另一个是 360 像素的宽栏。我们必须为这个新的侧边栏宽度构建一个单独的模板吗,或者我们可以重用到目前为止所做的工作吗?你不喜欢引导性问题吗?

我的班芙是不可阻挡的

在这里,我们终于可以利用body元素上的class属性了。如果我们知道我们有两个独立的侧边栏列宽,为什么不相应地分配一个class来“描述”文档呢?所以对于我们狭窄的广告栏宽度,我选定了

<body id="www-newyorkmag-com" class="ad-column-180">

对于更宽的一个,我用

<body id="www-newyorkmag-com" class="ad-column-300">

注意

严格地说,这些类名可能不是最理想的。一般来说,尽量避免使用表示元素向用户显示的方式的类或 id 值(例如红色链接、大标题,甚至 ad-column-300)。避免使用这些“表象”名称的主要原因是它们不是特别经得起未来的考验:当你重新设计你的网站时会发生什么,所有那些红色链接元素都需要变成绿色?ad-layout-1 或 ad-layout-2 可能更抽象,可能更好一些;然而,我们认为制作人员可能会更好地管理更具描述性的名称,剩下的就是历史了。或者类名。或者什么的。

实际上,这给了我们的模板一种切换,我们可以利用我们的 CSS。如果我们知道这两个模板中的一个将被应用于我们的body元素,我们可以相应地修改我们的样式规则:

/*
  Set the column offset on the content DIVs
*/
body.ad-column-180 #content-primary-wrap {
  margin-right: 200px;
}

body.ad-column-180 #content-primary {
  margin-right: 200px;
}

body.ad-column-300 #content-primary-wrap {
  margin-right: 370px;
}

body.ad-column-300 #content-primary {
  margin-right: 370px;
}

/*
  Set the right-hand column width
*/
body.ad-column-180 #content-secondary {
  width: 190px;
}

body.ad-column-300 #content-secondary {
  width: 360px;
}

在这里,我们充实了我们最初的规则,并用适当的body.ad-column-180body.ad-column-300选择器为两个单独的列宽做准备。

注意

正如你可能已经注意到的,ad-column-300 列实际上将是 360 像素宽。我从来都不擅长数学,但这个小小的命名差异是有原因的:更宽的栏将容纳 300 像素宽的广告横幅。因为非技术内容生产者最终将“拥有”这些模板,所以我选定了一个对他们有意义的类名。

此外,我们可以将不同的水平重复背景图形应用到内容布局中(参见图 3-9 和 3-10 ),以在右栏后面产生“灰色”背景的错觉。

The gray background image for our narrow right column

图 3.9。右侧窄栏的灰色背景图像

The gray tile for our wide right column

图 3.10。右侧宽栏的灰色区域

我们需要做的就是用下面的 CSS 替换我们的content-layout规则:

#content-layout {
  background-color: #FFF;
  background-position: 100% 0;
  background-repeat: repeat-y;
}

body.ad-column-180 #content-layout {
  background-image: url("bg-ad-column-180.gif");
}

body.ad-column-300 #content-layout {
  background-image: url("bg-ad-column-300.gif");
}

我们栏目的“背景”会自动调整,如图图 3-11 和图 3-12 所示。

The narrow graphic is applied with the ad-column-180 class on the body element.

图 3.11。窄图形是用body元素上的ad-column-180 class应用的。

By switching the class to ad-column-300, we've changed to the larger image for our wider column.

图 3.12。通过将class切换到ad-column-300,我们已经为更宽的列切换到更大的图像。

你可能会问,这种方法有什么好处?依靠这种class驱动的切换,我们的其余标记可以在两种布局场景中重用:只需将模板的body中的ad-column-180改为ad-column-300,我们就可以立即改变标记的显示样式。图 3-13 和 3-14 显示了这在两个不同的实时、生产就绪的文章模板上的实际应用,两者之间唯一的变化是body元素的class属性中的几个字符。这两个页面上的其余标记是相同的。我不知道你怎么想,但我对这种事情很感兴趣。

Our finished article template, with ad-column-180 in the body element's class attribute.

图 3.13。我们完成的文章模板,在body元素的class属性中有ad-column-180

The exact same template code, but with ad-column-300 in the class. Hot.

图 3.14。完全相同的模板代码,但是在class中有ad-column-300。很辣。

智能模块

因此,我们的页面级布局由新的class驱动的开关控制,让我们试着对页面的细节进行同样的控制。早些时候,我提到除了body元素的class属性,页面的标记还包括右边一栏中的一小部分内容块,或模块。就像我们刚刚创建的两列一样,这些模块会自动调整大小,以适应侧边栏的宽度。

让我们快速看一个例子,“现在在。。."模块。在其窄格式中(图 3-15 ,内容堆叠在一个单列中;然而,当content-secondary栏为宽格式时,两个内容区域并排放置(图 3-16 )。(我想郑重声明,这张图不是我选的。)

The narrow version of the "Now In ..." module. I'd like to state for the record that we didn 't pick this picture.

图 3.15。狭义版的“现在在……”模块。我想郑重声明,我们没有选这张照片。

使用我们从构建两列布局中学到的知识,让我们在这里尝试相同级别的标记重用。如果我们能有一个 HTML 模板用于这两种不同的模块布局,那将是理想的。

为此,让我们快速回顾一下本模块中不同的内容领域。我们可以看到有两个不同的内容区域,顶部有一个标题(图 3-17 )。即使在两栏版本中也是如此(图 3-18 ),但是第一个内容区域出现在右栏,第二个内容区域出现在其左侧。

The wide, two-column version of the "Now In ..." module

图 3.16。“现在流行...”的宽、两栏版本模块

The anatomy of our narrow module

图 3.17。解剖我们的狭窄模块

The two-column, wide-format layout

图 3.18。两栏宽格式布局

因此,有了对两种布局选项(单列和两列)中不同内容区域的基本理解,我们就可以构建一个基本的标记框架了。

<div class="block module-in-section">
  <div class="head">
    <h5><img srcimg/title-in-section.gif"
      alt="Now In Section" /></h5>
    <h6><img srcimg/title-slideshow.gif" alt="slideshow"
      /></h6>
  </div>
  <div class="content">
    <div class="row columns-2">
      <div class="column col-1">
        <img srcimg/156x78-in-section.jpg"
          alt="Now In Section" />
      </div>
      <div class="column col-2">
        <h5><a href="#">Apocalypse Guide</a></h5>
        <p>How to avoid avian flu, wash off a dirty bomb, evacuate,
          medicate, and otherwise live through a disaster.</p>
        <ul>
          <li><a href="#">Bulleted Link 1</a></li>
          <li><a href="#">Bulleted Link 2</a></li>
          <li><a href="#">Bulleted Link 3</a></li>
        </ul>
      </div>
    </div>
  </div>
</div><!-- /end div.module-in-section -->

这里有一些事项需要注意:

  • 模块的class属性的block值是我在整个纽约杂志模板中放置的一段可重用的标记。它只是简单的一个简单的清算方法的挂钩,并被添加到那些规则中(.block:after等)。)以便它包含内部的任何浮动。

  • 内容区域中的row类提供了类似的功能:如果它的任何一个子“列”div被浮动,它们不会逃脱它们的父“行”div

  • 模块的class ( module-in-section)中的另一个值充当这种类型模块的一种唯一标识符。我不能在这里使用一个真正的id属性,因为一个页面上可能会出现不止一个这种类型的模块,而且根据 HTML 规范,id在页面中必须是唯一的。

标记就绪后,我们可以继续对其进行样式化。鉴于该模块的宽版本和窄版本具有相同的美学品质(如排版、颜色和背景图像),我在这里就不讨论它们了;相反,让我们专注于构建我们的两个内容栏。

在单列模式中,我们可以让标记的源顺序为我们工作。第一列将简单地堆叠在第二列之上,如图图 3-17 所示。然而,我们可以应用一点 CSS 来清理一些东西:

.module-in-section .content {
  padding: 0 14px 13px;
}

body.ad-column-180 .module-in-section .col-1 {
  text-align: center;
  margin: 7px 0 10px;
}

第一个规则只是对我们的内容div应用一些填充,给我们的列一些喘息的空间。第二条规则将列内容(即img)居中,并添加一些顶部和底部边距。但是你可能已经注意到了,我们在第二个规则前面加上了同样的body.ad-column-180规则,我们用它来创建我们的窄边栏(在“我的班级-fu 是不可阻挡的”部分)。一个class,两个独立效果。轻量级代码是一件美好的事情,不是吗?

从这个逻辑出发,我们可以将ad-column-300 class应用到body元素来创建我们的两列效果。我们需要浮动每一列div,第一列浮动到右边,第二列浮动到左边,如图 3-19 所示。

body.ad-column-300 .module-in-section .column {
  width: 157px;
}

body.ad-column-300 .module-in-section .col-1 {
  float: right;
}

body.ad-column-300 .module-in-section .col-2 {
  float: left;
}

The code to get our two-column layout in place

图 3.19。让我们的两列布局就位的代码

所以我们有了它:我们的body属性中的一个单独的class值可以作为我们侧边栏中每个模块的一种交通警察。我们已经编写了一些期望(并利用)出现ad-column-180ad-column-300的 CSS,让我们的标记完全保持原样。

附加类别,附加控制

此时,我们已经在class属性中使用了一个值。通过使用ad-column-180ad-column-300,我们可以立即重新格式化右侧边栏及其内容。正如我们已经讨论过的,class属性可以接受多个值,但是我们可以使用body元素来控制页面表示的其他方面吗?我又开始问引导性问题了。

从小尺寸开始(980 像素)

当我参与纽约杂志网站的重新设计时,我被告知制作团队希望能够选择性地覆盖某些页面的灵活宽度设计,有效地将页面宽度固定在 980 像素。据推测,某些页面可能包含宽幅媒体(例如,大幅照片),而客户希望确保页面布局的其余部分保持不变。

让我们再来看看我们的#wrap规则,它包含了我们的min-widthmax-width参数:

#wrap {
  margin: 0 auto;
  min-width: 770px;
  max-width: 980px;
}

因此,如果这是默认行为,让我们给我们的body元素添加一个新的class值来覆盖它的 say,“fixed”?

<body id="www-newyorkmag-com" class="ad-column-180 fixed">

我们现在可以放入下面的 CSS,将我们的灵活设计变成静态设计:

body.fixed #wrap {
  width: 980px;
}

现在我们有了。既然我们现在已经在我们的wrap块上设置了宽度,那么min-widthmax-width属性就过时了。我们设计的容器div固定在要求的 980 像素,这满足了我们客户的要求。

注意

关于多个类名的一个警告:老版本的 IE5/Mac 有一个空格解析错误(www.macedition.com/cb/ie5macbugs/substringbug.html),当遇到一个类名是另一个类的子串时,这个错误会导致它变得混乱。因此,尽量使你所应用的类类型的类别尽可能的独特,并在浏览器中进行彻底的测试。

搭售 JavaScript

我们可以用body class调用一些其他的视觉效果,但是让我们暂时离开设计。毕竟这个技术远不是一招小马。我们还可以将类附加到文档中,作为 JavaScript 驱动的行为的标志,为网站的设计增加另一层基于标准的吸引力。

例如,在一些文章页面上有一组链接(图 3-20 )用于动态增加(图 3-21 )或减少(图 3-22 )页面上文章文本的大小。何必呢?嗯,这实际上是一个相当方便的辅助功能。如果读者视力下降,他可能不知道如何改变浏览器的文本大小。在页面上放置几个链接会以一种直接且易于使用的方式展示类似的功能。

The text-sizing control that appears on certain pages of the website

图 3.20。出现在网站某些页面上的文本大小控件

The text size can be increased . . .

图 3.21。文本大小可以增加。。。

. . . or decreased by using the links on the page. You're floored, I can tell.

图 3.22。。。。或者通过使用页面上的链接来减少。我看得出来,你被难倒了。

受古老的基于 JavaScript 的样式表切换器(www.alistapart.com/stories/alternate)的启发, New York 杂志的文本大小调整代码执行许多不同的任务。当用户点击其中一个链接时,一个额外的类被添加到body元素中,当它出现时,将相应地改变文章模板中文本的大小。此外,存储在用户浏览器上的 cookie 会记住用户的选择,并在用户返回时自动应用适当的文本大小。这是一段相当复杂的 JavaScript,但这可能是因为我们并不是 JavaScript 程序员的塞缪尔·L·杰克逊。

需要注意的是,你在图 3-20 中看到的链接实际上并不存在于 HTML 中。页面加载后,JavaScript 将三个“A”链接注入到页面中,确保控件只对浏览器支持它们的用户可用。我们对body元素的class表现出近乎强迫性的痴迷,我们可以使用该属性来触发我们的功能,这将允许我们的内容制作者将一个简单的单词放入class来调用该功能,从而将链接放入页面。

一如既往,让我们从我们的元素开始吧我知道,令人震惊。但是这一次,让我们使用text-sizer作为我们的新类:

<body id="www-newyorkmag-com" class="ad-column-180 fixed text-sizer">

在我们从文档的head中引用的scripts.js文件中有一个名为buildTextSizer的函数:

<script type="text/javascript" src="/path/to/scripts.js"></script>

这个函数有相当多的代码,所以如果你不是 JavaScript 忍者也不用担心(毕竟,我肯定不是)。幸运的是,我们最关心的部分发生在顶部:

function buildTextSizer() {
  if (document.getElementsByTagName && document.createElement 
    && document.getElementById) {
    var trigger = document.getElementsByTagName("body")[0];
if (findWord("text-sizer", trigger.className)) {
      if (document.getElementById("article-content")) {
        var container = document.getElementById("article-content");
      } else {
        var container = document.getElementById("content-primary");
      }

      if (container) {
        // Build elements
        var slugs = new Array("small", "medium", "large");
        var controlContainer = document.createElement("div");
        var topList = document.createElement("ul");
        var innerList = document.createElement("ul");
        var listItem = document.createElement("li");
        var span = document.createElement("span");
        var labelText = document.createTextNode("Text Size:")

        // Loop over the text size "slugs", and build a link for
        //each one
        for (var i = 0; i < slugs.length; i++) {
          var text = document.createTextNode("A");
          var anchor = document.createElement("a");
          var item = document.createElement("li");

          anchor.appendChild(text);
anchor.setAttribute("href", "javascript:textIt('txt-" +
            slugs[i] + "');");
          anchor.setAttribute("title", "Make the story text " +
            slugs[i] + ".");
          item.appendChild(anchor);
          item.setAttribute("id", "txt-" + slugs[i]);
          innerList.appendChild(item);
        }

        // Assemble everything, and insert it into the
        //document
        span.className = "label";
        span.appendChild(labelText);
        listItem.appendChild(span);
        listItem.appendChild(innerList);
        topList.appendChild(listItem);
        controlContainer.setAttribute("id", "text-size");
        controlContainer.appendChild(topList);
        container.insertBefore(controlContainer, container.
          childNodes[0]);
      }
    }
  }
}

/*
  Find full word (needle) in a string (haystack)
*/
function findWord(needle, haystack) {
  return haystack.match(needle + "\\b");
}

从本质上讲,我们这里有两个独立的函数:一个用于构建文本大小控制(buildTextSizer,继续我的获奖名称),另一个函数是第一个函数使用的findWord。在用粗体突出显示的代码部分中,buildTextSizer检查我们的body元素(var trigger = document.getElementsByTagName("body")[0];),并搜索其class属性中是否存在text-sizer字符串(findWord("text-sizer", trigger.className))。如果搜索结果匹配,那么函数的其余部分继续构建文本大小调整链接;如果没有找到匹配(即如果text-sizer没有出现在body元素的class属性中),那么函数停止运行,链接永远看不到。

由于该函数被设置为在站点的每个页面上触发,内容制作者可以有选择地将class放在他们希望显示大小控制的页面上,而在其他页面上省略它。如果在body元素中找不到text-sizer,该功能将会自动失败,这为网站的作者提供了切换该功能的灵活性和方便性。这当然是件好事。

总结

这一章绝不是在杂志网站上使用body元素的class属性的详尽列表;我很乐意给你提供这样一份清单,但我不认为我能强迫你耐着性子看完托尔斯泰长度的一章关于body元素的内容。相反,我希望这一章中的信息能激发一些想法,让你明白这种多类值技术如何能给你带来好处,以及它的智能应用如何能减少你的站点的模板数量,减少标记混乱,并给你足够的 JavaScript 和 CSS 的钩子。在纽约杂志网站上,我们使用了额外的class es 来动态替换特定区域的徽标,并自动突出显示当前的导航标签。这方面的其他应用完全取决于你。

Web 标准是关于改进对设计的控制,而不是维护庞大的代码。拥抱你的body,你的网站将更容易维护、更新和改进。当然,你的用户会喜欢的。

四、为打破常规而设计

安迪·克拉克

www.malarkey.co.uk

www.stuffandnonsense.co.uk

在英国,安迪·克拉克(马拉其)有广告背景。1998 年,他创办了自己的设计咨询公司 Stuff and nullness。从那以后,他为英国迪斯尼商店、英国心脏基金会、救助儿童会和英国世界野生动物基金会设计了网站。

安迪对设计和网络标准充满热情;他弥合了设计和代码之间的鸿沟。在工作室之外,Andy 是 Web 标准项目的成员,他在 2006 年重新设计了该组织的网站,并且是 W3C 的 CSS 工作组的特邀专家。

Andy 是国际知名的培训师和会议发言人,他定期培训设计师和开发人员 Web 标准的创造性应用。他在自己的个人网站上写一些关于设计和流行文化的内容,这些都是胡扯(www.stuffandnonsense.co.uk),他还是《超越 CSS 的 ??:网页设计的艺术()的作者,该书于 2006 年由 New Riders 出版(www.transcendingcss.com)。

Designing for Outside the Box

担忧?

“哦宝贝,怎么了?”她说。“你看起来压力很大,很担心。”

“我是,”我回答。“我担心我们的车需要新轮胎,除了一纸袋蘑菇和一管番茄酱,我们冰箱里没有喝茶用的东西,我妈妈的脚又有问题了。”

我可以告诉你,这可不是闹着玩的。如果担心自己的问题还不够糟糕,担心别人的问题会让人抓狂。尽管如此,一种叫做WorrySome.net的新型虚拟服务形式的帮助就在眼前。

这将不是你常见的或普通的网络应用程序,有足够的风险资本在新德里发动一场小战争和一个呼叫中心。这个网站是“由真实的人,为真实的人”的人会为你担心,当然是收费的。只要你继续付费,这项服务将让你自由自在地生活,无忧无虑。

我需要一个新网站,而你正是这份工作的合适人选。这是一个棘手的问题,但不要担心;帮助就在你身边,引导你把这个设计变成现实。如果你觉得在任何阶段你开始变得哪怕是一丁点儿担心,你总是可以付钱给一个担心的人来减轻你的负担。

在这一章中,你将把WorrySome.net主页从 design visual 变成一个使用 XHTML 和 CSS 的工作原型。你将从有意义的、内容外的标记开始,这总是开发一个创造性的、基于标准的设计的第一步。您将学习如何使用强大的 CSS 选择器和布局技术来实现这种设计。

担心网络

我个人很高兴WorrySome.net能代我担心,因为这两年,我一直在担心网页设计。网络是一个年轻的、充满活力的媒介,人们应该喜欢与他们访问的网站互动。创建人们喜欢使用的网站是创造性网页设计的主要目标之一。但是网页设计者和开发者经常关注标记、CSS、Ajax 的技术方面,或者可用性和可访问性的“科学”,而不是通过好的设计来联系访问者的情感。

我们已经看到了 CSS 提供的工具的进步,以及主流 web 浏览器对这些工具更广泛的支持。我希望我们不要再担心支持过期的浏览器,而是通过创造新的、鼓舞人心的设计来打破当前的思维模式。

WorrySome.net设计

由于WorrySome.net是一种处理世界忧虑的新颖的新方法,该网站呼吁一种打破当今许多闪亮的网络应用程序的熟悉惯例的设计。摘要要求这种设计是开放和友好的。它必须让访问者感觉“像一个值得信赖的朋友一样受欢迎,而不是像一个顾客一样。”

在设计WorrySome.net的外观时,设计采用了多种形式。我用许多不同的界面想法做了几个实验性的布局,只有少数几个进入了最终的设计。图 4-1 显示了你将在本章中使用的那个。

让我们开始将WorrySome.net主页的设计变成现实吧。您将使用有意义的 XHTML 标记和 CSS,但不只是任何旧的 CSS。这个最小的标记将要求你使用你可能还没有在自己的工作中实现的技术和 CSS 选择器。您可以从www.friendsofed.com下载所有必要的文件。

WorrySome.net homepage

图 4.1。WorrySome.net主页

别担心,从涨价开始

从事网络工作的设计师的目标之一应该是传达意义。我说的不仅仅是通过视觉设计来强化品牌价值所表达的意思,还有通过为内容选择的 XHTML 元素所传达的意思。根据元素的含义而不是视觉表现来选择合适的元素,这将有助于你创造出尽可能灵活和易于理解的设计。(当然,你还需要确保你的标记尽可能的精简和灵活。)您希望确保在没有 CSS 所提供的视觉丰富性的情况下,元素能够传达内容的全部含义。

回头看图 4-1 ,写下页面上每个视觉元素的含义。在此设计中,您会看到以下元素:

  • 一个包含网站名称和标语的品牌区,歌词来自鲍勃·马利,一位悠闲生活方式的大师

  • 导航链接列表

  • 三个标题,每个标题后面都有几段文字和一个烦恼者的内嵌图像

  • 标题后面是一系列人们经常担心的话题:从阴谋到乔治·w·布什(我想不出有什么联系,没有,先生)

  • 网站信息,通常包含法律注释、版权信息和设计致谢

完成内容大纲后,您就可以充实最适合表达其含义的标记了。在这一点上,您应该只关心描述这个内容的含义,而不是任何 division 元素或表示性标记技巧。

你应该从内容大纲的顶部开始,然后向下,所以我们从品牌开始。

添加内容元素

在 WorrySome 的主页上,网站名称可以作为页面顶级标题的一个不错的选择。

<h1>Worrysome.net</h1>

许多设计者会选择在内部页面上改变这一点,选择二级标题,保留顶级标题作为页面名称。在内部页面上,这个名称可能还会包含一个返回主页的链接,这在主页上是多余的。

接下来是标语。写在牙买加马利家的台阶上,那里烟雾缭绕,这是《三只小鸟》的摘录,非常适合作为一个放松的网站。浏览 XHTML 规范的页面,如果需要的话,寻找一个lyric元素。我就在这里等着,唱着“纯净而真实的甜美歌曲”,直到你回来。

已经回来了?

Adding the content elements

在没有更合适的元素来标记雷鬼伟人的这首诗的情况下,一个blockquote元素就可以了;毕竟他唱过那些词。

<blockquote cite="http://www.bobmarley.com/songs/songs.cgi?threebirds">
<p>Don' worry 'bout a thing, cos every lil thing is gonna be alright.</p>
</blockquote>

注意

注意引用的 URL 来源已经被引用。尽管这些信息在访问者的网络浏览器中是看不到的,但你还是应该注明你引用的任何引文的来源。关于使用脚本显示引用的 URL 的示例,请参见 Jeremy Keith 的书DOM scrp ting:Web Design with JavaScript and the Document Object Model(编辑之友,ISBN: 1-59059-533-5)。

如果你仍然“心情愉快”,那么构成主导航的订阅页面、忧虑列表和购物车的链接列表是有序的,任何特定链接都没有任何重要性或权重。无序列表是标记这些链接的合适选择。

<h4>Main navigation</h4>
<ul>
  <li><a href="#" title="Subscribe">Subscribe</a></li>
  <li><a href="#" title="Worrylist">Worrylist</a></li>
  <li><a href="#" title="Worrycart">Worrycart</a></li>
</ul>

但是标题在那里做什么?导航链接列表顶部的低级标题可以帮助使用屏幕阅读器(或其他形式的辅助技术)的访问者了解列表的用途。您可以选择使这些标题可见或隐藏,也许是通过在屏幕上缩进它们。这种技术被称为提供一个嵌入式替换

现在我们真的“卡住了”,是时候转移到这个主页上感兴趣的主要内容了:这个站点提供的服务的描述。您将为每个内容区域选择一个二级标题,后面是相关内容。

<h2>Worriers</h2>
<p>Introduction text</p>
<img src="img/worryone-i.png" alt="Lynda" />
<p>Name and role of worrier</p>
<p>Further descriptive text</p>

<h2>Worries</h2>
<p>Introduction text</p>
<img src="img/worrytwo-i.png" alt="Andy" />
<p>Name and role of worrier</p>
<p>Further descriptive text</p>

<h2>Worry done</h2>
<p>Introduction text</p>
<img src="img/worrythree-i.png" alt="Brain" />
<p>Name and role of worrier</p>
<p>Further descriptive text</p>

一个第三级标题自豪地宣布网站的专家担忧小组可以从你肩上卸下的主题列表。因为这个列表是按字母顺序排列的,所以选择一个有序列表而不是无序列表是否最合适是有争议的。对于这个例子,我选择了无序,因为没有一个条目比它的兄弟条目更重要。

<h3>Recently worried about</h3>
<ul>
  <li><a href="#">Worry item</a></li>
  <li><a href="#">Worry item</a></li>
  <li><a href="#">Worry item</a></li>
</ul>

你现在几乎在页面的底部,在网站信息和一个方便的链接回到顶部,以保存访问者的滚动手指。

<p><a href="http://www.stuffandnonsense.co.uk"> Stuff and
  Nonsense Ltd.</a> A demonstration site by Andy Clarke</p>
<ul>
  <li><a href="#worrysome-net" title="Top of this page">Top</a></li>
</ul>

有了整洁地编写的有意义的标记,现在你有机会在开发浏览器中预览你的页面(见图 4-2 )并验证你的代码以确保没有错误出现。

注意

如果像我一样,您选择的开发浏览器是 Firefox,您可以找到许多开发人员扩展,它们将在您工作时保持您的标记有效,尤其是 Chris Pederick 的基本 Web 开发人员工具栏。您可以从http://chrispederick.com/work/webdeveloper/下载 Web Developer 工具栏。

Adding the content elements Previewing the page in a browser to ensure that the content is well ordered when read without syles is your first step in developing visually expressive but accessible designs.

图 4.2。在浏览器中预览页面,以确保在没有字体的情况下阅读时内容是有序的,这是开发视觉上富有表现力但又易于访问的设计的第一步。

从内容中添加分部出来

总的来说,web 设计人员对标记和 CSS 的理解在最近几年有所发展,但是自从我们使用表格进行布局以来,我们对使用 CSS 完成视觉设计的方式的想法几乎没有改变。剥去许多基于标准的网站的外观,它们的 W3C“有效的 XHTML 和 CSS”徽章在阳光下闪闪发光,你会发现大量无意义和不必要的<div><span>元素。

从内容着手意味着只从结构元素开始,比如标题、段落和列表。这是让您的标记不受表示元素影响的理想方法。

接下来,您将只对那些您先前选择的相关元素进行分组,并为每个元素赋予一个标识来描述它所包含的内容。

注意

关于语义元素命名的主题已经写了很多。前 CSS 武士约翰·奥尔索普创建了 WebPatterns ( www.webpatterns.org),一个致力于元素命名惯例的网站。我关于命名约定主题的原始文章可以在 All That Malarkey ( www.stuffandnonsense.co.uk/archives/whats_in_a_name_pt2.html)找到。

为了避免代码重复,下一个示例只显示了内容区域,而不是再现标记的每一个细微差别。

<div id="branding">
  <h1>Worrysome.net</h1>
  <blockquote cite="http://www.bobmarley.com/songs/songs.cgi?threebirds ">
    <p>Don' worry 'bout a thing, cos every lil thing is gonna be alright.</p>
  </blockquote>
</div>

<div id="nav_main">
  <h4>Main navigation</h4>
  <ul>
    <li><a href="#" title="Subscribe">Subscribe</a></li>
    <li><a href="#" title="Worrylist">Worrylist</a></li>
    <li><a href="#" title="Worrycart">Worrycart</a></li>
  </ul>
</div>

<div id="content">
  <div id="content_main">
<div id="worriers">
                   <h2>Worriers</h2>
                   <p>Introduction text</p>
                   <img src="img/worryone-i.png" alt="Lynda" />
                   <p>Name and role of worrier</p>
                   <p>Further descriptive text</p>
                </div>
<div id="worriers">
      <h2>Worriers</h2>
      <p>Introduction text</p>
      <img src="img/worryone-i.png" alt="Andy" />
      <p>Name and role of worrier</p>
      <p>Further descriptive text</p>
   </div>

   <div id="worries">
      <h2>Worries</h2>
      <p>Introduction text</p>
      <img src="img/worrytwo-i.png" alt="Andy" />
      <p>Name and role of worrier</p>
      <p>Further descriptive text</p>
    </div>
  </div>

  <div id="content_sub">
    <h3>Recently worried about</h3>
    <ul>
      <li><a href="#">Worry item</a></li>
      <li><a href="#">Worry item</a></li>
      <li><a href="#">Worry item</a></li>
    </ul>
</div>
</div>

<div id="siteinfo">
  <p><a href="http://www.stuffandnonsense.co.uk"> Stuff and Nonsense Ltd. </a>
  A demonstration site by Andy Clarke</p>
  <ul>
    <li><a href="#worrysome-net" title="Top of this page">Top</a></li>
</ul>
</div>

这些适当标识的部分不仅增加了结构,使您能够更容易地开发视觉布局,而且它们的标识符也有助于增强它们所包含的内容的意义。在基于内容的工作流中,这种最小化划分的使用应该始终是您的方法。这使得在编写标记时,内容而不是视觉布局成为您思考的中心。

如果需要额外的部门来完成任何特定的设计,应该一次添加一个部门,直到可以实现您的设计。对于这种设计,只需要一个额外的容器部分,包装所有的元素。除了htmlbody元素之外,这个容器是一种允许您进一步选择样式的常用方法。

<div id="container">
All document content
</div>

您可能已经注意到,在这个标记示例中,没有添加额外的标识符或class属性,尽管设计很复杂。很少需要这样的表示属性,因为您的标记已经包含了所有的元素和属性(hreftitlealt等等),当您对基于标准的设计采用成熟的方法时,您可能会用到这些元素和属性。

完成标记中的元素和适当的划分后,但在开始使用 CSS 之前,您应该花点时间考虑再添加一个元素。这将有助于那些使用屏幕阅读器或不支持样式表的小屏幕浏览器浏览网站的访问者。

虽然期望每个访问者都能完全访问这个网站或任何其他网站是一个不可能的梦想,但在你的文档中添加一些不引人注目的内容会给一些人带来巨大的帮助。对于本例,您将添加一个简短的跳转链接列表,以允许屏幕阅读器用户跳转到主导航或主要内容。

<ul id="nav_access">
<li><a href="#nav_main">Skip to navigation</a></li>
<li><a href="#content_main">Skip main content</a></li>
</ul>

您应该将这个列表直接插入到开始的<body>标签之下,容器部分之外。

满足你的灵魂(用 CSS)

如果标记是你的“朋克雷鬼派对”,那么将它转化为视觉设计布局应该是你“满足我的灵魂”的时间。(好了,这是最后一首鲍勃·马利的歌名说大话,我保证。)

从面条事件(www.thenoodleincident.com)和蓝色机器人(www.bluerobot.com)的早期开始,使用 CSS 实现设计布局已经走了很长的路。在实际使用 CSS 的那些日子里,定位是实现列和其他布局特性的首选方法。不久之后,随着设计者越来越雄心勃勃地尝试使用 CSS 来制作复杂的设计,定位让位于使用浮动。不幸的是,定位及其相关的z-index堆叠已经有些失宠了。

尽管乍一看,定位很难理解,但它可能仍然是 CSS 设计工具中最强大的。实现WorrySome.net布局将大量使用定位和z-index以及浮动。

您还将使用图像替换和一整套 CSS 选择器。如果你使用 CSS 已经有一段时间了,其中的许多你会很熟悉;其他人可能看起来很奇怪。你将使用选择器,直到最近它还是网页设计者的梦想。不要担心“水牛战士”(对不起,我无法抗拒),我会解释每一个新的选择器和技术,因为我们的进展。

开往 Styleville 的火车

直到最近,你对可以在不同浏览器上可靠使用的 CSS 选择器和技术的选择还仅限于世界上最常用的浏览器微软的 Internet Explorer 6 for Windows 支持的几个简单的选择器。由于 Internet Explorer 7 开发人员的辛勤工作和对标准的热情,以及 web 标准项目(www.webstandards.org)的 Molly E. Holzschlag 等人的奉献,这种情况现在已经改变了,他们在 Web 开发人员社区和微软之间架起了桥梁。我们都应该感谢他们的工作。

Internet Explorer 7 远非完美的浏览器(什么浏览器?),但确实让浏览器公平竞争。它对所谓的“高级”CSS 选择器有很好的支持,并修复了过去版本的渲染问题和错误,这些问题和错误近年来一直困扰着 web 设计人员。

我想要时尚

尽管它们对 CSS 的渲染大体一致,但大多数浏览器在应用作者或用户样式之前会有不同的页面默认渲染方式,即页面的外观,使用所谓的用户代理浏览器样式,通常也称为默认样式。因此,您应该从在样式表中添加一些简单的规则开始,以保证任何元素的样式都符合您的意图,而不是浏览器的意图。这个例子包含了比您将要用来实现WorrySome.net更广泛的元素,使您能够处理将来可能需要的任何元素。

/*  =reset.css */
body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, form,
  fieldset, input, p, blockquote, address, th, td {
margin : 0; padding :0; }

h2, h3, h4, h5, h6 {
font-size : 100%;
font-weight : normal; }

ol, ul {
list-style-type : none; }

table {
border-collapse : collapse;
border-spacing : 0; }

caption, th {
text-align : left; }
fieldset, img { border : 0; }

dt, address, caption, cite, code, dfn, em, i, strong, b, th, var {
font-style : normal;
font-weight : normal; }

q:before, q:after { content :''; }

除了这个 reset CSS,我还建议你在常用的文本元素上指定marginpadding

/* =blocktext */
h2, h3, h4, h5, p, ul {
margin : 0 20px;
padding : .5em 0; }

造型WorrySome.net

许多网页设计者采用一种粒度方法来使用 CSS 实现他们的设计,而你将采用一种由外向内的方法,首先关注设计的外部元素,然后再处理细节。您将从应用设置布局结构的样式开始,从包含所有内容的htmlbodycontainer部分开始。

应用于根元素htmlbackground-colorbackground-image和字体color将使球滚动。一个细长的background-image将水平重复(repeat-x)来创建网站的条纹背景。

html {
background : #f7d8e8 url(img/html.png) repeat-x;
color : #333; }

注意

我选择的许多图像文件名都与它们所设计的元素密切相关。这种方法有助于节省时间,并减少几个月后返回网站时的混乱,或者当许多设计人员或开发人员在一起工作时。

接下来,您应该对body元素应用样式。这种设计将是固定宽度的,并在浏览器窗口中居中。

body {
position : relative;
width : 740px;
margin : 20px auto 0 auto;
padding-top : 10px;
background : url(img/body.png) repeat-y;
font : 88%/1.5 Calibri, Trebuchet, "Trebuchet MS", Helvetica, Arial, sans-serif; }

您可能想知道为什么position : relative;应该应用于body元素。毕竟,body不太可能被定位或偏离其自然位置。这个设计中的很多视觉元素都是绝对定位在页面上的。将position : relative;应用到body元素会将它建立为其任何定位后代的定位上下文。

接下来,轮到外container师了。同样,该元素已经被建立为其后代的定位上下文,并位于body的中心,以允许该元素的background-image为页面深度创建微妙的投影。

div[id="container"] {
width : 700px;
margin : 0 auto; }

注意

如果您不熟悉示例中的选择器,请不要担心。这是一个属性选择器,由于在 Internet Explorer 6 中缺乏对它的支持,web 设计人员和开发人员很大程度上避免使用这种类型。

属性选择器由三部分组成:

  • 您正在选择的元素(本例中为 div)

  • 用于选择特定元素的属性(本例中为 id)

  • 属性的值(本例中为容器)

您可以使用 div#container 或者甚至#container 来选择相同的元素,但是那样就没那么有趣了,不是吗?

造型基础页面分部

有了外部区域,您可以将注意力转向定义此设计的品牌、导航和内容区域。对于每一个,您将应用基本的样式,包括框和背景属性。从顶部的品牌区域开始。

div[id="branding"] {
height : 200px;
margin-bottom : 10px;
background : #f0a4c7 url(img/branding.png) repeat-x; }

这可以跟随主导航的外部划分。

div[id="nav_main"] {
background : #fedaeb url(img/nav_main.png) repeat-y; }

最后,将样式应用于其余的主要部分:

div[id="content"] {
margin-bottom : 80px; }

div[id="content_main"], div[id="content_sub"] {
width: 100%;  }

div[id="siteinfo"] {
clear : both;
min-height : 120px;
padding: .5em 0;
background : url(img/siteinfo.png) repeat-x;  }

通过在您的开发浏览器中加载页面,查看您的设计是如何完成的(参见图 4-3 )。对于如此少的努力来说,表现还不算太差,但你仍然只是第 40 名的新人,你还有一段路要走,才能登上排行榜的榜首。不用担心;这不会像你想象的那么难。

Styling the basic page divs, html, and body to create the canvas on which to create the WorrySome.net design

图 4.3。样式化基本页面 divs、html 和 body 来创建画布,在画布上创建WorrySome.net设计

制作栏目

我想是史蒂夫·克鲁格在他的书《不要让我思考》中建议莱昂纳多·达芬奇发明了标签。我不确定是谁发明了柱子。也许是纳尔逊勋爵,但我跑题了。

WorrySome.net的主页将它的三个主要内容区域分成几列,每一列都包含对该服务的不同解释,顶部是不同颜色的圆形图像。您的下一个任务是使用 floats 创建三个列。

以下规则将适用于所有三列。它将每个浮动到左边,并给它们一个最小的高度、宽度和边距;少量底部填充;和一个位于分区底部的background-image

div[id="worriers"], div[id="worries"], div[id="worrydone"] {
float : left;
min-height : 42em;
width : 220px;
margin-right : 20px;
padding-bottom : 1em;
background : url(img/worryone-b.png) no-repeat 0 100%; }

现在您可以选择将出现在最右边的worrydone部分,并移除它的右边距,将其放在容器的最外边。

div[id="worrydone"] {
margin-right : 0; }

Styling the basic page divs, html, and body to create the canvas on which to create the WorrySome.net design

您的列制作考察的最终结果显示在图 4-4 中。

Floating the divisions to make three columns worthy of Trafalgar Square

图 4.4。浮动师团让三个纵队配得上特拉法尔加广场

接下来,您将向这三列中的每一列添加单独的样式,从标题开始向下。您将使用流行的 Phark 负文本缩进技术(如第二章,“用 CSS、Flash 和 JavaScript 驯服野生 CMS 参见http://phark.net。该方法对每个标题应用一个background-image,并通过缩进大量像素将文本从浏览器窗口的左侧移开。

第一条规则适用于所有三个标题。

div[id="worriers"] h2,
div[id="worries"] h2,
div[id="worrydone"] h2 {
min-height : 50px;
margin : 0;
text-indent : 9999px; }

这应该遵循给每个标题添加一个唯一的background-image的规则,如图 4-5 中的所示。

div[id="worriers"] h2 {
background : url(img/worryone-t.png) no-repeat 0 0; }

div[id="worries"] h2 {
background : url(img/worrytwo-t.png) no-repeat 0 0; }

div[id="worrydone"] h2 {
background : url(img/worrythree-t.png) no-repeat 0 0; }

Using image replacement to style the headings

图 4.5。使用图像替换来设计标题样式

介绍性文字的每一段都将使用不同颜色的背景图像和更大的字体,如图图 4-6 所示。同样,第一条规则是所有三个段落共有的。

div[id="worriers"] h2 + p,
div[id="worries"] h2 + p,
div[id="worrydone"] h2 + p {
min-height : 4em;
margin : 0;
padding : 5px 20px 40px 20px;
font-size : 120%;
line-height : 1;
color : #fff; }

div[id="worriers"] h2 + p {
background : #cc6195 url(img/worryone-m.png) no-repeat 0 100%; }

div[id="worries"] h2 + p {
background : #dd82ae url(img/worrytwo-m.png) no-repeat 0 100%; }

div[id="worrydone"] h2 + p {
background : #f0a4c7 url(img/worrythree-m.png) no-repeat 0
100%; }

Distinctly different syling for the three introductory paragraphs

图 4.6。三个介绍性段落的顺序明显不同

注意

等等,这些选择器里的+号是干什么的?这个符号被称为兄弟组合子,并形成一个相邻的兄弟选择器。这种类型的选择器根据其前面的元素选择一个元素;在这种情况下,紧接着 h2 的是 p 元素。Web 设计人员和开发人员在很大程度上避免了这种类型的选择器,因为在 Internet Explorer 之前的版本中缺乏对它的支持。

你的专栏正在成形。最后,你可以整理肖像和烦恼者名字周围的空间,将文字居中并缩小字体大小,如图图 4-7 所示。

div[id="worriers"] img,
div[id="worries"] img,
div[id="worrydone"] img {
margin-left : 15px; }

img + p {
padding-top : 0;
font-size : 92%;
text-align : center; }

Getting down to details using attribute and adjacent selectors

图 4.7。使用属性和相邻选择器深入细节

虽然浮动和图像替换在您的脑海中还记忆犹新,但是让我们来看看令人担忧的主题列表及其标题。再次使用 Phark 方法替换标题文本。

div[id="content_sub"] h4 {
height : 35px;
width : 300px;
padding : 0;
background : url(img/h4.png) no-repeat;
text-indent : 9999px; }

该网站的专家团队可以代表您担心的主题列表将被转换为三栏式设计。您可以通过浮动每个列表项并使用一个background-image来提供一个装饰性的项目符号来完成这个效果。

div[id="content_sub"] ul {
float : left;
padding-bottom : 80px; }

div[id="content_sub"] li {
display : block;
float : left;
width : 190px;
padding-left : 20px;
background : url(img/li.png) no-repeat 0 50%; }

结果如图 4-8 所示。

Floating list items: an effective way of creating column designs with simple lists

图 4.8。浮动列表项目:用简单列表创建列设计的有效方法

样式页脚

页脚有时可能是设计中被忽略的部分。通常,他们最简单的处理会让你的视线离开页面底部。

页脚有一个较小版本的主标志和一个非常有用的顶部链接,这样网站的访问者就不用担心滚动到页面顶部会喘不过气来。

首先,开始设计页脚中的一小段文本。将其内容转换为大写字母,并减小其字体大小和对比度以降低其重要性。

div[id="siteinfo"] p {
padding-top : 40px;
font-size : 82%;
text-transform : uppercase;
color : #999;  }

div[id="siteinfo"] p a {
display : block; }

注意

如果你能更具体地说明你的目标锚,也许通过设计不同于你网站上其他页面的外部链接,这不是很好吗?现在,在很多情况下你可以。除了 Internet Explorer 7 之外,所有支持标准的主流浏览器都支持如下选择器:

div[id="siteinfo"] a[href^="http"] {
      display : block; }

带有^的选择器是一种子串匹配属性选择器,有点拗口,但却是 CSS 中最有趣的选择器类型之一。从现在开始,我将引用 tas 子串选择器,以节省墨水和树。

这种类型的选择器有不同的种类,其中许多可以使完成这种设计更加容易。此处的示例针对 siteinfo 部分中包含的所有链接,其中 href 以 http 开头。随着本章的深入,您将看到更多的子串选择器。

现在是时候将注意力转向添加小的WorrySome.net标志了。查看该页面的标记可以发现,这里没有内嵌的徽标图像。在一个无序列表中,只有到页面顶部的链接。从删除列表中的所有边距开始。

div[id="siteinfo"] ul {
margin : 0; }

现在,您可以使用定位和图像替换的组合,将这个不起眼的链接转换为闪亮的徽标。首先,设置它的比例并绝对定位它:左边 240 像素,上面 50 像素。

div[id="siteinfo"] ul a {
position : absolute;
display : block;
top : 50px;
left: 240px;
height : 120px;
width : 230px; }

应用一个背景图像,将它的文本滑动到屏幕之外,你就可以开始了。

div[id="siteinfo"] ul a {
background : url(img/a-t.png) no-repeat;
text-indent : 9999px; }

好吧,也许你还没有完成。在您的浏览器中预览结果,您将会看到徽标并没有像您预期的那样正好位于页脚上方。相反,它被定位在body元素之上 50px,因为这是它最近的定位祖先,如图 4-9 的顶部所示。

你可以很容易地补救这一点。通过应用position : relative;但不应用偏移,使站点信息部分本身成为定位上下文。

div[id="siteinfo"] {
position : relative; }

Correcting the position of the footer logo. Call me old-fashioned, but I think it looks better at the bottom.

图 4.9。更正页脚徽标的位置。你可以说我老土,但我认为它在底部更好看。

设计主导航

理解子字符串选择器的功能和灵活性非常重要,因为您将在设计该页面的主导航时更多地使用它们。同样,您将使用一系列不同的技术,包括定位和图像替换。主导航将如图 4-10 所示。

The finished look of the main navigation

图 4.10。主导航的最终外观

但是如何实现这一点呢?您的第一个简单任务是从视图中删除标题,这一次是将它放置在浏览器窗口的顶部边缘。

div[id="nav_main"] h4 {
position : absolute; top : 9999px; }

现在标题被取消了,除了浏览没有样式的页面的人,您可以设置无序导航列表的比例,并添加包含所有三个按钮图形的背景图像。

div[id="nav_main"] ul {
width : 310px;
height : 38px;
margin-left : 200px;
padding : 0;
background : url(img/li_nav_main.png) no-repeat; }

该列表中的导航链接将通过定位三个锚点来完成。接下来,建立这个无序列表作为定位上下文,并将所有列表项设置为内联显示,而不是块级元素。

div[id="nav_main"] ul {
position : relative; }

div[id="nav_main"] li {
display : inline; }

position : relative;应用于列表以建立定位上下文,现在为所有三个锚点设置一个通用规则。

div[id="nav_main"] a {
position : absolute;
top : 0;
display : block;
height : 38px;
width : 104px;
text-indent : 9999px; }

根据锚的title属性,这将遵循针对单个锚的特定规则。这些title属性为每个链接添加了一个可视化的工具提示,并允许您定位它们的锚点。

a[title="Subscribe"] {
left : 0; }

a[title="Worrylist"] {
left : 104px; }

a[title="Worrycart"] {
left : 208px; }

注意

您已经在前面的选择器示例中遇到了^符号,并了解到它针对的是以特定值开头的属性。相比之下,$符号针对的是以特定值结尾的属性。

<a href="#" title="Worries in your Worrycart">Worrycart</a>
  a[title$="worrycart"] {
   left : 208px; }

在浏览器中预览完成的结果。为了说明锚点的位置,我给图 4-11 中的每个锚点添加了一个红色边框(使用 Firefox 的 Web Developer 工具栏的轮廓功能)。

Showing the finished result, with anchors outlined for emphasis

图 4.11。显示完成的结果,并突出显示锚点

品牌设计

我希望,尽管有了所有的新技术和选择器,你的头脑没有烦恼。页面上还有一个区域需要你去处理,这是我在所有网站设计中最喜欢的部分:品牌。

此时,您已经使用了所有的选择器技术和类型,将品牌区域的顶级标题和 Marley 的“三只小鸟”的摘录转换为有吸引力和有意义的视觉元素。

由于这些元素将被定位为创造标志“打破常规”的视觉效果,因此首先要将品牌部门转变为这些元素的定位环境。

div[id="branding"] {
position : relative; }

现在你已经准备好放置顶层标题和blockquote。使用 Phark 图像替换方法将文本替换为background-image

h1 {
z-index : 1;
position : absolute;
left : 50px;
top : 30px;
height : 178px;
width : 379px;
background : url(img/h1.png) no-repeat;
text-indent : 9999px; }

div[id="branding"] blockquote {
z-index : 2;
position : absolute;
left : 225px;
top : 85px;
height : 103px;
width : 198px;
background : url(img/blockquote.png) no-repeat;
text-indent : 9999px; }

注意

为了确保醒目的块引用始终位于其相邻标题的前面,块引用被赋予了更高的 z 索引。关于 z-index 的创造性灵活性的更详细的解释,请阅读我在http://24ways.org/advent/zs-not-dead-baby-zs-not-dead的 24ways 文章。

Showing the finished result, with anchors outlined for emphasis

这样做的结果是,你引人注目的网站口号变成了更有吸引力的东西,如图 4-12 所示。

Positioning and z-index combine to create the branding of the site with few worries.

图 4.12。定位和z-index相结合,创建网站的品牌,没有什么顾虑。

对无障碍的家伙微笑

你的工作几乎完成了,但是WorrySome.net品牌的一个重要方面仍然缺失:黄色笑脸。如果您向后翻页查看该页面的标记,您会看到每个元素和属性都被使用了;没有任何东西被浪费。除了保存方便的跳转链接的无序列表之外,什么都没有。

不用担心;这个元素很快就会对你有用。许多 web 设计人员和开发人员选择隐藏这些嵌入式辅助功能,通常将它们推到屏幕之外,看不到。您将使用此元素,通过附加笑脸background-image来赋予品牌区域以生命。

ul[id="nav_access"] {
position : absolute;
top : 33px;
right : 50px;
height : 291px;
width : 340px;
margin : 0;
padding : 0;
background : url(img/a-access.png) no-repeat;
text-indent : 9999px; }

在你的浏览器中预览商标区所有的笑脸,你会发现这张脸并没有对你微笑。CSS 缺少了一个重要的部分,以及一个重要的教训。除非您为任何定位的元素指定了一个z-index值,否则那些在文档顺序中跟随它的元素将始终位于顶部。它们越靠近结束的</body>标签,它们在堆叠顺序中的位置就越高。

可访问性列表出现在文档的最开始,因此在堆叠顺序中,它位于所有其他定位的元素之后。你可以纠正这一点,通过给笑脸一个明确的z-index来恢复它的快乐,这将确保它在设计中占据应有的位置,如图 4-13 所示。

ul[id="nav_access"] {
z-index  : 2; }

Smile, hidden tools to help visitors with special needs can also be used as hooks for visual design elements.

图 4.13。微笑,帮助有特殊需求的访客的隐藏工具也可以作为视觉设计元素的挂钩。

我们会让你再看看最终的设计(图 4-1 ),看看它的辉煌:

Smile, hidden tools to help visitors with special needs can also be used as hooks for visual design elements.

处理传统浏览器

尽管已经有很多关于 CSS 的书,但是很少有人涉及到被认为是高级选择器的实际应用。一个原因是网络上最常用的浏览器,Windows 的 Internet Explorer,不支持这些选择器。Web 设计人员和开发人员避免使用这些选择器,或者他们集中精力限制他们的设计,以便页面在不同年龄或功能的浏览器上显示相同。

如果网页设计要进步,就必须找到新的方法。并不是你在本章中使用的所有技术在所有浏览器中都是一样的。不用担心;这是故意的。

在许多工作环境中,web 设计人员和开发人员必须处理浏览器的功能,这些功能仍在日常使用中,但也远远超出了最佳使用日期。不幸的是,这一群乌合之众的老浏览器包括 Windows 版的 Internet Explorer 6。幸运的是,有一个 solutionone 可以让你完全采用开发WorrySome.net时一直在使用的技术和选择器。

狄恩·爱德华兹的 IE7 脚本(http://dean.edwards.name/IE7/)使用 JavaScript 将样式表解析成 Internet Explorer 6 和更早版本可以理解的形式。它们使您能够在样式表中使用 CSS2 甚至一些 CSS3 选择器,并将 Internet Explorer 的旧版本转换成一个无忧的新浏览器,该浏览器能够理解以下内容:

  • 子选择器

  • 相邻兄弟选择器

  • 属性值选择器

  • :first-child:last-child:only-child:nth-child结构伪类

  • :before:after生成的内容

注意

狄恩·爱德华兹的 IE7 脚本可能不适合在所有情况下使用。这不是企业级解决方案,也不适合高流量网站。

随着越来越多的人将浏览器升级到 Internet Explorer 7,随着其对 CSS2.1 的支持增加,Internet Explorer 6 的用户数量将会减少。这使得 Edwards 的解决方案成为中低流量网站的设计者和开发者的有用选择,他们的目标是在更广泛的浏览器中安全地使用所谓的高级技术。

微软建议设计者和开发者停止使用 CSS hacks,转而使用微软专有的条件注释。这些注释仅受 Internet Explorer for Windows 支持,通过将注释放在文档的<head>部分,可以很容易地定位 Internet Explorer 的版本。

条件注释最常见的用途是提供特定的样式表,以解决旧版 Internet Explorer 中的错误和呈现错误。它们可以很容易地用于为需要它们的浏览器提供狄恩·爱德华兹的 IE7 脚本。例如,此注释将只为版本 7 之前的 Internet Explorer 版本提供脚本。

<!--[if lte IE 7]>
<script src="js/ie7-standard-p.js" type="text/javascript"></script>
<![endif]-->
</head>

没关系!

在这一章中,你已经了解到,当使用以前被认为是先进的 CSS 来创建一个打破常规的设计布局时,没有什么可担心的。现代的 CSS2.1 选择器、浮动和定位是用最少的非表示性标记创建引人入胜的网站设计的完美工具。

您已经看到了如何在精通 CSS 的 web 浏览器中将这些工具和技术付诸实现,以及如何使用巧妙的脚本来填补旧的、更糟糕的浏览器中的漏洞。我期待着看到你将如何利用你所学到的东西。

我的西装熨好了,我的皮鞋擦得锃亮了,摩登女郎们正在布赖顿大街上行进。是时候让你在剩下的章节里见到“王牌面孔”了。