衬氟截止阀dgfmjt:使用开源软件设计、开发和部署协作型 Web 站点,第 8 部分: 使用 CSS 对主题化内...

来源:百度文库 编辑:九乡新闻网 时间:2024/05/16 18:01:27
 

文档选项

将此页作为电子邮件发送

讨论


级别: 中级

Alister Lewis-Bowen (alister@us.ibm.com), 高级软件工程师, IBM
Stephen Evanchik (evanchik@us.ibm.com), 软件工程师, IBM
Louis Weitzman (louisw@us.ibm.com), 高级软件工程师, IBM

2007 年 5 月 24 日

在这个 系列 中,在 IBM? Internet Technology Group 团队的带领下使用一套可免费获得的软件为虚构的 International Business Council 公司设计、开发和部署一个外部网 Web 站点。在 第 7 部分 中,学习了为这个新 Web 站点的内容建立结构的方法。本文继续进行主题化,关注的重点从结构转移到使用层叠样式表(CSS)对 XHTML 应用样式。

简介

在这个 文章系列 中,Internet Technology Group 团队描述了如何为虚构的 International Business Council(IBC)公司创建一个定制的 Web 站点。这个站点需要文档存储、讨论组、专门的工作组、研讨会日程安排、日程议题描述等功能。

第 7 部分 中,学习了如何创建新的主题,以及在主题中为 Web 站点构造结构化 XHTML。本文继续进行主题化,关注的重点从结构转移到使用层叠样式表(CSS)对 XHTML 应用样式。

Drupal 允许主题设计人员使用 CSS 修改 XHTML 内容的表示方式。CSS 中的样式适用于所有 Web 站点,而不是专门用于 Drupal 的,但它是创建有用且符合期望的 Web 站点所需要的。因此,本文主要关注在进行 CSS 样式化时的常用实践。我们将总结对 IBC Web 站点进行样式化所用的一些技术。您将学习以下方法:

  • 设计可维护的 CSS 结构。
  • 提供成比例的页面布局。
  • 标识 Web 站点部分并提供视觉标志。
  • 创建 CSS 驱动的下拉菜单。
  • 启用用户可切换的布局。
  • 提供打印样式。

正如前面文章所解释的,Drupal 主题系统使我们能够将结构和表示方式与程序逻辑分隔开。我们还尽可能将 Web 内容的表示与内容结构分隔开。我们已经建立了良好的模板,它们使用 XHTML 为内容建立结构,所以现在可以使用 CSS 对内容应用样式。

本系列中的信息不应该解释为严格的开发规则,而是应该作为对 Web 站点应用样式时的起点。

兼容性

对 Web 站点应用样式是一项需要耐心和果断的工作。如果 XHTML 结构是良好的,您的工作就会轻松得多。但是,主题设计人员深知尝试使 CSS 跨不同浏览器、浏览器版本和平台工作时可能会遇到的挫折。

尽管越来越容易了,但是向后兼容性仍然依赖于客户的期望和用户的需要。一定要了解这些需求并明确地定义它们。对于 IBC 站点,我们面对的用户具有比较高的技术水平,他们中的大多数人使用最新的浏览器。通过对内容结构使用语义标记,我们生成的 Web 页面在老式浏览器上具有合理的布局,甚至在样式不可用时也是合理的。图 1 对比了在有样式和无样式的情况下 IBC 主页的显示。


图 1. 有样式和无样式的主页

在没有样式时,元素的显示方式是上下依次排列的,这使它占据更多的垂直空间。但是,语义结构仍然是完整的。另外,原本隐藏的一些内容显示了出来,这帮助访问者识别内容的某些部分,其中包括一个直接跳到页面中主内容开头的链接。这是为提供可访问性所使用的典型结构化技术(参见 第 7 部分)。

对于在不同的环境中实现相似的表示方式,有许多解决方案,或者说 hack。我们不打算使用这些方法。相反,我们愿意接受内容在不同浏览器或平台上显示方式略有不同的情况。只要内容仍然是可读的、能够发挥功能而且在布局中具有语义上的正确性,我们就接受这些差异。





回页首

CSS 文件的组织

第 7 部分 中,我们通过复制 Drupal 发布版附带的 Bluemarine 主题,在 themes 目录下面创建了一个新的主题目录。为了组织这个目录,我们决定在这个主题目录下创建一个 c 目录,用来包含我们的所有样式。还创建了 i 和 j 目录,分别包含这个主题专用的图像和 JavaScript 文件。

还可以在模块的 hook_init 函数或主题的 templates.php 中使用 theme_add_styles 函数,告诉 Drupal 您希望将哪个样式表添加到主题中。可以使用这个函数添加样式表的路径以及相关联的媒体类型。它在模板中作为 phptemplate 引擎传递的 $styles 变量中的一组 LINK 元素出现。我们不采用这种方法,而是将自己的 LINK 元素硬编码在 page.tpl.php 文件中。这种方法可能更适合您的主题设计人员,因为他们可以从页面模板文件直接控制对样式表的使用。

在默认情况下,Drupal 会通过 misc 目录中的 styles.css 文件应用样式。但是,我们不希望将所有样式都放在一个大样式表中,而是要定义多个样式表并将它们与特定的样式化任务关联起来。我们并不在 page.tpl.php 模板的 HEAD 部分中为每个样式表建立一个 LINK 元素,而是创建一个包含它们的样式表,在其中可以包含所有与任务相关的样式表文件。清单 1 显示 screen.css 文件的内容,我们使用这个文件定义主屏幕媒体相关样式。


清单 1. screen.css 文件中包含的样式表
                                    @import url("base.css");                                    @import url("form.css");                                    @import url("layout.css");                                    @import url("banner.css");                                    @import url("nav_bar.css");                                    @import url("side_bar.css");                                    @import url("login.css");                                    @import url("home.css");                                    @import url("workgroups.css");                                    @import url("conferences.css");                                    @import url("members.css");                                    @import url("announcements.css");                                    @import url("action_items.css");                                    @import url("agenda_items.css");                                    @import url("search.css");                                    @import url("discussions.css");                                    @import url("comments.css");                                    @import url("filegallery.css");                                    @import url("companies.css");                                    

这个文件中包含几个样式表,其中包括 XHTML 元素选择器的基本样式集、表单样式、页面布局、布局的主要区域(广告条、导航、边栏)和 Web 站点的主要部分。

对于一个请求只传输一个大样式表文件的速度比较快,而使用一套样式表的可维护性比较好,而且寻找特定样式也比较容易,需要在这两种方式之间进行折中。因为我们的样式表很小,下载速度很快,而一旦完成缓存,使用起来也会很快。根据您需要创建的样式数量以及主题设计人员的工作习惯,使用更少但更大的样式表文件可能更合适。

这种组织方法有一个问题:如果用户将 Web 页面保存到自己的计算机上,然后在断开网络连接的情况下查看页面。screen.css 文件中包含的样式表不会被保存,所以当用户离线查看页面时,内容上不会应用样式。解决这个问题的一种方法是建立一个后期处理脚本,它解析 screen.css 文件并将所有引用的样式表包含进 screen.css。

改进样式表的可搜索性的另一种方法是使用标志 来帮助我们搜索文件中的注释。清单 2 给出一个在部分的注释中使用等号的示例。这种方法是 Doug Bowman 提出的(参见 参考资料)。因为 CSS 语法中不使用等号,所以通过搜索等号,可以快速地找到样式部分的开头。

另一个有用的方法是按照字母表次序排列所有样式。这种技术在搜索样式时提供了一定程度的一致性。


清单 2. CSS 文件中的可搜索注释
                                    /* -----------------------------------------------------------------                                    *=announcement_summary                                    * -----------------------------------------------------------------                                    */                                    .announcement_summary {                                    margin: 0 0 .8em 0;                                    }                                    .announcement_summary h3 a {                                    font-size: 90%;                                    }                                    

浏览器会对 XHTML 应用默认样式,这可能会给主题设计人员造成混乱。对于我们要使用的所有 XHTML 元素选择器,将空白边和补白设置为零,从而防止浏览器应用默认样式,见 清单 3。现在,这些元素的样式的可预测性就加强了。另一种对所有元素应用零空白边和补白的方法是使用 * 选择器。但是,我们希望能够控制影响哪些元素。

Eric Mayer 的 Web 站点详细介绍了浏览器默认样式的效果(参见 参考资料。)


清单 3. 为要使用的选择器设置空白边和补白样式
                                    p, ul, li, ol, dl, dt, dd, h1, h2, h3, h4,                                    form, fieldset, blockquote, table, th, tr, td {                                    margin: 0;                                    padding: 0;                                    }                                    





回页首

用于提高可访问性的样式

第 7 部分 描述了我们在内容结构中使用的一些可访问性技术。在本节中,您将看到我们如何使用 CSS 提高可访问性。当然,可访问性设计涉及许多方面的问题。一些是标准设计问题,比如颜色要形成足够的对比度、在版面中提供足够的指引信息以及在内容的逻辑区域周围安排足够的空白。这些设计实践超出了本文的范围。我们关注主要区域的样式化,以便满足 IBC Web 站点的可访问性需求。

成比例的大小改变

成比例的大小改变(proportional sizing) 指的是,对于容器大小、文本域的长度、字体大小等,尽可能使用百分数和 em 单位。这种方法可以创建出流式布局,在这种布局中字体会随着布局成比例地改变大小。另一个要考虑的问题是,需要以某种方式对图像应用样式,让它们能够在流式布局中有效地工作。

灵活的字体
现代的浏览器能够改变 Web 页面的默认字体大小。这非常有用,用户可以减小字体大小以便在浏览器窗口中看到更多的内容,或者增加字体大小以使 Web 页面更容易辨认。图 2图 3 显示了 IBC 站点在使用小号字体和大号字体时的布局变化。


图 2. 减小字体大小后的布局


图 3. 增加字体大小后的布局

效果并不完美,但是在字体大小显著改变时显示效果还算不错。一种常用的实现技术是,设置一个初始字体大小,然后在样式表中对任何其他字体大小使用百分数。

清单 4 所示,我们在基本样式表(base.css)的顶部定义了样式,包括字体大小。


清单 4. 为 body 选择器设置初始字体样式
                                    body {                                    background: #fff;                                    color: #333;                                    font-family: Verdana, sans-serif;                                    font-size: small;                                    line-height: 1.5em;                                    margin: 0;                                    padding: 0;                                    }                                    

对于以后对字体大小的任何修改,我们都使用百分数。因此,如果用户改变了浏览器的默认字体大小,所有文字都会保持比例。例如,清单 5 显示我们如何设置边栏容器的字体大小。


清单 5. layout.css 中边栏容器的样式
                                    #sidebar {                                    background: transparent url(/themes/ibc/i/bg_sidebar_right.gif) no-repeat top right;                                    float: right;                                    font-size: 80%;                                    line-height: 1.4em;                                    width: 30%;                                    }                                    

所以,边栏中的字体大小现在是初始大小 small 的 80%。但是,在将百分数应用于子选择器的样式时,要记住单位是累积的。例如,如果将这个边栏中一个内容区域的字体大小设置为 90%,那么字体大小会是初始设置的大小的 80% 的 90%。在 Document Object Model(DOM)中使用嵌套更深的此类百分数,效果会更差。

流式布局
IBC Web 站点上的某些内容可能相当宽,所以我们希望尽可能利用浏览器窗口的宽度。我们决定采用流式布局而不是固定宽度的布局。图 4图 5 显示了布局如何随着浏览器窗口的大小而变化。


图 4. 窄浏览器窗口中的布局


图 5. 宽浏览器窗口中的布局

这意味着,我们要在主要布局容器宽度上使用百分数,比如主内容区域和边栏。在 清单 5 中的边栏样式中,宽度设置为 30%。在 清单 6 中,主内容容器使用略小于 70% 的宽度,这是为了适应 Microsoft? Internet Explorer 的 盒模型宽度实现


清单 6. layout.css 中的主内容容器样式
                                    #content {                                    clear: both;                                    float: left;                                    width: 67%;                                    }                                    

有许多种技术可以创建流式的多栏布局。我们选择让两个容器分别向左右浮动。我们提供适当的最小宽度和最大宽度,以限制设计中使用的图像的大小。在 清单 7 中可以看到 layout.css 文件中使用的样式。样式所针对的 wrap 容器见本系列 第 7 部分 中的图 1。您应该知道,max-widthmin-width 样式的实现在浏览器之间并不一致。因为我们选择让边栏浮动,所以当浏览器窗口的宽度太窄时,边栏会出现在主内容区域下面。


清单 7. 在 layout.css 中限制宽度
                                    #wrap {                                    max-width: 1600px;                                    min-width: 750px;                                    }                                    

我们还对一些元素应用成比例大小改变,比如 BUTTON 或 submit 类型的 INPUT 元素。对于这些元素,我们在 marginpaddingwidth 等样式中使用 em 单位而不是百分数。清单 8 显示我们如何对 submit 类型的 INPUT 元素应用样式。


清单 8. forms.css 中 submit 类型的 INPUT(form-submit)的样式
                                    input.form-submit {                                    background: #fff url(/themes/ibc/i/bg_btn.gif) repeat-x bottom left;                                    border: 1px solid #ccc;                                    border-bottom-color: #999;                                    border-right-color: #999;                                    cursor: pointer;                                    font-size: 79%;                                    margin: 1em 0 0 0;                                    padding: 0.25em;                                    text-align: center;                                    width: 6em;                                    }                                    

图 2 显示一个改变尺寸的表单元素的示例。当字体大小增加时,页面顶部的搜索表单中使用的文本域会变宽。

在许多情况下,需要用 DIVSPAN 容器包围一个表单组件,以便从 CSS 样式表访问它。Drupal forms API 允许使用 #prefix#suffix 数组元素在为每个表单组件生成的 XHTML 之前和之后定义内容。(见 第 6 部分 的清单 11 中的示例。)

对流式布局中的图像应用样式
图 2图 3图 4图 5 所示,字体大小和浏览器窗口宽度的改变会对页面上的可视元素产生显著影响。在容器的背景中使用单色(比如导航条中的黑色背景)可以在某种程度上缓解这个问题。当字体大小增加时,导航条的高度会随着增加。在这个容器上应用黑色背景就意味着我们不必担心了。同样,我们对边框的尺寸使用百分数或 em 单位。

另一种常用技术是沿水平或垂直方向在元素的背景中重复显示图像。这样的话,如果图像的边缘与定义的背景颜色融为一体,那么就能够适应任何大小变化。图 6 显示图像如何在 BUTTON 或 submit 类型的 INPUT 元素中创建渐变效果,从而适应增加字体大小所产生的空间。


图 6. 背景样式效果保持一致

图 7 显示 清单 8 中的样式如何在按钮中创建这种灵活的背景图像。


图 7. 图 6 中按钮的构造过程

submit 类型的 INPUT 元素的背景颜色设置为白色。在背景中使用一个图像提供到白色的逐变。这个图像宽 1 像素,并定位在容器的左下角。通过使用 repeat-x 属性,这个图像水平重复显示,填满容器。如果容器的大小改变了,背景图像会适应这种情况,从而创建我们需要的效果。

对于需要沿水平或垂直方向扩展或收缩的简单渐变,这种技术是有效的。但是对于更复杂的图像,比如边栏的背景,我们有意地使用比默认显示区域大的图像并适当地进行定位。当布局扩展时,图像的可视部分将总是可见的。Doug Bowman 的滑动门技术使这种技术更加流行。(参见 参考资料。)图 8 显示边栏背景的宽度如何随着浏览器窗口由窄变宽。


图 8. 窄窗口和宽窗口中的边栏

创建这种效果的方法是将一个容器放在另一个容器中,并给它们分别设置背景。一个背景形成右上角,另一个形成左上角。因为外边的 DIV 元素限制了边栏的尺寸,而内部的 DIV 会扩展到它的父元素的整个空间,所以这两个图像会精确地重叠。一个图像非常宽,会被外边的 DIV 裁剪,如 图 9 所示。


图 9. 创建边栏背景所用的背景图像

边栏的结构见 清单 9。外边的 DIV 元素的 ID 属性值为 sidebar,这个元素包含的内部 DIV 具有 class 属性值 gutter。在其中显示 $sidebar_right 区域变量的内容。


清单 9. page.tpl.php 中的边栏结构
                                                                        

清单 10 显示如何对这两个 DIV 容器应用样式。形成背景右上角的宽图像定位在 sidebar 容器的右上角。形成背景左上角的小图像定位在 gutter 容器的左上角。如果边栏的宽度增加了,两个背景图像就会相互错开(因此称为 “滑动门”),更多地露出下面的图像,如 图 9 所示。这看起来就像是背景图像扩大到整个区域。这就是许多技术使用的多层背景图像的基本概念。


清单 10. layout.css 中的边栏背景样式
                                    #sidebar {                                    background: transparent url(/themes/ibc/i/bg_sidebar_right.gif) no-repeat top right;                                    .                                    .                                    }                                    #sidebar .gutter {                                    background: transparent url(/themes/ibc/i/bg_sidebar_left.gif) no-repeat top left;                                    padding: 10px 20px 0 20px;                                    }                                    

为非传统浏览器提供的额外内容
第 7 部分 中讨论过这个问题。但是,当用户使用传统浏览器查看页面时,我们仍然需要隐藏这些额外的内容,所以对这些容器应用一个 display: none 样式,其 class 值为 access





回页首

部分的样式

第 7 部分 中,您看到了我们如何根据要显示的 Web 站点部分自动地设置 class 值。这提供了一个非常有用的标志,我们可以利用 class 属性根据部分改变 Web 站点的外观。

对于 IBC 站点,我们希望在整个 Web 站点上保持基本布局,以免 IBC 的受众感到迷惑并保持视觉上的一致性。但是,通过使用为品牌设计的主面板,我们可以修改某些可视元素的颜色,从而标识出主要部分。这些元素的一部分包含在 Web 站点的广告条中,如 图 10 所示。为了实现这种效果,我们使用 CSS 改变广告条的背景图像、选择的菜单条目旁边的图标以及底边框的颜色。


图 10. 每个主要 Web 站点部分的广告条

首先,我们使用一种常用技术隐藏 H1 元素,也就是隐藏了广告条中的 Web 站点标题。(见 第 7 部分 中的清单 1。)这样就可以使用背景图像,而在不应用样式时仍然显示文本标题。这对于后面讨论的打印样式很有帮助。清单 11 显示我们隐藏 H1 文本的方法。


清单 11. 在 header.css 中为站点标题提供图像
                                    #banner {                                    background: #ddd url(/themes/ibc/i/bg_header_home.gif) no-repeat top left;                                    height: 100%;                                    overflow: hidden;                                    height: 61px;                                    }                                    #banner h1 {                                    display: none;                                    }                                    

一个默认的背景图像应用于广告条。广告条的尺寸是固定,但是如果搜索表单中的文本大小增加了,高度就会变化,背景图像也会变大以提供另一个滑动门效果。然后将 H1 元素从文档流中完全排除出去,从而隐藏它。隐藏 H1 元素的另一种方法是,使用样式 text-indent: --999em 将它移动到浏览器窗口之外,这样的话文本仍然留在文档流中,但是用户看不见它。

我们以 Workgroups 部分为例。因为我们知道 BODY 元素的 class 属性值会设置为 workgroup,所以可以相应地对广告条元素应用样式。清单 12 显示了如何改变样式来修改这个部分的外观。


清单 12. workgroups.css 中 Workgroup 部分的样式
                                    .workgroups #banner {                                    background: #ddd url(/themes/ibc/i/bg_header_workgroups.gif)                                    no-repeat top left;                                    }                                    .workgroups #nav_bar #pri_nav li#t_workgroups a {                                    background: transparent url(/themes/ibc/i/icon_nav_workgroups.gif)                                    no-repeat center left;                                    color: #fff;                                    font-weight: bold;                                    }                                    .workgroups #nav_bar #pri_nav li#t_workgroups ul li a {                                    background: transparent url(/themes/ibc/i/icon_nav_bullet_workgroups.gif)                                    no-repeat top left;                                    color: #d1d1d1;                                    }                                    .workgroups #nav_bar #pri_nav li#t_workgroups ul li a:hover {                                    color: #fff;                                    }                                    .workgroups #nav_bar, .workgroups #nav_bar #pri_nav li ul {                                    border-bottom: 6px solid #d50304;                                    }                                    .workgroups #footer {                                    border-top: 3px solid #d50304;                                    }                                    

在这段 CSS 中可以看到,大多数样式出现在主导航 UL 元素中,见 第 7 部分 中的清单 7。这些样式修改 nav-bar.css 文件中的默认样式。在上面的 清单 12 中,将广告条的背景改为使用与部分相关的图像。然后,修改工作组列表项锚元素的背景,使效果看上去像是菜单条目前面的符号改变了颜色。为了增强效果,我们修改了这个列表项和其中任何子列表项的颜色和字体粗细。还改变了子列表项的样式,让用来创建符号的背景图像显示为对应的颜色。这是一种相当简单的部分样式。还可以使用 CSS 更充分地修改页面的布局。





回页首

导航

IBC 的主导航是动态的。导航的结构使用锚元素的无序列表。为了实现子菜单,我们嵌入另一级 UL 元素。第 7 部分 中的清单 7 显示了 XHTML。按照这种方法,在不应用样式时,仍然可以保持导航的语义,如 图 11 所示。它还使我们能够使用 CSS 在锚元素的背景中重复显示图像。因此可以轻松地添加新的菜单条目并减少下载时间。


图 11. 不应用样式时的 Web 站点导航

通过 CSS 使用嵌入的 UL 元素创建下拉菜单效果。网上和出版的许多参考资料解释了如何使用 CSS 实现下拉菜单。我们选用基于 Suckerfish Dropdowns 的技术。清单 13 显示应用于第一级 UL 元素的样式。


清单 13. nav-bar.css 中站点导航的第一级无序列表项的样式
                                    #pri_nav {                                    float: left;                                    display: block;                                    list-style: none;                                    margin: 0;                                    padding: 0 1em .5em 1em;                                    }                                    #pri_nav li {                                    float: left;                                    }                                    #pri_nav li#t_home {                                    width: 5.1em;                                    }                                    #pri_nav li#t_workgroups, #pri_nav li#t_workgroups ul li {                                    width: 10em;                                    }                                    #pri_nav li#t_conferences, #pri_nav li#t_conferences ul li {                                    width: 10em;                                    }                                    #pri_nav li#t_members, #pri_nav li#t_members ul li {                                    width: 8em;                                    }                                    #pri_nav li a {                                    background: transparent url(/themes/ibc/i/icon_nav.gif)                                    no-repeat center left;                                    border: 0;                                    color: #d1d1d1;                                    color: #e0e0e0;                                    display: block;                                    float: left;                                    font-family: Arial, Helvetica, sans-serif;                                    margin: 0;                                    padding: 0;                                    text-decoration: none;                                    text-indent: 16px;                                    text-transform: uppercase;                                    }                                    #pri_nav li a:hover {                                    color: #fff;                                    }                                    

前两个样式规则设置 UL 元素,使所有 LI 子元素水平显示,而且前面不显示符号。后四个样式规则设置每个代表站点主要部分的 LI 元素的宽度。它们也确保任何嵌入的下拉列表的宽度相同。图 12 显示以上 CSS 应用于第一级 UL 元素所产生的菜单效果。


图 12. 只对第一级 UL 元素应用样式的导航

第一级列表项目的显示是合适的。但是,嵌入的 UL 元素需要正确地调整,要显示更好的符号图像,而且只当鼠标停留在包含它们的 LI 时出现。清单 14 显示了应用于这些嵌入的 UL 元素的 CSS。


清单 14. nav-bar.css 中站点导航的嵌入无序列表元素的样式
                                    #pri_nav li {                                    position: relative;                                    }                                    #pri_nav li ul {                                    background: #000;                                    border-bottom: 6px solid #666;                                    left: -999em;                                    margin: 0;                                    padding: .7em .1em 0 .5em;                                    position: absolute;                                    top: 1.3em;                                    width: 10em;                                    }                                    #pri_nav li:hover ul, #pri_nav li.over ul {                                    left: 0;                                    }                                    #pri_nav li ul li {                                    float: left;                                    list-style: none;                                    width: 10em;                                    }                                    #pri_nav li ul li a {                                    background: transparent url(/themes/ibc/i/icon_nav_bullet.gif)                                    no-repeat top left;                                    border-top: 1px solid #333;                                    display: block;                                    font-size: 95%;                                    padding-left: 12px;                                    text-indent: 0;                                    text-transform: capitalize;                                    width: 9em;                                    }                                    #pri_nav li ul li a:hover {                                    color: #fff;                                    }                                    

这段 CSS 中比较有意思的部分包含在前三个样式规则中。第一个规则确保可以相对于包含它们的 LI 元素对嵌入的 UL 元素进行定位。第二个样式规则使用 left: -999em; 样式将嵌入的 UL 元素定位到浏览器窗口的外边,使用户看不到它们。我们在这里使用绝对定位,使这些 UL 元素脱离页面流,这样它们的高度就不会添加到包含它们的元素的高度中。如果在这里使用相对定位,就会出现 图 13 所示的情况。这里的最后三个样式规则对齐文本并应用样式,还为代表下拉列表的嵌入元素提供新的背景图像。


图 13. 在 nav-bar.css 中对 #pri_nav li ul 选择器使用相对定位的效果

清单 14 中的第三个样式规则使下拉菜单出现,它将嵌入的 UL 元素从浏览器窗口外边移动回包含它的 LI 元素下面并对齐。

现在,下拉菜单的样式完整了。图 14 显示当鼠标停留在 MEMBERS 链接上时的效果。


图 14. 在完成的下拉菜单上,鼠标停留在链接上的效果

到编写本文时为止,Internet Explorer(IE)在 LI 元素上还不支持 hover 伪类。在 清单 14 中,可以看到选择器 #pri_nav li.over ul。IE 使用 over 类来找到嵌入的 UL 元素。这些类可以以手工方式放进导航 XHTML 中。或者,按照 Suckerfish Dropdown 技术,用 onload 事件触发一小段 JavaScript,这段代码解析 DOM 并在包含的 LI 元素中插入 over 类。





回页首

切换布局

在参与 IBC 的用户之间的通信和协作很重要,而且这个 Web 站点的需求之一是提供查看成员配置文件的不同方式。我们利用选项卡,根据 IBC 成员所属的公司或在 Web 站点上的角色进行查看。我们的用户测试表明,提供每个成员的照片是一项有价值的特性,如 图 15 所示。


图 15. Web 站点成员的照片布局

但是,IBC 站点管理员认为查看更传统的列表视图(如 图 16 所示)更合适,这样可以更快地看到更多的用户信息。


图 16. Web 站点成员的紧凑布局

内容基本上是相同的,但是成员数据的布局很不一样。因为可以使用 CSS 控制这两种布局,所以我们选用一种简单的样式切换技术。

我们已经有了一个样式表 members.css,它处理照片布局的样式。为了创建紧凑布局的样式表,我们在同一目录中复制这个文件,并将它重命名为 members_alt.css。

因为这组替代的成员样式可以与常规样式表组合在一起,我们在同一目录中复制 screen.css,并将它重命名为 screen_alt_members.css。在这个文件中,将 members.css 的包含语句(见 清单 1)替换为 members_alt.css。

为了完成这个过程并向浏览器提供替代样式,我们在 page.tpl.php 中的页面头部分中添加一个新的 LINK 元素。清单 15 显示这个 LINK 元素以及在这两者之间 title 属性的差异。


清单 15. 在 page.tpl.php 中定义替代样式
                                                                                                            

浏览器会发现存在对这个 Web 站点应用样式的替代方式,并允许访问者通过浏览器界面选择这种新的显示方式,如 图 17 所示。


图 17. 通过 Firefox 浏览器界面切换样式

但是,某些浏览器不能识别替代样式;我们仍然需要在成员部分中提供一个可视线索,表明可以切换样式并允许用户激活布局改变。有多种方法可以满足这种需求,但是我们选用的方法基于 Paul Sowden 描述的技术(参见 参考资料。)

在控制成员节点列表的布局的模板中,我们添加了两个链接。如 清单 16 所示,这些锚元素包含 onclick 触发器,它们调用 setActiveStyleSheet JavaScript 函数。


清单 16. 切换样式的链接
                                    Photo layout                                                                        Compact layout                                                                        

这些 JavaScript 代码解析 DOM 中 media 属性值为 screenLINK 元素,并在与 setActiveStyleSheet 函数传递的 title 属性不匹配的 LINK 元素上设置 disable 属性。这一选择存储在 cookie 中,以便保存活动样式表的状态。





回页首

打印媒体的样式

IBC 站点上存储着许多参考资料。我们最初的用户测试表明,许多 IBC 成员喜欢把资料打印出来供离线查看,比如研讨会议程和会议资料。设计 Web 内容的打印版本的样式是很重要的。通过使用打印媒体专用的样式,我们能够在大多数打印设备上创建便于阅读的布局。

下面两个图都是 IBC Web 站点上的研讨会页面,图 18 是 Web 站点上的样式,图 19 是使用打印媒体专用样式表的输出。


图 18. 包含议程的研讨会页面


图 19. 图 18 中 Web 页面的打印形式

在为打印媒体设计样式时,有几个问题。

  • 使用实际打印机进行测试的成本高而且费时间。

     

  • 通常,无法找来许多种打印设备进行测试。

     

  • 需要考虑在单色打印机上进行打印的情况,这种打印机只使用有限的灰色色谱。

     

  • 打印机有时候无法打印出很亮的颜色。高亮显示的信息就会丢失。需要创建显示这些信息的替代方法。

     

  • 大多数打印设备没有像 Web 浏览器那样提供改变字体大小或进行缩放的方法。需要使用一种便于大多数人阅读的基本字体大小。

     

  • 在 Web 页面上有意义的某些信息(比如超链接或表单)在打印的页面上可能没有意义。

     

  • 因为我们的 Web 页面布局是流式的,用户可以改变浏览器窗口的大小来形成更合适的显示方式。标准的打印页面没有提供这种灵活性。

     

  • 标准的打印页面在垂直方向上要换页。需要决定某些内容块(比如边栏信息)应该如何放置在页面上。

     

  • 打印媒体专用的样式在现代浏览器上还没有完全实现。因此,在进行换页(使用 page-break-beforepage-break-insidepage-break-after 样式)等设置时要谨慎。在一种流行的浏览器的某一版本中,使用换页会破坏布局。

 

创建打印媒体样式表

我们在其他样式表所在的目录中创建一个新的样式表,print.css。为了将这个样式表提供给浏览器,我们在 page.tpl.php 模板文件中 清单 15 所示的元素前面添加了另一个 LINK 元素。清单 17 显示这个元素,它将 media 属性值设置为 print,从而表明这个样式表的用途。


清单 17. 在 page.tpl.php 中包含打印媒体专用样式
                                                                        

当然,如果定义了 media 属性值为 all 的 screen.css,并将这个 LINK 放在它后面,打印样式就会继承所有屏幕样式。但是,为了保持更大的控制能力,我们决定不这么做。

对打印机友好的内容

我们以 IBC Announcement 页面为例说明我们如何设计打印样式。图 20 突出显示了 Web 站点标题和公告的实际内容,因为它们已经经过转换,可以适应打印媒体。页面其余部分显示的链接仅仅是隐藏 Web 站点上的信息、提供到这些信息的链接或触发对这些信息的操作,而没有提供其他功能。


图 20. 标题(A)和内容(B)已经经过转换,可以适应打印媒体

语义标记的作用

您可以想像到,对于每种新的媒体类型,都需要对所有东西重新设置样式。但是,如果使用正确的 XHTML 元素为内容提供语义意义,就会获得其他一些好处。图 1 显示了无样式的站点的外观,其中没有广告条、搜索条、可访问性信息、导航和边栏。这为 Web 站点创建了一个非常干净的可打印的布局。正确地使用标记会使内容保持可读性,而且不需要做很多重新样式化工作就可以建立合理的打印媒体输出,从而在大多数打印设备上产生不错的效果。

基本布局

那么,如何开始设计打印样式呢?首先要定义一个基本字体系列和字体大小。尽管可以定义背景颜色、字体颜色和空白边,但是我们保持打印设备的默认设置。下一项工作是隐藏 Web 页面上对打印媒体没有意义的那些区域。如上面的 图 20 所示,我们只使用站点标题和页面的主要内容区域。清单 18 显示最初的基本样式。


清单 18. print.css 中的基本打印样式
                                    body {                                    font: 12pt Georgia, "Times New Roman", Times, serif;                                    }                                    #nav_bar, #sidebar, #footer {                                    display: none;                                    }                                    .action, .more, .return_top, .tabs, .index {                                    display: none;                                    }                                    

字体样式使用 12pt 值,这是常用的打印媒体字体大小。我们选用标准的 serif 字体以保持可读性。第二个和第三个样式规则隐藏那些在打印文档中不需要的内容部分。

测试打印样式

使用可用的打印设备测试打印样式是个好主意。但是,往往要经过很多次迭代才能获得需要的显示效果,因此会在等待打印方面浪费很多时间,还会浪费纸张。更好的方法是使用大多数浏览器上都有的打印预览选项,如 图 21 所示。

我们发现浏览器在应用打印样式方面存在一些差异,但是这些差异比屏幕媒体样式遇到的差异少得多。Web Developer extension for Firefox 这样的插件(参见 参考资料)允许使用 XHTML 中定义的不同媒体类型来查看 Web 页面。但是,我们发现打印预览选项可以更可靠地显示打印页面的外观。当然,真正的测试是实际打印 Web 页面。按照这种方式,可以只在页面的打印预览效果令人满意时进行实际打印。


图 21. 公告的打印预览

调整打印样式

可以很快地建立合理的 Web 内容打印样式,但是我们发现有许多小的调整可以提高可读性。例如,在标题上应用边框样式有助于提高可读性。下面列出了对 IBC 站点的打印样式的几处修改。

空白
浏览器的默认打印样式会创建可读性很好的文档。但是,我们发现元素之间的一些空白边不理想。例如,我们增加了段落周围的空白以提高可读性。清单 19 显示应用于 P 元素的样式,这个样式会调整段落上下的空间。


清单 19. print.css 中的段落调整
                                    p {                                    margin: 0.2em 0;                                    }                                    

链接
我们提到过,链接在打印媒体上下文中不提供有意义的信息。根据读者需求的不同,这可能是有争议的。您可能希望强调某些链接到其他 Web 文档的单词或短语。这可能应该采用下划线形式,因为粗体和斜体文本是常用的打印强调技术,使用它们可能会使内容的含义产生混淆。也可以考虑使用颜色,这在下面讨论。另一种技术是将链接的 URL 打印在相关文本的后面。清单 20 显示我们如何使用 after 伪元素和 content 样式显示链接的 URL。


清单 20. 在链接文本后面显示 URL
                                    a:link:after, a:visited:after {                                    content: "[link:"attr(href)"]";                                    font-size: 90%;                                    }                                    


图 22. Web 页面上和打印页面上的 IBC 链接

如果在 XHTML 链接中使用相对 URL,那么打印版本可能会使读者觉得迷惑。与相对 URL forum 相比,绝对 URL http://intbizcouncil.org:96/forum 在这个上下文中更合适。

颜色
我们希望 IBC 内容在尽可能多的打印设备上有良好的打印效果,所以希望控制打印颜色的方式。例如,用来在表格数据中标识间隔行或强调研讨会议程的某些部分的色带。可以使用与屏幕样式相同的颜色定义,让打印设备以默认方式将它们显示为不同的灰色底纹。但是,通过在样式中定义颜色,可以定义更好的灰色底纹。

颜色的另一个用途是显示某些实体(比如 IBC 成员)的状态。在 Web 站点上,以一种颜色突出显示只有操作人员能够看到的成员。为了在打印页面上体现这种效果,我们使用与 清单 21 相似的技术添加一些说明性文本,如 图 23 所示。


清单 21. 显示不可见 IBC 成员的状态
                                    .member_summary.hl_red .fn:before {                                    content: "(Not visible) ";                                    }                                    


图 23. Web 页面上和打印页面上的不可见 IBC 成员

隐藏的和链接的信息
使用 CSS 隐藏和显示内容是非常容易的,因此可以在打印的内容中添加在其他页面中没有的信息。例如,对快捷键进行解释的可访问性内容和研讨会议程页面。

在提供给研讨会页面的模板文件的节点对象中,不只包含议程,还有研讨会地点等会务信息。在屏幕样式表(conference.css)中,我们隐藏了 DIV 元素中的会务信息,但是提供了到包含会务信息的另一个页面的链接。在打印样式表中,显示会务信息,让读者能够在页面上了解到关于研讨会的更多信息。但是,这种做法以不一致的方式显示信息,可能会引发某些有趣的争议。

换页
某些信息的显示可能需要在页面之间进行符合逻辑的分隔。换页样式(page-break-beforepage-break-insidepage-break-after)提供了在 CSS 中控制分隔方式的办法。

我们对每个包含一天中的议程的表格使用 page-break-before 样式。打印效果的可读性很好,但不幸的是,在某个流行的浏览器版本上进行测试时,这会破坏整个布局。我们认为这个 bug 现在已经修复了,但是这使我们意识到某些打印样式特性在浏览器中还没有完全实现。





回页首

预期和测试

向包含动态内容的 Web 站点应用样式不是一件轻松的工作。包含静态内容的 Web 站点提供了一个可应用 CSS 的非常稳定的基础。这里不会有导致 XHTML 结构发生更改(进而有可能影响 CSS 效果)的异常内容。例如,IBC 站点的内容编辑可能会决定将一个文档中的某些文本剪切到新公告的某个字段中。主题设计人员无法预测这些被剪切的内容是什么!这种内容结构的变化是否会导致某些 XHTML 标记未正常关闭?内容是否会超过特定的长度,使文本显示未能填充到页面的某些元素中?内容中是否有在页面上无法正常显示的特殊字符?在某种程度上对内容进行限制,以及使用最大字段长度和 tinyMCE 来控制用户输入是有帮助的。但是,意外情况还是会发生。

随着在系统中添加更多的角色,并根据这些角色修改用户看到的内容,内容结构和显示方式的不确定性就会增加。那么,如何处理这些意外情况呢?如果主题设计人员不可能精确地预测内容结构的变化,至少应尝试通过预期和测试预测出 80% 的情况。

第 7 部分 中,我们讨论了为内容的语义提供逻辑分隔的有效容器。对于包含静态内容的站点,只需将 idclass 属性应用于这些容器,就可以对它们应用样式。但是,向内容可变的站点应用样式时,主题设计人员常常需要对模板中的内容结构进行迭代,添加更多的 idclass 属性,或者在外边加上额外的 DIVSPAN 元素来控制显示方式。通过预测变化的内容的效果,可以降低这些迭代的复杂程度。Zen Garden 使用的模板就是一个很好的例子。(参见 参考资料。)

测试

为了测试这些预期的效果,我们需要数据、用户及其适用角色。用测试数据填充 Drupal 站点是有帮助的,但是在开发阶段如果能够使用真实数据,就能更好地表现 Web 站点的情况。当然,如果您是在对 Web 站点进行重新设计,就可能有足够的真实数据,可以从旧站点迁移到 Drupal 数据库中。对于 IBC 站点,在这个开发阶段,我们要求客户开始输入真实数据。这不但为我们提供了开始进行主题样式设计所需的数据,而且还有以下好处:

  • 训练客户使用 Drupal 管理界面
  • 对新模块进行测试
  • 调整内容的结构化布局
  • 从客户那里获得有价值的反馈
  • 了解客户的操作方式

 





回页首

结束语

在本文中,您学习了如何建立结构符合语义的 Web 站点,以及使用 CSS 实现所需的屏幕和打印样式。还学习了这个团队如何对它的样式表进行组织、几种基于标准的样式技术和测试方法。

本系列中的下一篇文章描述 Drupal 数据库抽象层,以及如何使用 DB2 Express-C 替代 MySQL 或 PostgreSQL。



参考资料

学习
  • 您可以参阅本文在 developerWorks 全球站点上的 英文原文

  • 订阅 这个系列的 RSS feed。(进一步了解 RSS。)

  • 进一步了解这个 系列。在这个系列中,Internet Technology Group 团队描述一个需要定制 Web 站点的虚构的组织,这个 Web 站点包含文档存储、讨论组、专门的工作组、研讨会日程安排、日程议题描述等功能。

  • tinyMCE in Drupal:学习这个 Drupal 模块如何将 TinyMCE WYSIWYG 编辑器集成到 Drupal 站点中,用来编辑站点内容。

  • Web Developer plug in for Firefox:学习如何使用各种 Web Developer 工具在浏览器中添加菜单和工具条。

  • Zen Garden:学习关于 CSS 设计的更多知识。

  • Alternative Style - Working With Alternate Style Sheets:通过 Paul Sowden 的文章了解一种在不同浏览器上动态地切换样式表的方法。

  • Going to Print:通过 Eric Meyer 的文章了解关于创建媒体专用样式的更多信息。

  • Suckerfish Dropdowns:通过 Patrick Griffiths 和 Dan Webb 的文章了解关于下拉菜单的更多信息。

  • 访问 Eric Meyer 的 Web 站点,这里提供了关于浏览器默认样式的更多细节。

  • Sliding Doors of CSS, Part 2:通过 Douglas Bowman 的这篇文章了解如何使用简单的、基于文本的语义标记创建精美的界面元素。

  • CSS Mastery: Advanced Web Standards Solutions :作者是 Budd、Moll 和 Collison,书中介绍了尖端的 CSS 开发技术。

  • Designing with Web Standards, 2nd Edition :Jeffrey Zeldman 所著的这本书改变了设计 Web 站点的方式。

  • Web Standard Solutions: The Markup and Style Handbook :作者是 Dan Cederholm。

  • A List Apart:这里有许多为 Web 站点设计人员准备的文章。

  • CSS Discuss:这个邮件列表专门讨论 CSS 以及在真实环境中使用它的方法。

  • CSS Organization Tip 1: Flags:Douglas Bowman 的一篇 blog 文章。

  • technology bookstore 寻找相关技术主题的图书。

  • 随时关注 developerWorks 技术活动和网络广播


获得产品和技术
  • 使用 IBM 试用软件 构建您的下一个开发项目,这些软件可以从 developerWorks 直接下载。


讨论
  • 参与论坛讨论

  • 通过参与 developerWorks blog 加入 developerWorks 社区。


作者简介

Alister Lewis-Bowen 是 IBM 的 Internet Technology Group 的高级软件工程师。他从 1993 年开始作为 IBM 英国职员从事互联网和 Web 技术方面的工作。Alister 后来到美国为 IBM 赞助的体育活动的 Web 站点工作,之后成为 ibm.com 的高级网管。他当前正在帮助创建语义 Web 原型。可以通过 alister@us.ibm.com 联系 Alister。


Stephen Evanchik 是 IBM 的 Internet Technology Group 的软件工程师。他是许多开放源码软件项目的代码贡献者,其中最著名的是 Linux 内核中的 IBM TrackPoint 驱动程序。Stephen 当前从事语义 Web 技术。可以通过 evanchik@us.ibm.com 联系 Stephen。


Louis Weitzman 是 IBM 的 Internet Technology Group 的高级软件工程师。他从事设计和计算已经有 30 年了。他曾经帮助开发 ibm.com 使用的基于 XML 片段的内容管理系统,当前正在从事将设计过程融入新项目的工作。可以通过 louisw@us.ibm.com 联系 Louis。 



使用开源软件设计、开发和部署协作型 Web 站点,第 8 部分: 使用 CSS 对主题化内... 使用 Spring Framework 设计和开发 SCA 组件,第 2 部分: 使用 Apache Tuscany 的高级技巧 如何部署使用“远程桌面Web连接” 使用 Spring Framework 设计和开发 SCA 组件,第 1 部分: 三剑客:Spring、SCA 和 Apache Tuscany 51CTO专项调研:2011年中国Web开发工具选择和使用情况 工具推荐:如何部署使用“远程桌面Web连接” 使用Axis开发Web Service程序-月光博客 使用Struts2开发Java Web应用程序(目录) 使用 Axis2 进行 SOA 开发,第 1 部分: 了解 Axis2 基础 使用CSS sprite 的好处和坏处分析 在 WebSphere Application Server Community Edition V2.0 中开发和部署 JAX-WS Web 服务 5使用 WebSphere DataStage XML 和 Web Services 包转换... Ganglia 和 Nagios,第 2 部分: 使用 Nagios 监视企业集群 WASCE 中的高级管理,第 2 部分: 使用线程池、集群和配置插件 使用 Acegi 保护 Java 应用程序,第 1 部分: 架构概览和安全过滤器 CSS使用技巧201则 学会使用css中的behavior 使用 RESTlet 框架开发符合 JSR311 规范标准的 REST Web Service 在IE下使用Firebug的简单功能 – WEB前端开发 精选30个国外优秀的CSS技术和实例【翻译】_raozou:专注于Web前端开发&&互联网... 使用 TreeView IE Web 控件 开发ActiveX控件使用MFC和ATL之比较 自我防护Web站点和恶意链接的方法 使用CSS实现侧边Tab菜单栏1