HWeb标准的创造性全绝不原创的飞龙

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

查看这一部分的XHTML,您会看到波段名也在

元素中指定,该元素使用display:none隐藏。这是为了确保如果图像和CSS被禁用,该网站仍然是品牌。

背景

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

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

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

body{margin:0;padding:0;font-size:95%;font-family:Georgia,'LucidaGrande',Verdana,sans-serif;text-align:center;color:#333;background:#C6C2B6url(img/background.jpg)centertopfixedrepeat-x;}注意由于图像是水平重复的(repeat-x),无论浏览器窗口有多宽,它都会占据整个网站的宽度。但是,页面background-color是在背景拼贴底部的平面颜色上采样的。与这种颜色结合的图像将完成整个背景,并给人一种背景图像高得多的印象。

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

刊头

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

图1.7。报头背景图像

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

#masthead{width:768px;height:254px;margin:15px008px;color:#030;background:#ECE4D9url(img/masthead.jpg)no-repeat}最后,主内容选择器返回到wrapper中定义的full-width,允许所有剩余内容重新开始,并指定新的背景图像。这个新图像向各个方向平铺,尽管内容区域的宽度仅够显示垂直平铺。此拼贴扩展了刊头背景中使用的边缘,给人一种又长又旧的页面的感觉。

导航菜单

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

图1.8。各种报头创意

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

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

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

#mastheadulli{width:135px;height:25px;list-style-type:none;padding-top:4px;font-size:12px;letter-spacing:0.07em;}接下来,我们选择每个列表项中的链接。大多数是跨各种状态的常见链接方法,但我们发现包含display:block以防止应用于每个链接的各种边距值导致链接聚集在一起并造成巨大破坏是至关重要的。

#mastheadullia{display:block;padding-left:11px;text-decoration:none;font-weight:bold}#mastheadullia:link,#mastheadullia:visited,#mastheadullia:active{color:#FFF;}#mastheadullia:hover{color:#F00;}有了所有这些,两个菜单被准确地放置在我们想要的位置,现在我们可以考虑单独处理每个链接了。

前面我提到过,我们已经给了每个链接一个唯一的ID。这些钩子现在可以让我们玩得开心了。在Photoshop中,我创建了三个不同的背景图像,它们都适合我们的

  • 元素的给定宽度。我们现在可以随机地将这三种背景中的任何一种应用于每个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被添加到元素中,目的是用CSS应用程序的一个小技巧轻松地突出显示主菜单中的当前页面。

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

    /*Highlightthecurrentpage*/#home#m1a#homebutton,#news#m1a#newsbutton,#diary#m1a#diarybutton{color:#F00;}因此,每当用户查看主页时,链接颜色将被设置为红色,但在滚动时仍然是白色。从CSS来看,应该清楚新闻模板用的是,日记模板用的是。剩下的唯一工作是为每个需要与模板对应的唯一链接ID复制CSS,将目标分组到一个整洁的无所不包的定义中。

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

    标题

    DirtybeautifulThings网站大量使用了2级(

    )和3级(

    )标题。最值得注意的是,二级标题用在所有页面的主要内容区域和侧边栏的顶部,但是有不同的外观。这是通过在样式表中使用后代选择器实现的。

    下面的标记反映了一个简化的侧栏。注意,主内容中的

    元素也没有惟一的ID或类。

    TheBand

    DirtyPrettyThingsareCarlBarat,AnthonyRossomando,DidzHammondandGaryPowell.

  • 图1-9显示了用于两个

    元素的两个背景图像。

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

    主内容区域中使用的

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

    h2{margin:002px10px;padding:6px05px13px;font:14px/165%italicGeorgia,Arial,Helvetica,sans-serif;letter-spacing:0.2em;color:#FFF;background:#EAE5D8url(img/blackhead.gif)leftbottomno-repeat}现在,我们继续讨论侧边栏的

    。巧妙的部分是用后代选择器完成的。当

    元素在侧边栏中时,选择器#sidebarh2告诉浏览器应用这些规则。如果找到匹配,则使用不同的背景图像blackheadside.gif,并缩小页边距和font-size。

    #sidebarh2{margin-top:3px;font-size:12px;background:#EAE5D8url(img/blackheadside.gif)leftbottomno-repeat;}注意后代选择器对于避免不必要的类和id是必不可少的,否则它们可能会破坏XHTML文档。通过使用后代选择器,CSS规则可以变得更加具体,并且后代选择器可以沿着树向下移动多远——可能是父代的子代的子代?

    表格

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

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

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

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

    table{width:100%;margin:10px020px0;border:0;font-size:11px;}然后,我们在每一行的顶部放置一个虚线边框,并添加特定的填充,消除对过时的表示标记的需要,如cellpadding或cellspacing。

    td,th{margin:0px;border-top:1pxdashed#999;padding:3px5px3px5px;}注意值得注意的是,cellspacing没有可靠的CSS等价物,所以很多设计师仍然利用这个表象属性。

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

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

    定义列表

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

    所有的定义列表都由两个主要部分组成:术语和描述。定义列表是使用三个基本元素构建的:容器(

    )、定义术语(
    )和定义描述(
    )。这个简单的结构适合我们对侧栏标题和游览日期的需求,其中日期充当定义术语,标题或地点是描述。结果是逻辑配对提供了所有必要的样式挂钩。

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

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

    dt{float:left;padding:2px07px0;line-height:130%;font-weight:bold;}接下来,定义描述元素被样式化。非常简单,关键任务是移除默认边距,该边距将它从包含的

    元素的左边缘推开。

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

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

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

    丹·鲁宾

    www.webgraph.com

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    该乐队的标志艺术品

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

    当前专辑封面

    十个类别的主要导航

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

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

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

    图2.5。最初的Photoshop合成

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

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

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

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

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

    由于CMS控制着大部分内容块周围的标记,最简单的方法就是创建一个shell布局,用

    来包含每个数据模块。该设计基本上是两列加一个页脚,徽标和导航位于左列。折腾了几个比特的样本内容,我得到了这个:

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

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

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

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

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

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

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

    背景设置

    定位方法(位置:)

    位置(x,y)

    宽度/高度

    边距/填充

    颜色

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

    边界

    定位元件

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

    .clearfix:after{content:".";display:block;height:0;clear:both;visibility:hidden;}.clearfix{display:inline-block;}/*HidesfromIE-mac\*/.clearfix{display:block;}/*EndhidefromIE-mac*/"body{background:#111url(../i/bg_body.gif)repeat-x;margin:0;padding:0;font-family:'lucidagrande',tahoma,sans-serif;font-size:small;}#wrapper{width:800px;}#content被设置为float:left,使其包含它所包含的两个浮点(#content-primary和#sidebar-wrapper):

    #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#logoa{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:20px030px;color:#EFB32F;font-family:'lucidagrande',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:3pxsolid#111;clear:both;}#sidebar-wrapper{float:right;background:#1C1C1Curl(../i/bg_sidebar_wrapper.gif)no-repeatleftbottom;width:277px;margin:003px;padding:0010px;}#sidebar.module{color:#A07029;padding:15px15px15px0;border-top:1pxsolid#111;clear:both;}#footer-wrapper{background:#1B1B1Burl(../i/bg_footer_wrapper.gif)repeat-x;padding-right:10px;clear:both;border-top:1pxsolid#333;}#footer{background:#262626url(../i/bg_footer.gif)repeat-x;padding:20px020px;}这没有什么奇怪的。它是容器(或包装器)、一些列的浮动和一些绝对定位的混合物。因为这一章的目的不是教你CSS的基本原理,我在这里就不赘述了。如果你觉得自己在任何基础知识上落后了,我推荐阅读西蒙·科利森的初学CSSWeb开发(出版社,ISBN:1-59059-689-7)。

    瞄准CSS选择器

    我之前展示的基本shell标记中包含的生成标记的一个大问题是,在决定使用哪种标记时,我没有发言权。在描述中包含嵌套段落的定义列表可能是最合适的,但我可能会被迫处理一些嵌套的包含到处都是

    。您可以通过查看现场的源代码来了解这一点。啊。再喝一杯(浓茶)来帮助你克服这个心理印象。

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

    IDs:在CSS中作为#footer出现,在(X)HTML中作为元素上的属性值出现,比如,其中div是元素,id是属性,footer是值。

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

    元素选择器:目标任意(X)个HTML元素。例子有ul、p、div、body、table,甚至html。

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

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

    这种标记完全不受我的控制,但我仍然需要对它进行样式化。并且很可能给生成的

    标签上的类属性分配了通用的类名,我的钩子(类item、summary和stream)在整个站点的许多其他地方使用。这意味着我需要一些方法来定位这个部分中的类,以便处理视频模块的任何特定需求。因为CMS的内容模板生成的标记中没有提供这些挂钩,所以我在布局模板中创建它们,将它们包装在调用生成内容的代码中:

    ...

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

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

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

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

    #sidebar.moduleimg.fullsize{float:right;margin:005px5px;border:none;}这个选择器使用我分配给我的包装器的类

    和#sidebar,所以如果我决定在布局中的任何地方使用module类,这个规则将不适用。

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

    #sidebar#mod-mediaimg.fullsize{float:left;margin:05px5px0;}通过将选择器中的类(.module)替换为ID(#mod-media),我指示浏览器首先应用通用样式,然后覆盖浮动和边距设置。

    同样的方法可以让你摆脱CMS生成的标记为你挖的几乎所有的洞。虽然我们没有人真的想使用像body#events#content.item.module.summary#membershipp.permalinkspan{}这样难看的选择器,但是如果你陷入困境,需要完成工作,将选择器与一两个包装器

    组合并分层会让你的生活压力小很多。

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

    制造竖排文字的假象

    应该垂直的标题都是静态的。由于它们不需要定期更新,我可以使用Photoshop中渲染的图像。竖排文字的效果不容易用其他方式复制。我可以用Flash做到这一点,但用这种方法更容易,因为sIFR方法(接下来讨论)不支持旋转文本,Flash项目可能更难定位。我可以使用CSSbackground-image属性将每个图像分配给一个容器

    ,但是在HTML文件中没有实际的标题,如果标记是可访问的,即使是基本的,这也不是理想的情况。

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

    #sidebar.moduleh3{background:url(i/header_module_events.gif)no-repeat;width:18px;height:58px;margin:0;text-indent:-5000px;}该规则处理以下内容:

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

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

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

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

    图2-7,afterthebackgroundimageisapplied(middle),andaftersettingtext-indent:-5000px;(right)")显示了应用CSS规则之前、期间和之后的标题。

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

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

    sIFR我的木材

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

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

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

    您想要使用sIFR渲染的字体

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

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

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

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

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

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

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

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

    .sIFR-hasFlash#teaserh3{visibility:hidden;letter-spacing:0;font-size:24px;line-height:22px;}最后,我们有了最终结果,如图2-8所示。

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

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

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

    标签的背景,并使标签(以及徽标)链接到主页:

    下面是XHTML:

    h1#logo{position:absolute;z-index:100;left:29px;top:39px;margin:0;padding:0;}h1#logoa{display:block;background:url(../i/logo_lifehouse.gif)no-repeat;width:38px;height:175px;text-indent:-5000px;}瞧,我现在有了一个可点击的标志。

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

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

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

    在实现我所设想的设计时,我面临的一个更大的挑战是InternetExplorer/Windows和#teaser

    的透明背景。我有两个选择:

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

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

    图2.11。这是一个微妙的区别,但主照片底部的阴影允许图像的底部融入下面导航栏的背景色,并与#teaser

    的透明背景配合得很好。

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

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

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

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

    ethanmarcotte

    www.vertua.com

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

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

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

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

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

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

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

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

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

    importurl("core.css");/*\*//*/importurl("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),它可以防止除了麦金塔上的InternetExplorer5(IE5)之外的任何浏览器看到其中的代码。所以现在,有了我们的半隐藏的patches-mac.ie5.css,我们可以在浏览器中放置任何样式规则来解决CSS错误。

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

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

    在这里,我们使用那些条件注释来隐藏我们的第二个链接,它来自于比版本7(没关系!在这一章中,你已经了解到,当使用以前被认为是先进的CSS来创建一个打破常规的设计布局时,没有什么可担心的。现代的CSS2.1选择器、浮动和定位是用最少的非表示性标记创建引人入胜的网站设计的完美工具。

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

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

    杰夫·克罗夫特

    www2.jeffcroft.com

    杰夫·克罗夫特是一名专注于基于标准的开发的网页和平面设计师,他在堪萨斯州的劳伦斯生活和工作。作为世界在线的高级设计师,杰夫在www.lawrence.com和www.ljworld.com等获奖新闻网站工作。杰夫还在www.jeffcroft.com经营一个受欢迎的博客和个人网站,在那里他写了许多话题,包括现代网络和图形设计。

    自从有网可织以来,杰夫就一直在织网。他在1994年用SimpleText和NetscapeNavigator1.1N在MacintoshPerforma600上创建了他的第一个网页。他于1996年开始全职从事网络工作,并一直坚持到现在。

    尽管Jeff喜欢技术和小工具,但网络真正激发他灵感的是它沟通和联系人们的能力。杰夫是设计的忠实消费者,几乎在任何地方都能找到灵感。

    当杰夫不在电脑前工作时,他喜欢摄影、音乐、电影、电视和在镇上度过一个美好的夜晚。

    PNG图像被网页设计社区广泛忽视,这是有原因的。直到最近,还不可能充分利用这种格式并让它在所有浏览器中可靠地工作。但是,有了InternetExplorer7中对PNG的适当支持,以及一些方便的JavaScript和CSS技巧来解决旧浏览器的问题,我们可以使用PNG图像来大大增强我们的设计词汇。

    PNG通常读作“ping”,代表便携式网络图形。这是一种无损压缩位图图像格式。简单地说,这是一种保存图形图像的方式,可以在不降低图像质量的情况下减小文件大小。它最初是作为无处不在的GIF格式的替代品而创建的,GIF格式过去需要成像软件的生产商获得专利许可才能合法使用它(GIF/LZW专利已经过期,所以这不再是一个因素)。PNG也是国际标准(ISO/IEC15948:2003)和W3C官方推荐标准(www.w3.org/TR/PNG/)。

    除了作为一种免费的格式,PNG还为网页设计者提供了几个优于GIF的实用优势:

    更大的压缩率:对于大多数图像来说,PNG文件比GIF文件更小。

    更大的颜色深度:PNG提供高达48位的真彩色,而GIF只允许256色调色板。

    alpha通道透明:GIF只提供二进制透明,而PNG通过启用Alpha通道来实现透明,从而允许几乎无限的透明效果。

    除了对浏览器支持的误解之外,GIF对动画的内置支持是(并将继续是)它成功的一个关键原因。然而,近年来,随着其他技术(特别是Flash)在动画中变得越来越常见,GIF的这种使用变得不那么流行了。

    透明性是GIF和PNG的一个关键特征,这也是它们中的任何一个被选为网页设计者选择特定图像元素的格式的原因。尽管PNG对透明性提供了更广泛的支持,但web设计人员经常需要创建图像的GIF版本,以适应较旧的浏览器。使用CSS,可以将GIF图像发送到旧的浏览器,将高质量的png发送到理解它们的浏览器。但是创建两个图像对网页设计者来说是额外的工作,这经常导致人们满足于最小公分母,仍然是GIF图像。

    最后,GIF仍然如此受欢迎有几个原因,但大多数是基于误解或越来越不常见的用例场景。掌握了PNG如何工作以及如何在各种浏览器中可靠使用的一些新知识,您应该能够利用这种格式提供的所有优势,而不必依赖GIF。

    JPEG是网络上另一种无处不在的文件格式,对于照片(或类似照片)图像来说,它几乎总是比PNG或GIF更好的选择。巴布亚新几内亚无意与JPEG竞争。在处理照片时,JPEG的有损压缩(每次保存图像时都会导致质量下降)会产生比PNG小得多的文件。另一方面,当PNG中的图像是文本、艺术线条、徽标、单色等时,它会生成较小的文件。

    现在让我们来看看PNG在网页设计中的一些重要用途。我已经将每个例子的所有文件包含在本章代码下载的一个单独的文件夹中,可以在www.friendsofed.com找到。

    在过去的几年里,两种或两种以上颜色之间的渐变已经成为网页设计者最好的朋友。特别受欢迎的是微妙的,几乎不明显的渐变填充,它增加了深度和纹理的感觉,而不明显和俗气。

    GIF有时候是渐变的好选择。如果渐变是简单的双色渐变,GIF通常就可以了。但是,GIF256色限制通常会在更复杂的渐变过渡中产生明显且难看的条纹。另一方面,JPEG可以呈现非常令人愉悦的渐变,但通常会以文件大小超出预期为代价。虽然JPEG渐变通常“足够好”,但请记住,JPEG确实使用有损压缩,这意味着再现的图像永远不会像原始的未压缩图像那样高保真。

    考虑通常用于按钮、框和其他任何东西的典型背景渐变样式。它可能看起来有点像图5-1。从左上方顺时针方向,我们有原始(未压缩)图像、GIF版本、PNG版本和JPEG版本。您可以看到,PNG产生的文件最小(515字节)。比GIF图小四倍左右。JPEG比PNG稍大,为637字节,由于有损压缩,它的质量也较低(不可否认,在这个简单的例子中,人眼察觉质量差异的能力是值得怀疑的)。

    图5.1。Photoshop的“存储为Web格式”面板显示不同格式的同一图像的文件大小差异

    有时有必要创建一个在各种背景下都能很好工作的图像。一些常见的例子是徽标和图标。这些情况传统上是GIF文件的领域,但是有几个原因说明PNG可能是更好的选择。在标志和其他简单艺术品的文件大小的较量中,巴布亚新几内亚几乎总是赢家。此外,PNG固有的透明性使得创建一个可以在任何背景上工作的文件变得简单。PNG确实提供了二进制透明性与gif一样,但也提供了更令人兴奋的alpha通道种类,其中像素可以是部分透明的,而不是简单的开或关。使用后者确实会增加文件大小,有时会超过(二进制)透明gif的大小,但也允许对艺术作品的边缘进行抗锯齿处理,这有助于在背景上放置更优雅的文件。

    对于堪萨斯州托皮卡的KTKA频道新闻网站(www.49abcnews.com),世界在线的工作人员精心制作了漂亮的天气图标,在网站的标题中显示当前的天气状况。但是,由于一个聪明的编程,使得标题在日落时从白天的配色方案变为夜间的配色方案,天气图像需要在不同的背景下工作得同样好。看看图5-2和图5-3。

    图5.2。www.49abcnews.com头球,白天

    图5.3。www.49abcnews.com头球,夜间

    通过使用PNG,我能够公正地处理设计师的作品,无论它是出现在白天还是夜晚的背景上。而且,如果我们选择在某个时候改变背景,我就不必重新制作任何天气图标,因为透明的PNG文件在任何东西上看起来都很棒。

    如果我选择使用GIF,我会被限制在GIF的二进制透明性。结果看起来会像图5-4。我想我们都同意这还不够好。

    图5.4。www.49abcnews.com标题,nightime,用GIF图片代替PNG

    一种非常常见的图形设计技术是在照片或其他图像上覆盖一个部分透明的区域,通常包含文本。这使得文本可读,而不会完全模糊下面的图像。设计师WilsonMiner(www.wilsonminer.com)在Gingeroot珠宝网站(www.simplygingeroot.com)上很好地利用了这一点,你可以看到图5-5")。

    图5.5。www.simplygingeroot.com,由天才的威尔逊·迈纳(www.wilsonminer.com)设计

    Wilson将他的透明区域和文本包含在JPEG图像中。他事先用Photoshop制作了它们。这很好,并且完全适合网站的需求。但是,如果半透明区域的文本需要经常改变,甚至对每个访问者都不一样,那该怎么办呢?在这种情况下,将文本放在图像中是不实际的。该文本将需要在HTML和CSS精心制作。使用PNG的透明alpha通道,我们可以模仿Wilson的风格,而无需将文本放入图像本身。

    我将从我女儿HaleyMadysan的一张照片开始,并将其放入一个简单的XHTML页面中,使用一些基本的CSS样式(这是代码下载中的haley_example/index.html)。注意,我使用嵌入的CSS样式表只是为了演示。在现实世界中,使用链接的外部样式表通常会提供更大的灵活性、更少的代码重复和更实用的文件管理。

    图5.6。模仿HTML和CSS的www.simplygingeroot.com风格,但是没有透明度

    现在我将在Photoshop中创建一个1×1像素的图像。我用浅蓝色填充图像,设置图层透明度为70%。最后,我使用Photoshop的PNG-24设置保存图像,启用透明度。然后我简单地使用这张图片作为叠加的背景,而不是你在图5-6")中看到的纯灰色。

    #feature-content{position:absolute;bottom:0;left:0;height:125px;width:720px;background-image:url('transparent.png');}结果与原始的非常相似,但是有了HTML和CSS文本,它变得更加灵活,如图5-7所示。

    图5.7。通过PNG图像格式添加透明度几乎复制了www.simplygingeroot.com样式。

    WilsonMiner实际上在www.simplygingeroot.com现场的不同区域使用了相同的概念。在展示可用产品的页面上,一个透明的PNG图像被用来在销售项目产品照片的左上角显示一个OnSale标志,如图图5-8所示。通过一次性创建OnSale图像,并使用透明背景将其保存为PNG图像,Wilson避免了为每个嵌入旗帜的产品图像创建单独版本的需要。

    图5.8。www.simplygingeroot.com的项链部分使用PNG图像,透明背景覆盖在产品图像上,在左上角显示一个OnSale标志。

    我还在探索汽船(www.exploresteamboat.com)上使用了这种技术,这是一个致力于科罗拉多州汽船泉事件、娱乐和活动的网站,如图5-9所示。

    图5.9。通过透明PNG的方式在图像上放置一个半透明的盒子。

    在另一个创意例子中,设计师布莱恩·贝洛索(www.avalonstar.com)使用了一个固定在页面底部的透明PNG图像来创建一种“淡入”效果,当你向下滚动页面时,文本似乎凭空出现。在www.revyver.com(见图5-10和图5-11)发现的效果比描述的要好,所以一定要亲自检查一下。此外,树图形位于页面文本内容的前面,产生了意想不到的视觉效果。当你第一次看到它时,它有一种令人惊叹的因素。

    图5.10。在www.revyver.com,设计师布莱恩·贝洛索使用了一种透明的PNG来创建一种当你向下滚动页面时的“淡入”效果,并将他的作品放在页面文本内容的前面。

    图5.11。通过在Photoshop中查看Bryan的页脚PNG图像,我们可以了解如何构建透明alpha通道来实现设计的效果。

    图5.12。www.jeffcroft.com上的照片详情页

    如果我想把我的个人标志放在我所有的照片上呢?是的,可以在Photoshop中打开每个图像,应用徽标,然后重新保存图像。然而,当处理成千上万的频繁更新的图片时,这变得非常不切实际,有时当我不在电脑旁边时(例如,当我通过手机向Flickr发送照片时)。如果logo是自动添加的不是很好吗?巴布亚新几内亚可以帮助做到这一点。

    用于在页面中显示照片的HTML如下所示:

    a.photo-container{position:relative;display:block;}img.watermark{position:absolute;top:2em;left:1em;}结果是一个水印看起来像是嵌入在照片本身,但实际上是一个独立的PNG图像位于它的上面,如图图5-13所示。通过把它放入我的内容管理系统的模板中,我不用做2000多次就可以在每张图片上添加水印。

    图5.13。微妙的www.jeffcroft.com徽标标记通过透明PNG出现在照片的左上角。

    如果您想变得更聪明,您甚至可以使用DOM脚本来动态插入水印的附加(X)HTML标记。

    PNG图像和它的alpha通道透明度的另一个方便的用途是遮罩它下面的图像。从技术上来说,这与你刚才看到的水印非常相似,但它实现了不同的视觉效果。

    这一次,我将在Photoshop中制作一个更大版本的徽标。我不把logo做成白色,而是把它做成透明的,图像的其余部分是白色,因为白色是页面的背景色,如图图5-14所示。

    图5.14。在Photoshop中创建用作透明PNG蒙版的图像

    正如我所说的,它的技术方面与上一节中的水印几乎相同,从HTML开始:

    a.photo-container{position:relative;display:block;}img.mask{position:absolute;top:0;left:0;}最终结果见图5-15。

    图5.15。PNG蒙版放在照片的上面,创造出一种“打孔”的效果。

    通过使用你在前一个例子中看到的蒙版概念,一些人只用CSS就创建了可以改变颜色的图标。这个想法既简单又巧妙:将一个带有图标符号“打孔”的透明图像放在一个正方形、矩形或其他具有单色CSS背景的形状上,这样就有了一个图标。通过简单地改变背景的CSS颜色,你给人以图标改变颜色的印象。

    也许我们需要一组表示常见运动的图标,如图图5-16所示。

    图5.16。一些常见的体育图标

    我已经用图标符号形状的透明穿孔创建了白色图像,正如我在上一节的蒙版示例中对徽标所做的那样,如图图5-17所示。

    图5.17。为每个图标创建“挖空”的PNG蒙版

    在将图像缩小到合适的尺寸(我选择了48×48像素)后,我使用Photoshop的PNG-24默认设置并启用了透明度来保存它们。然后我创建了一个简单的XHTML文件来引用每张图片(代码示例下载包中的sports_icons_example/index.html):

    图5.18。透明的PNG图像作为网络图标。注意CSS背景色(红色)透过图像显示出来。

    正如你在图5-19中看到的,我可以简单地通过改变CSS中的颜色值来改变图标图像的颜色:

    图5.19。在CSS中改变背景颜色会改变图标的外观颜色。

    当你需要重新设计你的网站时,这种简单的颜色变化会非常方便。不用重新制作所有的图标图像,你只需要在CSS中改变一次颜色。这也是为链接图像实现简单鼠标悬停效果的好方法。例如,您可以使用红色作为标准颜色,蓝色作为悬停样式(代码示例下载包中的sports_icons_example/index_links.html):

    图5.20。使用CSS通过添加边框进一步增强图标的外观

    丹·塞德霍尔姆(www.simplebits.com)早在2003年(www.simplebits.com/notebook/2003/07/24/magic_icons_for_lazy_people_like_me.html)就在他的博客中写过一个非常类似的技术,PJ·小野里(www.somerandomdude.net)在他的网站(www.somerandomdude.net/srd-projects/sanscons/)上提供了一组基于它的图标(称为Sanscons)。

    然而,我通过使用一个带有穿孔符号的白色图像颠倒了他们的概念。他们在透明的背景上使用了一个白色的符号,这也非常有效。在这种情况下,您的CSS背景颜色会作为围绕符号的正方形或矩形而发光,而不是作为符号本身发光。

    丹和PJ都使用透明的gif文件而不是png文件。这完全符合他们的需求,因为他们创建的图标风格是位图,看起来像小精灵。通过使用png,您可以应用相同的技术,但是要利用抗锯齿边缘和部分透明来用于更详细的图标。

    我知道你在想什么:所有这些PNG透明的东西看起来真的很好,但是它实际吗?

    好消息是,几乎所有现代浏览器都完全支持PNG图像,包括我在示例中充分利用的alpha通道透明度。Safari(所有版本)、Firefox(所有版本)、Opera(6版及更高版本)、Netscape(6版及更高版本)和Mozilla(所有版本)都会很乐意做我要求它做的一切。坏消息是,我没有提到的浏览器是你的用户最有可能使用的:InternetExplorer。

    InternetExplorer6和更低版本不支持PNG格式内置的alpha通道透明度。由于这几年来它一直是绝大多数网络冲浪者的选择(或非选择)浏览器,这个明显的漏洞让许多网页设计师远离PNG。但是,随着InternetExplorer7的发布,我们终于在所有主流浏览器中完全支持PNGalpha透明。此外,还有一些方法可以让alpha透明的png在InternetExplorer6及更低版本中工作。所以,如果你想使用这些效果,没有什么可以阻止你。InternetExplorer6和它的老版本比它应该做的工作多了一点,但这是完全可能的。

    InternetExplorer包括几个专有的过滤器。它们在CSS中使用,但是它们不是任何官方CSS规范的一部分。换句话说,它们不是网络标准。不幸的是,InternetExplorer6和更低版本不完全支持PNG图像格式(W3C推荐),但微软确实包括了一个克服这一弱点的过滤器:AlphaImageLoader。

    简而言之,您可以简单地将AlphaImageLoaderCSS应用于一个img元素,并让它产生想要的结果。这样做将加载图像,透明度保持不变,但也会将图像作为没有透明度的对象的前景内容再次加载(从而模糊您的透明版本)。

    你不能使用一个透明的PNG作为一个(X)HTML元素(比如一个

    )的CSS背景图像,并期望AlphaImageLoader过滤器使它在InternetExplorer中像预期的那样工作。记住AlphaImageLoader在对象的背景和前景之间插入图像。所以,虽然它会加载你的透明图片,但它还是会加载你的CSS背景图片,没有你漂亮的半透明像素。

    让我们回到前面的一个例子,试着让InternetExplorer正确地加载图像。还记得托皮卡的电视台49频道吗?你当然知道。图5-21显示了网站在InternetExplorer6中的样子。

    图5.21。www.49abcnews.com页眉,在Windows的InternetExplorer6中显示,PNG透明度保持不变

    标题的天气部分的HTML看起来像你所期望的那样:

    那么JavaScript文件fixWeatherPng.js中到底有什么呢?看一看:

    window.attachEvent("onload",fixWeatherPng);functionfixWeatherPng(){varimg=document.getElementById("weatherImage");varsrc=img.src;img.style.visibility="hidden";vardiv=document.createElement("DIV");div.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+src+"',sizing='scale')";*//Some49abcnews.com-specificCSSstylingomittedforbrevity.*img.replaceNode(div);}我们来一步步分析这个脚本在做什么。首先,我们告诉浏览器,我们希望在页面加载时运行fixWeatherPng函数。脚本的其余部分是函数本身。

    首先,我们通过图像的id属性找到要处理的图像,并将其存储在一个名为img的变量中。我们将src属性(图像文件的URL)保存在一个名为src的变量中。然后,我们通过将visibilityCSS属性设置为hidden来隐藏img元素。

    接下来,我们创建一个新的div元素,并将其存储在一个名为div的变量中。我们将使用之前保存的src变量中的URL,对其应用AlphaImageLoader过滤器。

    最后,我们用新创建的div元素替换原来的img元素(它是隐藏的),这个元素附加了AlphaImageLoader的优点。

    使用DOM脚本动态插入经过AlphaImageLoader过滤的位有一个好处,就是可以将不必要的无效CSS排除在CSS文件之外。同样,它将无意义的div元素排除在(X)HTML标记之外。由于所有这些都只在条件注释中引用,所以其他浏览器不可能被微软的专有代码所阻塞。

    如果你一定要做一些无效的事情,至少你可以把它抽象出来,和所有不需要它的东西隔离开来。

    PNG作为一种图像文件格式,比广泛使用的GIF提供了许多技术优势。事实上,它的优势如此之大,以至于PNG早就应该成为所有非照片图像的首选文件格式了。但是,InternetExplorer缺乏对PNG的一些更令人兴奋的功能的适当支持,如alpha通道透明性,导致许多web开发人员回避它。但是有两个很好的理由让你不应该害怕巴布亚新几内亚。

    首先,即使InternetExplorer6和早期版本对PNG的支持并不完美,但仍然提供了GIF的所有功能(当然,除了动画)。PNG几乎总是产生更小的文件,以实现更快的传输和更少的带宽使用。

    第二,InternetExplorer7完全支持PNG的alpha通道透明性。不透明度选项的完整范围可以实现的效果实际上是无穷无尽的。我怀疑那些找到使用透明png的有趣方法的设计师们,比如在这一章中概述的那些,将会打开一扇全新的风格之门,这种风格迄今为止还没有在网上广泛出现。我已经给了你一些关于如何用PNGs和透明度来获得创造性的想法,但是不要就此打住。也找到你自己的!

    马克·博尔顿是一名来自英国加的夫的印刷设计师。他曾在悉尼、伦敦和曼彻斯特的设计机构担任艺术总监,为BBC、T-Mobile和英国航空公司等客户服务。马克在BBC做了四年的高级设计师,设计网站和网络应用程序,之后他创办了自己的设计咨询公司马克·博尔顿设计公司。

    他是国际排版设计师协会的活跃成员,并在www.markboulton.co.uk撰写设计期刊。

    网格系统是一个框架。这是一个用来创作作品的系统。放眼望去,你可以看到网格系统:城市街区、杂志、报纸、建筑立面。这是因为我们人类喜欢组织事物,而且,在许多西方文化中,当它们被组织成直线时,我们就能理解它们。因为网格系统,我们知道下一步看什么,下一步按什么或点击什么,下一步做什么。但是网格系统不仅仅是功能性的;他们可以很美。

    一个网格系统可以用黄金分割来设计,这个比例几个世纪以来一直与美感联系在一起。如果某样东西被认为是美丽的,那么根据美学可用性效果,它也更有用。

    网格系统在设计过程中非常重要。它们和排版一起决定了信息的视觉组织。

    在这一章中,我将向你展示我是如何为最近的一个项目设计一个简单的网格系统的。不过,在我开始之前,我觉得有必要简要概述一下网格系统的设计,网格系统是如何产生的,以及它们在过去几十年中所经历的变化。

    没有人真正知道网格系统起源于哪里。有些人会争辩说,自从人类开始创作艺术以来,它们就一直存在。另一些人会说,当人类发展出书面语言时,它们就开始了。然而,我认为它们开始于设计师有意识地开发它们来解决构图问题的时候。我认为,这始于至少从中世纪就开始使用的维拉德图。

    在第二次世界大战之前,网格系统是非常公式化的,简单明了的事情围绕着设备的比例建造的矩形结构,如维拉德图。它们往往受到生产技术的限制,有时会出现被图像打断的文本列。那个时代的网格系统很少使用空白作为设计手段,更不用说多种字体了。直到一些著名的设计师出现,包括挑战当时设计传统的约瑟夫·穆勒-布罗克曼。他们提出了一个新系统:一个更灵活的网格,有更多的工具供设计者使用,称为模块化网格。

    这些设计师思维的重要性不应该被低估。我们所理解的现代印刷术和网格系统设计的大部分都来自于他们。从杂志设计(见图6-1)到网站(见图6-2)的平面设计中,可以看到他们工作的证据。

    图6.1。杂志版面,即使像这样复杂的版面,也使用网格系统来帮助设计者编排页面。

    图6.2。KhoiVinh的Subtraction.com是少数几个使用网格系统取得巨大成效的网站之一。

    比率是任何设计良好的网格系统的核心。那些比例有时候是有理的,比如1:2或者2:3,有时候是无理的,比如1:1.618(黄金分割比例)。设计网格系统的挑战是使用这些比率来创建和谐的组合。

    使用我们选择的度量将比率应用于网格系统。然而,我们在网络上无法控制的一件事是网格位于浏览器窗口的画布上。

    印刷设计的画布大小由媒体大小决定,无论是纸张、标牌、信封还是其他。Web上网格设计的画布大小通常由浏览器窗口大小决定,而浏览器窗口大小又由用户的屏幕分辨率决定。这些都不是固定的。考虑到这种灵活性,设计师应该按照最低要求进行设计,这通常是大多数用户的平均屏幕分辨率。

    随着ListApart(见图6-3)和Stylegala等网站的重新推出,关于1024像素固定宽度网格的讨论又开始了。就实际的网格设计而言,画布的大小真的无关紧要。决定采用1024像素的应该是对用户屏幕分辨率的研究。如果某个网站的用户群显示使用该尺寸或以上的分辨率,那么使用该尺寸进行设计的决定是有效的。

    图6.3。JasonSantaMaria设计的ListApart使用了比标准宽度更宽的宽度。这为您使用网格生成的布局提供了更大的灵活性。

    然而,正如一些人注意到的,即使你运行的分辨率高于800600,这是否意味着你的浏览器窗口占据了整个屏幕?我们不知道。我个人认为,这不仅是特定于平台的,还取决于个人及其经验水平。也许PC上更有经验的用户不会全屏使用浏览器。根据我对各种各样的人进行用户测试的经验,我看到许多PC上的新手用户以全屏方式运行浏览器,因为这是默认的;在Mac上,默认不是全屏幕。

    现在您已经对网格系统有了一些了解,让我们看一个实际的例子。

    2005年春天,国际文凭组织(IBO)找到我,让我设计一个内部网应用程序和一个他们自己开发的新的基于web的应用程序。选择我作为他们的设计师的令人兴奋的原因部分是因为这个项目需要使用Web标准来构建。

    IBO是国际教育领域公认的领导者。IBO目前与122个国家的1,785所学校合作,为超过200,000名3至19岁的学生开发和提供课程计划。为了教很多学生,必须有很多老师,所有这些老师都需要访问文档资料。

    几年前,IBO开发了一个名为在线课程中心(OCC)的教师内部网,IBO教师可以在这里访问和共享文档。在接下来的几年里,OCC在用户和功能方面都有所增长,直到它变得明显需要重新设计。从一开始,IBO就想要新的设计一些新鲜的、现代的、实用的东西。除了OCC,我还被要求为IBO员工设计一个新的在线应用程序,名为“车间资源中心(WRC)”。这是一个复杂的应用程序,车间领导(IBO有带教师的开发车间)可以从库中选择文档,然后将它们转换为pdf进行打印。它的工作方式有点像电子商务系统,将文档添加到用户的“购物车”中,然后签出进行转换和存储。

    正如我所说的,这两个项目都必须使用Web标准构建,选择符合标准的浏览器,谢天谢地,没有包括InternetExplorer5!

    InternetExplorer5可能是一个挑战,正如你将在本书的其他部分看到的,包括EthanMarcotte的第三章。AndyBudd等人(编辑之友,ISBN:1-59059-614-5)在《掌握CSS》中也对浏览器支持问题进行了很好的讨论。

    在查看了简介之后,很明显这个项目的大部分内容都是印刷的。需要整合各种各样的内容类型,其中许多内容类型仍有待创建。因此,排版结构需要清晰简洁。此外,信息需要以四种语言呈现:英语、法语、西班牙语和中文。

    将所有这些字体显示在屏幕上,不仅需要强大的排版层次,还需要强大的网格。

    我喜欢用纸和笔开始每一个设计。这种方法有几个优点。绘图快速、便宜且容易。如果有什么不行,可以把那张纸扔掉,重新开始。你可以乱涂乱画,直到有东西能用为止。此外,与坐在电脑屏幕前相比,使用钢笔和墨水是一个更加有机的过程,可以让想法更快地流动。简而言之,既省时又省钱,还能让你远离电脑!

    图6.4。在你接近电脑屏幕之前进行设计不仅省钱,还能保护你的眼睛!

    我们进行的过程类似于传统的网页设计过程:简要,发现,线框,设计,生产,代码。然而,我在IBO中扮演了更多的伙伴角色。这帮助我彻底理解了组织的业务目标和用户的目标。所以当涉及到设计时,就容易多了。

    一个重要的任务是分解网站的内容对象。现在,这可能看起来像是技术、信息架构,甚至是项目经理的任务。我实际上将内容分析视为设计师任务的一部分。由于这个框架将主要是排版和网格结构,将内容分解到微观层次对于理解它们之间的关系非常重要。我通过识别设计中的元素开始了这个过程。这些可以分解为宏观元素和微观元素。

    宏元素

    宏观元素是设计中的大东西,是所有东西都适合的结构。网格可能位于一个宏元素之上,因为其他元素可以放入其中。这是我为这个项目列出的宏元素列表(见图6-5)。

    桅顶

    主导航

    页脚

    微量元素

    微元素是构成内容其余部分的比特。它们是视觉元素,需要单独考虑,但也需要在更广泛的设计系统中考虑。以下是IBO项目的微观要素(见图6-6):

    框出(侧边栏元素)

    状态框

    列表(有序、无序和定义)

    桌子

    链接

    段落

    形象

    图6.5。可以先绘制宏元素(如柱)的草图。

    图6.6。微距元素位于微距元素的内部和周围,构成了页面的内容。

    你大概可以看到这是怎么回事。这开始看起来像一个CSS文件的结构。

    开发的线框非常复杂。有很多信息需要用户快速理解,其中大部分是排版信息。屏幕上会有很多单词。因此,显示这种类型的网格需要仔细考虑。

    遵循我在本章前面讨论过的一些基本原则,我开始绘制较大的网格元素,即柱。三列布局是Web上一种流行的网格配置,这也许是有充分理由的。

    三分法是一个合成法则。事实上,它更像是一个指南,主要由摄影师使用,但可以应用于平面设计。三分法则指出,将空间水平分成三份(如果你使用图像,也可以垂直分成三份),并使你的设计与这些线条对齐,可以创造更多的能量和张力。它帮助设计者从创造有趣的作品中去掉一些猜测。

    根据三分法,我创建了一个六列网格。图6-7显示了我的笔墨渲染,图6-8显示了我在Photoshop中创建的版本。

    然后,可以将这些列划分为多个布局配置,如图图6-9所示。正如你所看到的,这里的布局选项对于大多数网站和应用程序来说是足够多样的。

    图6.7。最终六列网格草图

    图6.8。显示色谱柱配置和尺寸的最终表格

    图6.9。从六列网格中可以获得许多成分配置。此处显示的示例不仅说明了不同的列配置,还显示了这些列的相对视觉重点。

    你可能已经注意到在我最初的网格设计中没有水槽。

    檐槽是柱子之间的缝隙。它们在那里,所以不同列的文本或图像不会碰到一起。在网格系统设计中,有时(取决于你阅读的理论),檐槽与柱子是分开的。由于我们构建列的方式,这给我们在Web上设计网格系统带来了实际问题。

    通常,但不总是,我们使用Web标准创建的列是divs,它们使用CSS给定宽度、位置和样式。因此,理想情况下,我们不希望为檐槽创建单独的列。因此,我们将檐槽作为列的部分(参见图6-10),并且它们是通过填充或者创建边距来实现的,用于放置在列内的元素或者有时是列本身。

    图6.10。本例中的檐槽是柱的一部分,而不是位于柱之间。

    我总是选择向列中的元素添加填充。这可能意味着当我写样式表时,我最终会为自己创造更多的工作。我可以简单地添加一个空白。但是这样做可以确保当我想让元素相互碰撞时,我可以做到。这也避免了InternetExplorer的盒子模型问题,但由于在这个设计中它不是一个受支持的浏览器,我不必太担心这个问题。

    所以,我有我的专栏全部六个。现在我可以开始添加水平元素,如页脚和报头。但在此之前,我需要解决一个重要的排版测量问题。

    对于这个项目的构建,要求用户能够选择固定或灵活的布局。在固定布局中,列将由像素测量来确定,因此是固定的。在灵活布局中,百分比将用于列,而ems将用于排版。

    图6.11。10px的装订线现在变成了1em,因为我已经将正文的字体大小定义为62.5%。

    这使得1em大约为10px(16除以100乘以62.5等于10),这是一个很容易处理的度量单位。现在我们可以把像素大小等同于ems。例如,设置为14px的文字可以表示为1.4em,9px的文本可以表示为0.9em,依此类推。

    当我将它添加到body标记中时,我还添加了全局空白重置,它删除了所有浏览器默认的边距和填充。

    通过使用CSS通用选择器*,我能够选择HTML文档中的所有元素,然后移除所有默认的填充和边距。

    这个项目的所有颜色和图形元素都由另一个单独的样式表控制。这是因为网格、版式和许多元素的基本样式(比如无序列表、定义列表和图像)需要在整个站点中保持不变,因为整个站点有两种不同的配色方案。很简单,用灰色设计,简单地根据网站覆盖颜色。

    向容器div中添加一个类来控制各种布局选项。这个三列布局有一个类c1-c2-c3,但是布局选项是为各种各样的布局创建的,比如c1、c1-c2、c1-c2-c3-c4-c5等等。这个命名约定告诉我两件事:六列网格中使用的列数以及文档顺序。例如,c1-c2-c3可能看起来和c2-c1-c3一样,但是文档顺序会不同:带有c2的id的

    会出现在c1和c3之前。

    总而言之,OCC有六种不同的样式表:

    全局样式表

    IBO样式表,控制所有顶级颜色

    用户可配置的布局样式表

    一个排版样式表,它的元素是用户可配置的

    颜色样式表,控制整体颜色

    出于辅助目的的替代缩放布局

    这被证明是该设计最具挑战性的方面之一。

    一旦我有了网格的想法,我就开始考虑如何使用Web标准来构建它。首先,我构建了一个粗略的XHTML模板,开始开发CSS。

    在任何多栏布局中,一个重要的考虑因素是文档顺序。在这一阶段,你应该试着把网格的外观放在一边,把注意力集中在文档的内容流上。先获取内容;稍后添加CSS。

    所以,我开始添加线框中规定的各种元素。一、实用程序菜单:

    报头包括几个重要的元素:组织的名称、您所在的服务(或站点)以及语言切换(这两个站点有四种语言版本)。

    我尽量避免使用在意义上是表象的类名。例如,我可以将刊头命名为topbar、topnavigation或类似的名称,但这意味着一个表示性的位置,所以,masthead就是这样。

    一旦我有了这两个元素,我需要将它们包装在一个容器div中,我将使用这个容器来定义网格的宽度,包括固定模式和灵活模式。

    然后,我可以在报头后面添加列。出于演示的目的,我在这里添加了虚拟内容。

    Somecontentgoeshere

    Somecontentgoeshere

    Somecontentgoeshere

    我这里有三列,分别是从c1到c3的id。也许,从语义上来说,这些不是列的最佳名称,但是在命名约定中不要太抽象,我认为这是说明这一点的最佳选择。此外,出于开发目的,它们很容易记住,这在六列网格有数百种布局可能性时非常重要。

    现在我有了HTML结构的基本框架。我有一个刊头和三个栏目。

    图6.12。XHTML。目前还没有应用CSS,但是这个阶段对于显示文档顺序非常重要。

    我现在正处于网格发展的阶段,我需要移动东西。我总是发现首先开发一个基于固定像素的网格更容易,以确保我所有的比例都正确,并且构图正常。我在这方面使用的一个小技巧是由KhoiVinh在他的优秀网站www.subtraction.com上首次描述的。还记得我在Photoshop里做的网格图(图6-8)吗?在网格的整个开发过程中,我导出网格并将其作为背景添加到容器div中。

    #container{background:url(img/grid_background.gif);}我现在有了一个网格的可视化表示(见图6-13)来开始对齐元素。网格可能是复杂的野兽,所以拥有一个可以如此容易地从模板中添加和删除的视觉参考对我们设计师来说真是一个好消息。

    图6.13。使用网格作为背景图像允许我将所有元素对齐到它。

    设定容器的宽度

    我通常从外部元素向内开始构建CSS。我首先设置容器的宽度div。

    图6.14。网格居中

    设置列宽

    接下来,我使用浮动来定位列。首先,我向左浮动#c1和#c2,向右浮动#c3。

    #c1{float:left;width:250px;}#c2{float:left;width:250px;}#c3{float:right;width:250px;}这会将列定位在背景图像的网格标记上。为了确保这一点,我给每个div添加了不同深浅的灰色作为背景色(见图6-15)。

    图6.15。三列

    一旦对齐正确,我就移除列中的灰色,为了这个例子的目的,我给列增加一个高度,以显示当div中有内容时网格将如何延伸。

    设计标题和语言菜单的样式

    报头只是向左浮动,宽度设为100%,以确保div一直延伸。

    #masthead{float:left;width:100%;background:#000;margin:1em000;}正如你在HTML中看到的,语言菜单只是一个带有language的id的

      。首先,我给它一点填充,这样文字就不会碰到浏览器窗口的顶部。这是以像素为单位设置的,不像我所有其他的排版尺寸,都是以ems为单位设置的,因为我不希望这个值在文本调整大小时改变。我希望它在右边,所以我将整个列表向右浮动,并给它一个none的list-style,以去掉子弹。

      #languageli{float:left;padding:01em01em;border-right:1pxsolid#fff;}然后我把链接变成白色,以突出黑色。我将用一个单独的颜色样式表覆盖这个默认颜色,但是我总是发现用黑白颜色开始开发更容易。

      #languagelia{color:#fff;}注意我发现首先用黑白设计有助于澄清我正在做的设计决定。如果颜色不是问题的一部分,那就把它去掉,下次再考虑。

      图6-16显示了布局中的报头。

      图6.16。添加报头。现在布局真的成型了。

      设计可访问性和服务菜单

      我用对待语言菜单的方式来对待可访问性和服务菜单中的列表。我将

    • 元素向左浮动,并给它们填充和一个none的list-style:

      #accessibility{float:left;list-style:none;padding-top:15px;}#accessibilityli{float:left;padding:01em01em;border-right:1pxsolid#ccc;}#services{float:right;list-style:none;padding-top:15px;}#servicesli{float:left;padding:01em01em;border-right:1pxsolid#ccc;}我还在这些列表的顶部添加了一些填充。请再次注意,这是以像素为单位的固定填充。调整文本大小时,我不希望此值改变。

      #branding{float:left;text-align:left;margin:1em001em;padding:001em6em;background:url(ibo_logo.gif)no-repeat00;}右侧填充如此之大的原因是为了容纳IBO标志,当我开始添加颜色和圆角时,我会马上添加它。

      使用ems确定标题的大小。给h1一个相当于14px的值,给h2一个相当于18px的值。

      #brandingh1{font-size:1.4em;}#brandingh2{font-size:1.8em;font-weight:bold;}然后我把链接涂成白色。

      #brandingh1a,#brandingh2a{color:#fff;}图6-17显示了这些增加的内容。

      图6.17。添加品牌和菜单。在这里,我添加了IBO标志作为报头的一部分,和其他菜单一起。

      事情现在开始看起来更像一个网站。我坚持我建立的网格,设计开始感觉正确。

      现在我已经有了基本的列结构和报头,我添加一些示例内容:标题、链接、段落和无序列表。我仍然是黑白的,所以我可以专注于对齐网格,并确保排版处于良好的工作状态。

      接下来,我开始给报头添加颜色(通过一个单独的彩色CSS样式表)。

      最后,我给列中的元素添加了一些边距,以创建一些水平对齐。

      这个项目面临许多挑战。这是一次重新设计,所以有遗留的内容,品牌方面的历史,以及所有重新设计带来的一定程度的用户期望。这些都是必须考虑的。

      CSS是一个特殊的挑战。不过,原因可能出乎你的意料。你以为我会说ie浏览器有问题,对吗?啊哈!不,那不是问题所在。

      作为一名设计师,我很幸运能为一个梦想中的客户工作,他基本上会说,“哦,忽略不符合标准的浏览器。”当然,我问他们是否确定。起初,我不太明白这是为什么,但我很快意识到这是因为在推荐和支持的软件方面,我们面对的受众非常有限。在IBO中,Firefox实际上是推荐的浏览器。当然,对于IBO的读者来说,InternetExplorer仍然是主流浏览器,但是我使用Firefox作为主要浏览器来开发设计,以确保代码尽可能符合标准。后来,我将注意力转向了InternetExplorer6,并添加了变通方法以确保它也能在该浏览器中工作。很高兴目标浏览器允许我将黑客攻击保持在最低限度。

      在这一章中,我没有涉及CSS黑客。为什么呢?嗯,我认为它们超出了这里的范围,可能会混淆对构建网格的解释。如果您的设计需要,您可以在中添加hacks。在这本书里有更多关于黑客的内容,CSSMastery(ED之友,ISBN:1-59059-614-5)包含了关于黑客的全面信息。

      正如我所说的,这个项目的挑战是如何管理CSS。

      这个网站的定制选项非常丰富。所有这些选项都将保存到用户配置文件中,这意味着系统必须记住用户保存的字体大小、布局等等。概要规定用户必须能够改变布局(固定或灵活)和字体大小。此外,还有一个为视障人士设计的缩放布局。除此之外,两个站点,OCC和WRC,都必须共享相同的元素,比如网格和排版;唯一的区别是颜色。如果所有这些都要使用不同的样式表来解决,这是一个复杂的问题。

      克服这些问题并不容易,但是由IBO和我自己承担的项目过程对我帮助很大。有规格,线框,用例,和概念所有你在这样规模的项目中期望的文档。然而,这个过程很小,而且与客户很亲密。一次又一次的重复。我想说,一起解决问题是这个项目真正的成功之处。

      我在这里创建的是一个简单的网格系统,而不仅仅是列。

      对于不经意的观察者来说,这只不过是使用标准250像素宽的三列布局。然而,我仔细地构建了网格,考虑到我使用这个六列网格系统的所有组成选项。这允许各种各样的布局选项,重要的是,这些选项相互关联。

      为了子孙后代,也为了让你了解新设计的根本不同,我提供了一些截图来显示之前和之后的状态。图6-18和6-19为OCC现场,图6-20为WRC现场。我肯定你会同意,新网站远远超过旧网站。

      图6.18。前世的OCC

      图6.19。新的OCC设计通篇使用CSS布局,并为用户提供改变字体和大小的选项,并为视障用户提供高对比度布局。

      图6.20。新WRC与OCC共享许多基本样式表。唯一的区别是不同的colour.css,它覆盖了基础colour.css。

      www.robweychert.com

      RobWeychert是一名平面设计师、艺术家、作家和思想家,以其对细节神经般的一丝不苟而闻名。自20世纪90年代末以来,Rob一直为娱乐、旅游、医疗保健、教育、出版和电子商务等不同行业的客户提供印刷和交互式平面设计解决方案。

      像所有的艺术一样,它(印刷术)基本上不受进步的影响,尽管它也不能不受变化的影响。

      罗伯特·布林赫斯特,

      排版风格的要素

      印刷术有着丰富而传奇的传统,就像大多数艺术形式一样,它的制作过程进展缓慢。

      自15世纪古腾堡发明了具有里程碑意义的活字印刷术(一种由金属雕刻而成的单个字母组成的印刷方法)之后,印刷术技术直到工业革命才出现重大变化。随后的照相排字机和Monotype机以及(相对短命的)照相排字工艺本质上是同样古老的印刷方法的更快、更有效的模型。然而,麦金塔在1984年将字体和设计引入数字时代是一种激进的新方法的培养。然后,不到十年后,就在平面设计师开始习惯于印刷的数字制作工具时,一种全新的媒介被推给了他们。

      万维网是一种革命性的获取信息的方式,因此,它需要一种不同的方式来思考设计。然而,随着几个世纪的印刷传统被抛在身后,以及相对较新的计算机的采用,大多数设计师很难考虑除了印刷以外的任何东西,而且HTML从未打算适应平面设计也没有帮助。网站的另一半是由计算机爱好者设计的,无论是专业的还是业余的。他们对网络令人兴奋的潜力有了更好的理解,但对视觉设计原理知之甚少或一无所知。

      网页设计的早期黑暗时代就这样过去了。语义的、灵活的文档看起来一点也不好,好看的文档一点也不语义或灵活。跨越世纪之交,对标准化web技术的更大重视旨在解决这个问题。

      今天,在网络越来越复杂的初期,它的大部分排版仍然是软绵绵的。

      本章旨在通过将印刷排版丰富的视觉传统与网络排版激动人心的动态功能相结合,来帮助阻止这种趋势。我将展示他们可能会在哪里汇合,他们应该在哪里同意不同意,以及仅仅几个简单而微妙的排版技术如何给页面注入新的生命。

      设计者对于在网络上设置字体的第一个抱怨似乎是跨平台可用的字体数量很少。虽然这可能会令人沮丧,但重要的是要记住,选择字体只是排版设计的一个方面。印刷世界中一些最好的印刷工把他们的武器库限制在几个他们通过反复学习和使用而非常熟悉的字体上。即使适用于网络的有限的字体选择确实提供了较少的多样性,它也迫使我们保持同样的良好习惯。幸运的是,一些可用的面孔是为屏幕设计的最好的例子。对这些字体的深刻理解,包括它们的创造者和历史背景,对我们使用它们大有裨益。

      如果你怀疑一个漂亮的设计可以用一种普通的字体来实现,我希望这一章能改变你的想法。我要讲的大部分内容将使用Georgia,这是微软在1993年委托著名字体设计师MatthewCarter设计的衬线字体。根据一项正在进行的代码风格网站调查(www.codestyle.org/css/font-family/sampler-CombinedResultsFull.shtml)的最新结果,Georgia出现在大约91%的MAC、84%的PC和53%的Unix系统上,使其成为世界上最普遍的衬线字体之一。谢天谢地,这也是一个出色的设计。

      乔治亚很像TimesNewRoman(图7-1vs.Georgia(bottom)")),是仅有的分布较广的衬线字体之一。像泰晤士报新罗马,格鲁吉亚是一个永恒的设计,体现了几个不同的历史时期的审美和实用的特点。然而,就我们的目的而言,乔治亚在屏幕上胜过泰晤士报新罗马,因为那是它被设计来显示的地方。

      图7.1。泰晤士报新罗马(上)对佐治亚(下)

      通常,当创建数字字样时,其印刷形式优先。首先绘制文字形状的轮廓,然后基于这些轮廓绘制小文本大小的位图版本(为了在屏幕上清晰,以防它会出现在屏幕上)。换句话说,与分辨率无关的设计被改造成极低的分辨率。结果各不相同,但在许多情况下,小文本在屏幕上几乎难以辨认。在格鲁吉亚问题上,卡特决定逆转这一进程。因为这种字体主要是为屏幕设计的,所以首先绘制位图(8到12点大小),然后绘制轮廓以适应它们(图7-2)。这为基于屏幕的衬线字体带来了前所未有的优雅清晰度,这种分类因其模糊性而臭名昭著。

      图7.2。佐治亚州轮廓vs佐治亚州位图

      马修·卡特被选中承担这项任务绝非偶然。他是一位著名的字体设计师和印刷历史学家的儿子,20世纪50年代末,他开始在金属上切割原始设计和经典字体的复刻,然后继续共同创立了著名的Bitstream和Carter&Conedigitaltypefoundries。基于他几十年的经验,令人印象深刻的客户名单(包括时代杂志、纽约时报和华盛顿邮报)和大量工作(最著名的是贝尔百年纪念,以及后来的屏幕上的Verdana),很少有人能声称更有资格设计一种永恒、清晰的字体,用于屏幕上,但仍然植根于传统。

      好了,现在你已经掌握了乔治亚是如何、为什么以及何时产生的,你已经准备好用一个实际的例子来使用它了。让我们建造一些东西!

      为了展示一些可能性,我为恐怖片的原创大师埃德加·爱伦·坡做了一个小小的主页。基本布局由宽度大致相等的四列组成。两个中间的列组成了主要的内容区域,左侧是导航列,右侧是侧边栏列。页眉和页脚横跨四列的整个宽度。

      图7.3。示例项目

      以下是标记的简化版本:

      用于Windows的InternetExplorer6和7

      适用于Windows和Macintosh的Firefox1.5

      适用于Windows和Macintosh的Opera9

      用于Macintosh的Safari1.3和2.0

      因为这一章的重点是排版,案例研究的某些方面在这里就不讨论了,但是在其他地方有详细的记录。其中包括RogerJohansson的一般页面布局的弹性设计方法(“固定宽度还是可变宽度?有弹性!”www.456bereastreet.com/archive/200504/fixed_or_fluid_width_elastic/)和道格拉斯·鲍曼(DouglasBowman)的滑动门技术,用于展开标题和导航(“CSS的滑动门”,www.alistapart.com/articles/slidingdoors/)。

      我将讨论的大部分技术集中在案例研究的主要内容领域(#main)。这一节将演示其比例是如何设计的,以及这些比例对布局其余部分的影响。

      的数目。。。

      由于#main是页面层次结构中最重要的元素,我想确保它具有适当的焦点权重,并且可读性最大化。第一步是确定线条长度的宽度。单列中可读文本集的标准范围是45到75个字符(包括空格)。这个范围允许行以合理的增量断开,防止它们变得太长或太短而不便于阅读。许多排字工人认为大约66个字符的行是理想的,我也是其中之一,所以这个例子将使用这个宽度。这是一个关键的比例,我想确保它尽可能保持良好,这将是如何将页面放在一起的一个重要因素。

      好吧,我们承认:这本书打破了这里多次概述的行长惯例,但我们有我们的理由。这主要是因为我们不仅要处理文本,还要处理代码段;如果你不得不把代码分割成几个片段来适应页面,代码行的可读性会变得很差。

      如果我使用的是液体布局,线条长度会根据用户浏览器窗口的宽度而增减(图7-4)。另一方面,如果我使用固定宽度的布局,当用户调整浏览器文本的大小时,行的长度会增加或减少,如果浏览器窗口比我的页面指定的宽度小,水平滚动的可能性也存在(图7-5)。由于对这两个选项都不满意,我选择了弹性布局,这给了我两全其美的选择(图7-6,butalsocontractswiththewindowtoavoidhorizontalscrolling(right)."))。

      布局将随着文本大小或浏览器大小的调整而扩展和收缩,但不会扩展超过指定的宽度。这里的折衷方案是,我的行会随着浏览器窗口的收缩而变短,但太短的行比太长的行更容易阅读,也是水平滚动的一个令人愉快的替代方案。

      图7.4。流动布局:当浏览器窗口扩大时,许多人会发现这一行太长,阅读起来不舒服。

      图7.5。固定宽度布局:如果浏览器窗口太小,水平滚动是必要的。

      图7.6。弹性布局,扩展和收缩:当浏览器窗口扩展(左)时,行长度保持所需的比例,但也会随着窗口收缩以避免水平滚动(右)。

      全能的em

      弹性布局的秘密武器是em。在印刷和网络世界中,em是字体大小的正方形,基于其最宽字符的宽度或其最低下行字母(如小写字母p的词干)到其最高上行字母(如小写字母b的词干)或发音符号(图7-7)的距离。在CSS中,em基于父元素的font-size。因此,如果我在ems中指定我的布局的宽度,它将随着文本大小的调整而扩展和收缩,保持文本大小和行长度之间的比例,从而保持我的66个字符的行完整无缺。

      图7.7。一个乔治亚em

      我的布局的弹性将适合大多数桌面浏览器分辨率,但我仍然希望它的预期比例(图7-8)在800600浏览器窗口中舒适地放置,因此740px的原生页面宽度是谨慎的。为了在ems中指定这个宽度,我必须做一些数学计算。

      图7.8。近似布局比例

      我的主要内容区域(#main)需要有66个字符的宽度,这也需要是布局全宽(#wrap)的50%左右。如果我用ems中指定的宽度设置一个Georgia文本块,计算几行中的字符数(包括空格),然后用这些行的平均值除以文本块的宽度,我会发现Georgia对一个em来说平均是2.2个字符。因此,一个66字符的度量应该是30em,这将使#wrap成为60em。如果我用740像素除以60,我得到12.3像素,然后瞧!我有一个font-size。

      但是有一个问题。InternetExplorer不会使用以像素为单位指定的font-size来调整文本的大小。幸运的是,现代浏览器对关键词的渲染相当一致,我知道font-size:small的分辨率大约是13px。有了这个数字和一点点数学知识,我可以在我想要的结果范围内达到比例。

      首先,我需要重新计算#wrap的宽度,因为它是基于我的font-size的,现在它有点大了。如果我用740像素除以13像素,#wrap的新宽度(四舍五入)是57em。为了保持我的66字行,#main的宽度将保持为30em,这是#wrap宽度的53%(再次取整)。最后,考虑每列2%的页边距将得到图7-9所示的比例。

      图7.9。最终布局比例

      翻译

      带着自鸣得意的简单,CSS简洁地显示了我如此努力和冗长地确定的比例:

      body{font-family:Georgia,"TimesNewRoman",Times,serif;font-size:small;}#wrap{max-width:57em;}#nav{width:19%;margin-right:2%;}#main{width:53%;margin-left:2%;margin-right:2%;}#about{width:19%;margin-left:2%;}图7-10展示了结果:一个可读性很强的文本块,其比例将保持合理预期的一致性。关于在CSS中使用ems的另一种方法,参见第六章“网络网格设计”

      图7.10。#main一个可读行的长度为

      现在#main有了一个舒适的宽度,我将把注意力转向其中的段落。自从段落元素出现以来,web浏览器通常使用默认的下边距来呈现段落元素,通常在1em到2em之间。这就产生了段落之间空行的效果,这种习惯在印刷中肯定不是没有过。然而,在印刷中很可能看到的是一种在网络上相对罕见的描绘惯例:段落缩进。

      空行有时会破坏连续的文本,段落首行的缩进可以标记新的段落,同时保持文本的连贯性。不过,在网络上应该谨慎使用。段落缩进作为空行的替代方法在打印时效果很好,因为文本还有其他物理拆分方式,如多列和分页。网络上的冗长写作偶尔也会给读者的眼睛一种空行所能提供的放松,因此,在简洁的陪伴下,网络上的段落缩进是最快乐的。

      由于只有三个简短的段落,#main是段落缩进的完美候选。我只需要做两件事:

      缩进除第一段以外的所有段落的第一行。

      去掉那些空行。

      简单缩进

      一个既能缩进段落又能去掉空行而不修改标记的非常简单的方法是这样做:

      p{text-indent:2.1em;margin:0;}缩进2.1em在我的文本块中雕刻出一个正方形(图7-11),看起来很棒。不幸的是,尽管结果很完美,但是这个CSS规则缩进了我的第一段。除了缩进之外,在段落之间使用空行是多余的,同样,缩进文本中的第一段也是多余的。两种形式的描述一前一后只会强调重点,就像添加一些大的红色文本,上面写着,“看,一个新段落的诞生!”好吧,也许没那么糟,但我还是不想做。

      图7.11。每个段落缩进都有一个空格。许多排字工人认为正方形是理想的缩进。

      不完美世界中的相邻选择器

      使用相邻选择器是我合乎逻辑的下一步:

      p{margin:0;}p+p{text-indent:2.1em;}p+p相邻选择器将只处理紧接在另一个段落前面的一个段落。理论上,这正是我想要的,因为第一段明显没有另一段在前,因此会忽略这条规则。在一个完美的世界里,这会完成手头的任务,我现在应该在酒吧了。遗憾的是,InternetExplorer6不支持相邻的选择器,现在它将我的所有段落呈现为一个模糊的斑点。

      *当我在整理我的个人网站时遇到类似的问题,我是这样解决的:

      p{text-indent:2.1;margin:0;}h2+p{text-indent:0;}所讨论的内容区域以两个标题开始:一个标题(h1)和一个日期戳(h2),然后是第一段(p)。h2+p相邻兄弟选择器在兼容的浏览器中实现了预期的效果,在InternetExplorer中实现了缩进的第一段,这是在标记不可更改的情况下的必要妥协。

      在我目前的情况下,这不是一个可行的选择,因为#main的第一段前面没有另一个元素,但也没有什么能阻止我稍微改变标记。我只需要给第一段一个类first:

      Firstparagraphcopygoeshere.

      然后在我原来的CSS中再添加一条规则:

      p{text-indent:2.1em;}.first{text-indent:0;}任务完成(图7-12)!

      图7.12。具有优雅段落缩进的内聚文本块

      这个文本块的形状很好,但是还需要一点点。这种排版风格的最后两个要素包括创造性地使用大写字母,这将为页面增添足够的视觉趣味来完成设计。

      首字下沉是一种被称为versal的书写形式,这种书写传统可以追溯到欧洲中世纪时期最早的照明手稿(图7-13)。一个versal的目的是庄严地介绍文本。首字下沉通过显著放大段落的第一个字母并在前几行为其留出空间来做到这一点。

      图7.13。15世纪70年代晚期的一页小时书,一种常见的照明手稿

      作为另一个优雅的保险措施,我的读者会立即被#main要说的话吸引,首字下沉将非常适合这一页。

      以下是我希望首字下沉包括的属性:

      正文应该换行。

      它应该是文本大小的六倍左右。

      顶部应该与第一行文本的顶部齐平。

      左侧应该与文本的左侧保持齐平,但右侧和底部应该有一个小的边距,以避免与文本对接。

      不完美世界中的伪元素

      因为我直接处理第一段中的第一个字母(它已经有了一个类first),所以使用CSS:first-letter伪元素选择器是一个合理的起点。因此,我的首字下沉规则将被发送到p.first:first-line,并且很容易从我的期望属性列表中逐行翻译出来。

      p.first:first-letter{float:left;font-size:6em;line-height:.75em;margin-right:.1em;margin-bottom:.1em;}难得的是,这段代码在我测试过的所有浏览器中都呈现出合理的一致性,除了Mac版Firefox的,它神秘地在首字下沉的顶部和底部插入了额外的空间(图7-14)。再怎么摆弄line-height、padding或margin也不会让它在不同浏览器中表现一致,如果段落以em或strong(或span,我稍后会添加)这样的行内元素开头,结果会更加不同。遗憾的是,我不得不尝试不同的解决方案。

      图7.14。火狐:first-letterbug

      跨越到救援

      对加价的另一个小调整将是必要的。我将我的O包装在一个span(带有一个drop类)中,如下所示:

      October7,1849...

      我给这门课的规则和以前完全一样,就像这样:

      .drop{float:left;font-size:6em;line-height:.75em;margin-right:.1em;margin-bottom:.1em;}有效!我的首字下沉已经到位(图7-15)。

      图7.15。一款纯CSS格鲁吉亚首字下沉

      图像替换

      但是我还是不开心。尽管我很爱乔治亚,但那个大乔治亚还是不太适合我。这一页需要一些更具装饰性的东西,所以我创建了自己的华丽首都O(图7-16)。这种字体大致基于波多尼字体,这是一种精致的现代衬线字体,在爱伦坡出生前一年设计。

      图7.16。我的定制versal

      我将使用图像替换技术,而不是把我的通用图像放在标记中。

      我使用的特殊图像替换技术只是众多技术中的一种,其中大部分是由DaveShea在他的mezzoblue.com网站(www.mezzoblue.com/tests/revised-image-replacement/)上编辑的。虽然我在这个例子中推荐这个方法,但是其他的方法可能更适合不同的情况,我建议对它们进行复习。你也可以在第二章“用CSS、Flash和JavaScript驯服野生CMS”中找到更多关于图像替换技术的内容

      图像替换正如它所说的那样:它用图像替换元素的HTML文本。在这个例子中,它将通过使用负的text-indent从元素中吸出文本,然后放入我的versal图形作为背景图像来完成。

      .drop{width:83px;height:83px;float:left;text-indent:9999px;background-image:url(o.gif);background-repeat:no-repeat;background-position:topleft;margin-right:.1em;margin-bottom:.1em;}我的浮动和边距与前一个例子相同,我的文本负向缩进到另一个星系,宽度和高度的值对应于我的通用图形的宽度和高度。它在我测试的所有浏览器上都很棒,除了InternetExplorer。那个浏览器选择了负缩进我的整个段落,而不仅仅是我的span,导致段落完全消失(图7-17)。

      图7.17。InternetExplorer文本缩进错误

      .drop{width:83px;height:83px;display:block;float:left;text-indent:9999px;background-image:url(o.gif);background-repeat:no-repeat;background-position:topleft;margin-right:.1em;margin-bottom:.1em;}我定制的首字下沉已经到位了(图7-18)!

      图7.18。我闪亮的首字下沉

      我对我的首字下沉很满意。然而,让我的段落从如此夸张的介绍直接变成小得多的小写文本在视觉上有点不协调。我将用最后一点改进来解决这个问题,之后#main将准备好与公众见面。

      如果你没有在排版世界里学过,你可能已经在网络世界里学过了,尤其是在电子邮件和即时消息中:用全部大写字母设置的文本应该非常谨慎地使用。大写锁定键的错误组合会给你的观众留下你在对他们大喊大叫的印象,这不是让他们回来的最好方法。记住这个规则,所有的大写字母仍然可以发挥很大的作用,有节制的使用将在我巨大的首字下沉和它引入的小得多的正文之间建立一个逻辑桥梁。由于我的日期戳October7,1849(爱伦坡的死亡日期)已经作为一个简洁、独立的文本开头,所以它是一个完美的全大写处理的候选。

      您的第一反应可能是在标记中设置全部大写的文本,从而避免我将要描述的更加费力的CSS过程。这不是一个好主意,原因有很多,其中最主要的是您以后可能希望对文本进行不同的样式化。如果这是一个用来构建许多页面的模板,那么在一个CSS文件中更改一个规则要比在几十个(或者几百个或者几千个)HTML文档中更改标记容易得多。此外,正如您将在下面的示例中看到的,在设置所有大写文本时,可能需要考虑更多的内容,而不仅仅是在大写锁定状态下键入。

      首先,我将最后一个span添加到我的标记中,作为日期戳的目标:

      October7,1849:Loremipsum...

      现在,我只需要两个简单的、不言自明的CSS规则来使我的datestamp类以期望的方式运行:

      .datestamp{text-transform:uppercase;letter-spacing:.13em;}给text-transform一个值uppercase将确保我的文本全部大写。它还可以取值lowercase(所有小写文本)和capitalize(每个单词的第一个字母大写)。至于letter-spacing,当文本全部大写时,一点额外的字母间距是易读性的关键。通过少量的实验,我发现非常精确的0.13em测量对于这种情况是理想的(图7-19)。

      图7.19。#全大写的美因日戳格鲁吉亚

      我的段落介绍看起来不错,但是我还有最后一条鱼要钓。让Georgia如此珍贵的原因之一是,它是唯一一种在网络上广泛使用的字体,包括文本数字(有时被称为旧式数字)(图7-20vs.TimesNewRoman'stitlingfigures(bottom)")),本质上是小写数字。就像小写字母一样,文字数字的上升和下降对正文的破坏性比大写字母要小,称为标题数字。理想情况下,字体将包括文本和标题图,但通常只包括后者。Georgia有一个奇怪的区别,它只包含文本数字,因此,我的大写日期戳包含小写数字。这不行。

      图7.20。佐治亚州的文字数字(上)与泰晤士报新罗马标题数字(下)

      泰晤士报新罗马,其相似性和格鲁吉亚和包括所有权的数字,是这个问题的完美解决方案。此外,我发现TimesNewRoman的所有大写字母比Georgia的所有大写字母略轻一些。通常情况下,我会避免在同一个文档中使用如此相似的字体,但是在这种情况下效果很好,因为这里的想法是创造一个一个字体的假象。再有一个简单的CSS规则,#main将最终完成(图7-21):

      图7.21。#main完成

      我还选择了一个排版元素,应用在Poe主页右侧的#about段落中。我希望第一行以小型大写字母出现。

      #about的基本标记和#main非常相似。

      公平警告

      对于外行人来说,小型大写字母很容易被误认为是大写字母的缩略版本。但是,在一个设计良好的字体中,小大写和大写字母是分开画的,两者的细微差别保持了字母笔画粗细的一致性(图7-22,thefullcap(center),andthetruesmallcap(right)."))。真正的小型大写字母在小字体时更容易阅读,并且不会扰乱文本的流动,而仿小型大写字母(例如,8点大写字母设置在一组12点字体中)几乎总是引人注目和分散注意力。

      图7.22。请注意仿小笔帽(左)、全笔帽(中)和真小笔帽(右)之间的笔画宽度差异。

      当面对下面一组CSS规则时,web浏览器会将指定的文本设置为乔治亚斜体,这当然是一种不同于Georgia常规字体的设计,而不仅仅是一种倾斜的斜体。

      font-family:Georgia;font-style:italic;然而,如果我要添加一个规则font-variant:small-caps,文本不能设置为真正的小型大写字母,因为格鲁吉亚没有提供。同样,绝大多数最广泛、公开传播的数字文本字体不包括一组小型大写字母。因此,web浏览器默认使用仿小型大写字母。在Quartz(MacOS)和ClearType(Windows)等屏幕字体平滑技术出现之前,这并不是什么大问题,因为人造小型大写字母的比例差异的微妙之处被像素化字母的低分辨率所取代(图7-23vs.smoothedsmallcaps(bottom)"))。然而,随着屏幕字体平滑变得越来越普遍,我们不能再依靠浏览器来掩盖自己的印刷错误。仿小型大写字母现在在屏幕上看起来和印刷时差不多。

      图7.23。像素化小型大写字母(上)与平滑小型大写字母(下)

      虽然早在网络出现之前,假的小型大写字母就已经成为合法的嘲笑对象,但可以说它们在网络上是可以接受的,因为真正的小型大写字母还没有出现。尽管它们可能很显眼,但它们仍然有能力增强和丰富页面。是否使用它们是你自己的决定。

      不完美世界中更多的伪元素选择器

      我最后一次尝试使用伪元素选择器以心痛告终(还记得:first-letter?),但是,为了小盘,我准备再试一次,这次用:first-line。不出所料,:first-line会影响其目标元素的第一行文本。在这种情况下,目标元素将是#about的第一段。

      这可能是合理的推理,但InternetExplorer和Safari不会听进去。每一种都有自己的缺陷,阻碍了预期效果的发生。InternetExplorer不会认可font-variant和text-transform规则的任何组合,Safari也不会认可应用于伪元素选择器的text-transform规则。因此,InternetExplorer和Safari都将标记的大写字母显示为全大写。Firefox和Opera可以正确显示文本。

      特别是Safari的bug使得我想要的效果不可能在不同的浏览器上一致地呈现,因为它是我在这里尝试使用的伪元素选择器first-line和文本转换规则lowercase的组合。因此,要避免对我的标记进行进一步的更改,并确保我的小型大写字母只保留在文本的第一行,这需要一个折衷方案:InternetExplorer和Safari将显示一个可能混合了全大写字母和仿小型大写字母的包。看着完成的页面(图7-24),我想我绝对可以做得更差!

      图7.24。所有的努力都是值得的!

      毫无疑问:印刷世界和网络世界是不同的地方,各有各的特点。不过,它们至少有一个非常重要的共同点,那就是它们的存在是为了帮助人们交流。虽然我们应该承认并尊重这样一个事实,即在印刷上对一方有效的东西对另一方可能无效,但我们也应该尊重读者,他们可以从许多技术中受益,这些技术的效用与任何一种媒体都没有必然的联系。我在这一章中概述的技术应该已经给了你一个很好的想法,让你可以在网上激活类型。*

      伊恩最近为SitePoint写了他的第一本书,名为使用HTML&CSS以正确的方式构建你自己的网站(在这本书中,他向完全的初学者教授基于Web标准的设计)。

      我正坐在办公桌前忙着某件事,这时我的同事对我说,“有没有什么方法可以让你的网页只打印某个特定的部分?”

      “哦,是的,”我回答说,“这很容易,你可以用打印CSS样式来做到这一点。您想打印页面的哪一部分,不想打印哪一部分?”

      “嗯,那要看情况,”他回答道,准备抛出众所周知的曲线球。“我们有很长很长的利率页,但根据这个人的账户,他们会希望打印不同的部分。”

      我仔细考虑过了。我记得在一些浏览器上,可以选择页面的一部分,然后只打印那一部分,这是在Print对话框中提供的一个选项,但这并不理想,因为它要求用户知道这个选项的存在。此外,它并不是在所有浏览器上都可用。对于技术人员来说,可以使用一个油滑的猴子【1】脚本来打印一个给定的选择,但这可能只占我们预期受众的0.001%。我的同事想要的是浏览器没有以任何明显的格式提供的东西。所以我告诉他,“对不起,你不能这么做。恐怕除非他们知道突出显示某个部分,然后选择“打印选择”,否则这是不可能的。”

      然后我回到我当时在屏幕上推动的像素。然而,这个想法一直萦绕在我的脑海里。我个人很讨厌你想打印一页的一个部分,结果却打印了七页废话,其中六页马上就被扔掉了。难道没有办法解决这个问题并减少浪费的打印输出吗?然后我想到了:打印CSS的混合;一些好的、可靠的语义标记;一些不引人注目的JavaScript可能正好达到他的目的。所以我开始进行概念验证。

      对于任何具有可能需要单独打印的特定部分的给定页面,比如促使我进行调查的利率页面,使用JavaScript动态切换显示属性(也就是说block或none),但是对于打印视图,仅切换。

      这项技术的其他目标包括

      这项技术必须不引人注目。【2】它应该符合渐进式增强的类别,【3】并且所有的行为都应该从一个共享的JavaScript文件进行控制。

      一定要好看,不仅仅是工作。

      它必须基于完全干净和有效的标记。

      这项技术的目的需要对用户来说非常明显。

      令人欣慰的是,所有这些目标都是可以实现的,我将在接下来的几页中展示这一点。

      有了一个清晰的最终目标和一些明确的目的,我开始着手一个简单的概念证明。这是视觉效果看起来有点难看的过程的一部分,但功能部分得到了解决,所以不要担心,我会在本章的后面让它看起来很漂亮。我知道最终的目的是什么(将它应用到冗长的利率页面上,该页面需要切割以供打印),但首先,我创建了一个包含基本内容的虚拟页面。

      这项技术的关键是知道你想打印和不想打印的页面部分。在我看来,这可以使用CSS类来完成,显而易见的选择是使用类名section,或者,如果你想让它的用途非常清楚,使用类似于print_section的类名。【4】所以,这里有一个简单的HTML页面,包含一些部分

      图8.1。分割页面,准备打印

      这将是访问者将看到的基本页面(忽略我用于虚拟页面的占位符内容)。现在的诀窍是在那些浏览器的基础上增加额外的好的层次,这些浏览器正在进行工作渐进增强。

      Section1

      Thisissection1\.Nothingmuchtoseehere,justabunchofmeaninglesswords.

    Section2

    Thisissection2\.You'dbebetteroffwatchingpaintdrythanreadingthecontenthere.

    Section3

    Thisisthefinalsection.Hurrah!

    这暂时不会对事物的视觉方面产生影响,但是它将提供我们JavaScript行为所需要的钩子。现在让我们来看看它的具体细节。

    在本章的前面,我用简单的英语描述了这种技术应该做什么。现在我将转向伪代码的世界,描述这里将要发生的事件的顺序。

    浏览器开始加载页面,并在包含所有行为规则的外部.js文件中包含一段JavaScript。当页面加载后,JavaScript启动并执行以下操作:

    首先,它遍历整个文档寻找div元素并创建一个数组

    接下来,它一个接一个地遍历这个由div元素组成的数组。如果div元素的类名为print_section,它会执行以下操作:

    它会创建一个按钮或链接,显示“打印此部分”或类似内容。

    然后,它对该按钮应用一个行为。单击时的行为是首先检查被单击链接的id。如果id与当前节匹配(当浏览器浏览文档中所有可打印的节时),使该节可见(在打印视图中)。如果单击的链接的id不匹配(当浏览器搜索文档中所有可打印的部分时),它会隐藏当前部分(同样,仅用于打印)。

    在浏览器中调出Print对话框,如图图8-2所示。不幸的是,要避免这一步并让它直接印刷是不可能的。用户仍然可以再单击一个按钮。在图8-2中的Firefox示例中,是OK按钮。

    图8.2。打印前出现Print对话框。

    页面上的单个低速加载元素会延迟这种效果的原因是因为JavaScript在页面加载后运行。这是因为一旦页面上的所有内容都被下载了,所有链接到其他位置的图像、脚本和CSS文件都会发生onload事件,而不仅仅是页面的标记。

    这就是虚拟页面的攻击计划。让我们看看一些真正的代码,它们将帮助我们实现这一目标。

    addEvent功能启动网页。它告诉浏览器它需要运行什么(哪个JavaScript函数)和什么时候运行(在什么事件上,例如,当页面加载时或者当某个东西被点击时)。这是:

    functionaddEvent(elm,evType,fn,useCapture){if(elm.addEventListener){elm.addEventListener(evType,fn,useCapture);returntrue;}elseif(elm.attachEvent){varr=elm.attachEvent('on'+evType,fn);returnr;}else{elm['on'+evType]=fn;}}如果你觉得这看起来像天书,不要担心。你不需要理解它做的每件事或如何做。您只需要知道它是为了解决一些跨浏览器JavaScript问题而创建的,它允许您使用三个参数来调用它:

    你在处理什么元素(elm)

    事件是什么(点击、加载、聚焦)(evType)

    当元素触发了事件时,您希望它执行什么JavaScript函数(fn)

    这是一个你如何称呼它的例子:

    addEvent(window,'load',addPrintLinks,false);或者,说白了,当window(或者更准确地说,这个窗口中的文档)已经loaded时,请运行addPrintLinks功能。这个函数还没有建立,所以为了测试它是否工作,我暂时在这里放了一个简单的警告:

    functionaddPrintLinks(){alert("Here'swherethecoolstuffwillhappen");}addEvent(window,'load',addPrintLinks,false);警报看起来像图8-3。

    图8.3。动作中的警报占位符

    列出了完成这项工作所需的步骤之后,让我们来看看将完成这项工作的实际代码(我将引用我前面的描述):

    浏览器开始加载页面,并在包含所有行为规则的外部.js文件中包含一段JavaScript

    在前面的例子中,我展示了嵌入页面本身的脚本。现在是时候将脚本放在它们自己的文件中,并在网页中引用它们了,就像这样:

    这是我们之前提到的AddEvent部分。addEvent函数应该在.js文件中,正如下面对该函数的调用一样:

    addEvent(window,'load',addPrintLinks,false);".。。JavaScript启动并执行以下操作:

    首先,它遍历整个文档寻找div元素并创建一个数组。"

    functionaddPrintLinks(){varel=document.getElementsByTagName("div");for(i=0;i

    接下来,它一个接一个地遍历这个由div个元素组成的数组。如果div元素的类名是print_section。。."

    functionaddPrintLinks(){varel=document.getElementsByTagName("div");for(i=0;i

    然后,它对该按钮应用一个行为。"

    实现这些目标需要相当多的JavaScript,下面是(在适当的地方有注释解释每个部分在做什么):

    点击时[链接的]行为是首先检查被点击的链接的id。如果id与当前部分匹配(当浏览器浏览文档中所有可打印部分时),使该部分可见(在打印视图中)。如果点击链接的id与不匹配(当浏览器搜索文档中所有可打印的部分时),它会隐藏当前部分(同样,仅用于打印)。

    在浏览器中调出Print对话框:"

    使用以下几行脚本附加了链接的行为:

    newLink.onclick=togglePrintDisplay;newLink.onkeypress=togglePrintDisplay;这意味着当点击链接或者当链接获得焦点并且检测到按键事件时,浏览器应该运行一个名为togglePrintDisplay的新函数。

    添加行为

    我们来看看togglePrintDisplay函数里有什么。我将首先一次性展示所有内容,然后逐一解释各个组成部分,解释发生了什么:

    functiontogglePrintDisplay(e){varwhatSection=this.id.split("_");whatSection=whatSection[1];varel=document.getElementsByTagName("div");for(i=0;i

    varbtId="printbut_"+el[i].id;当然,使用更短的变量名是可能的,但是我这里的目标是可读性。请注意,id不能以数字开头;因此,我在id值中使用了下划线。这使得以后检索该值变得非常容易,如下面的代码片段所示。我们使用一个split函数,在下划线处进行分割。这创建了一个包含两个值的数组:printBut和我们真正想要的部分,在下面的例子中是sect2。

    这两个值被传入一个变量whatSection。不过,我们真正想要的只是数组的第二部分。因为数组从0开始,所以使用[1]引用数组中的第二项;因此,我们使用whatSection[1]获得我们想要的信息。该值随后被传递到whatSection变量中(覆盖其先前的数组值;whatSection现在不再是数组,变成了字符串)。

    functiontogglePrintDisplay(e){varwhatSection=this.id.split("_");whatSection=whatSection[1];现在我们已经有了要寻找的id,我们需要再次浏览文档,寻找所有的div元素,特别是类名为print_section的div元素:

    varel=document.getElementsByTagName("div");for(i=0;i

    el[i].removeAttribute("className");if(el[i].id==whatSection){//ifthisisthesectiontobeprinted,seta'print'classnameel[i].setAttribute("className","print_sectionprint");el[i].setAttribute("class","print_sectionprint");}else{//otherwisehidethesectionfromprintoutel[i].setAttribute("className","print_sectionnoprint");el[i].setAttribute("class","print_sectionnoprint");}}}注意,这里似乎需要加倍努力:同时设置class属性和className属性。这是解决InternetExplorer和其他浏览器处理事物的方式之间的差异的一种变通方法。这不是一个大的开销,几乎不值得创建一个新的自定义函数来处理它(如果你愿意,你可以这样做)。

    另一个解决方案可能是动态地编写按钮而不是链接。然而,这本身就存在一些问题。首先,这可能会限制您的样式选项(与button或submit类型的输入相比,您对link元素有更多的CSS控制)。其次,这其实不是一种形式,对吧?如果您动态地编写表单按钮,您需要在它周围包装一个表单元素。此外,如果是一个表单,您应该使用按钮或提交类型的输入?毕竟,没有提交表单数据进行处理。所以,我选择了主播。有人开枪打我吗!

    最后,我们调用Print对话框。所有的类名都被改变了,这影响了它们的显示,所以我们已经准备好了:

    window.print();}//endofthetogglePrintDisplayfunction将新链接写入文档

    不过,我们还没有完成。从addPrintLinks函数调用了togglePrintDisplay函数,第一个脚本还没有完全完成。有一件小事,就是在网页加载后将按钮(包含在段落中)插入网页。这是通过这条线实现的:

    el[i].insertBefore(newLinkPara,el[i].firstChild);概述:这些脚本的作用现在我们差不多完成了。所以来回顾一下:

    页面加载,addPrintLinks运行。

    addPrintLinks调用另一个函数togglePrintDisplay,在这里设置行为。

    当为每个所需的元素设置了行为后,addPrintLinks恢复,将新的链接追加到web页面中。

    以下是完整的脚本:

    .print_sectionp.printbutton{float:left;}.print_sectionp.printbuttona{text-decoration:none;background:white;display:block;float:left;margin:3px;padding:10px;border:1pxsolidred;}mediaprint{.noprint,.printbutton{display:none;}.print{display:block;}}通过包含在mediaprint后的花括号内,样式被限制为打印显示。因此,显示样式的切换不会影响屏幕视图(或其他媒体类型)。

    将所有这些缝合在一起,最终的结果看起来像图8-4。

    图8.4。完成的原型页面

    如果点击OK按钮,将只打印页面的一部分。在这个例子中,它是第二部分,正如Firefox中的打印预览功能所展示的那样(见图8-5)。

    图8.5。打印一个部分的功能正在工作!

    在我们从概念验证阶段进入实际应用之前,有一个小问题需要解决。考虑一下这个场景:

    如果用户点击了一个Printthissection链接,然后点击了Cancel,会发生什么?也许用户最终想要打印整个页面?

    如果您检查各种事件何时被触发以及它们做了什么,您会注意到有一个问题。通过在第一次激活一个打印部分按钮后单击浏览器的打印按钮,只有部分部分将被打印。这是因为CSS显示已经设置好了,浏览器的打印按钮不会对此产生影响。

    一个解决方案是写出两个链接:一个写着printthissection,另一个写着printthewholepage。这个想法是为了阻止人们转向他们的浏览器打印按钮,如果他们刚刚使用了printthissection按钮。或者,您可以创建另一个函数,当某个可预测的事件发生时,将每个部分的显示重置为默认值。例如,这可能发生在当鼠标指针经过页面标题区域时,如果它从页面的一部分移动到浏览器的顶部,这几乎肯定会发生,如图图8-6所示。

    图8.6。使用mouseover事件重置显示,该事件检测用户是否被浏览器的打印按钮吸引

    下面是我的第一个解决方案所需的代码(为每个部分添加第二个打印按钮的更简单的解决方案)。在addPrintLinks功能中(粗体显示的附加内容):

    functionprintAll(e){varel=document.getElementsByTagName("div");for(i=0;i

    修改后的概念验证页面现在看起来像图8-7。

    图8.7。完成的原型页面,进行了改进

    请注意,您可以将为每个部分添加一个printthewholepage链接的想法与我之前提出的关于当鼠标经过标题区域(或类似区域)时重置打印区域以显示所有内容的建议结合起来,这是众所周知的“带括号”方法。

    嗯,您已经看到了该技术背后的理论,并且在一个基础页面上看到了它的演示,但是该技术的实际应用呢?正如我在本章开始时提到的,灵感来自一位同事,他问当打印的人可能只对利率的一部分感兴趣时,是否真的需要打印整页利率。图8-8显示页面。

    图8.8。如你所见,这是很长的一页!

    在概念验证的例子中,我将所有的函数放在一个单独的.js文件中。这包括了addEvent功能。如果你有可能在整个网站中不止一次地使用addEvent功能,最好将.js文件分成两部分:

    一个包含addEvent函数的文件(它可以在站点的任何地方用于任何目的)

    另一个包含打印处理函数的文件(因为它只需要在得到这种打印处理的页面上调用)

    标记现在有了必要的钩子,脚本可以抓取并写入打印链接。但是这些看起来怎么样?嗯,比概念验证中显示的要好得多!图8-9显示了上下文中链接的建议设计。

    图8.9。打印链接设计

    不出所料,这个设计是在Photoshop中完成的,但很大程度上是关于如何构建的想法。在图8-9的例子中,链接按钮可以使用图像来创建(脚本需要修改,以便写出img元素而不是文本)。图8-10显示了两种方法:第一组链接是背景图片上的HTML文本,第二组基于img元素。

    图8.10。创建链接按钮的两种方法

    为了建立在概念验证阶段并进行对等翻译,我将展示如何使用CSS背景图像和真实文本的组合来实现这一点,而不是使用img元素。

    重要的:我应该警告你,这种方法的缺点是,当你在页面上放大文本时,按钮的背景图像不会相应地放大,文本可能会脱离按钮区域,如图8-11所示。编写一个img元素可以解决这个问题,但是我会把这个问题留给你去试验(真的,改编脚本来做这件事并不困难!).

    图8.11。当文本位于按钮顶部时,在InternetExplorer中放大到最大尺寸的效果

    不管链接采用什么方法,都需要应用一些CSS。在概念证明中,我使用了一个段落,其中包含了两个链接。这可以用来包含一个背景图像(图8-10中的灰色部分包含一个打印机),而链接本身需要背景。图8-12显示了组成部件。

    图8.12。用于设计打印链接样式的背景图像和按钮

    在查看CSS之前,简单回顾一下:这些按钮的HTML(一旦通过JavaScript生成并插入到DOM中)完全符合概念验证。此处显示的粗体标记是将动态生成的部分:

    p.printbutton{background-image:url(print-button-para-bg.gif);background-repeat:no-repeat;background-color:#576374;float:right;padding:6px0040px;}#sect1p.printbuttona{background-image:url(print-button-bg.gif);background-repeat:no-repeat;padding:2px0;margin:010px00;color:white;text-decoration:none;width:110px;height:19px;font-weight:bold;font-size:x-small;display:block;float:left;text-align:center;}齐心协力脚本已经被插入到文档头中,生成的链接的样式已经被定义,页面已经应用了所有必要的id来使技术工作。图8-13显示了在屏幕上看到的最终结果(在Firefox的Windows版本中)。

    图8.13。完成的网页

    啊,那个!我说我会回到主题,这是所有关于节约纸张,避免不必要的打印输出。有了你在本章中看到的JavaScript魔法,用户现在可以只打印他们感兴趣的部分,这就是证据。首先,图8-14显示了在“之前”应用脚本之前页面的打印输出结果

    图8.14。唷,这么多纸!

    并且图8-15显示了应用脚本“after”后的结果

    图8.15。好多了!

    眼尖的人会注意到,出现在页面上用于有选择地打印某些部分的控件没有显示在打印输出上。你为什么需要打印出来?您不能单击它们或在纸上做任何事情,所以这些动态生成的控件在打印样式表中被关闭,如下所示:

    如果我能从这个练习中得出一个结论,那就是很容易因为浏览器做不到而放弃一个想法。有了DOM、CSS和JavaScript,您可以定制构建功能以适应各种创造性的想法,并为长期存在的浏览器问题提供解决方案,这些问题看起来永远无法解决。网络上的印刷品经常被忽视,但事实并非如此。一些微调可以走很长的路。而且在这个过程中还可以拯救一两棵树,这都是好的。

    【2】不引人注目的脚本在HTML中不需要内联事件处理程序,比如onclick或onmouseover。所有的脚本都是集中的,使得站点范围的管理和维护更加容易(类似于使用共享样式表集中管理站点的表示)。

    【4】如果我们使用XHTML2.0,我们可以选择使用section元素。更多信息见www.w3.org/TR/xhtml2/mod-structural.html#edef_structural_section。标记(仅应用少量CSS来帮助识别边界):

    卡梅隆·亚当斯有一个法律学位和一个科学学位。很自然,他选择了web开发这一职业。当被追问时,他自称为“网络技术专家”,因为他喜欢参与图形设计、JavaScript、CSS、Perl(是的,Perl)以及那天早上他喜欢的任何东西。他经营自己的公司,为政府部门、非营利组织、大公司和小型创业公司工作过。

    除了帮助他的客户名单,卡梅伦还在全国各地的许多研讨会上授课,并在世界各地的会议上发表演讲,如媒体和网络方向。他在2006年发布了他的第一本书,JavaScript选集,这是关于现代JavaScript技术最完整的问答资源之一。

    卡梅伦住在澳大利亚的墨尔本,在马拉松比赛间隙,他喜欢踢足球,为愤怒的邻居混音。

    即使在同一台设备上,不同的用户也有不同的需求。访问者来你的网站做不同的事情,你的界面应该能够适应所有这些。您希望能够为用户提供适合其所选设备和用途的最佳体验。

    很明显,不同的设备有不同的显示能力。这一点在比较移动设备(如PDA)和它们的桌面兄弟时表现得最为明显。PDA的分辨率可以低至240320,而桌面显示器可以高达20481536甚至更高。即使在台式机上,分辨率的差异也是惊人的。你的父母可能正在浏览一个(现在是史前的)800600系统,而你的超级用户姐姐正在浏览一个1280960屏幕。两者之间的差异是巨大的,可用面积增加了150%以上。并且每一种的设计要求同样不同。将宽屏和双屏系统组合在一起,可能性就会爆炸。

    有了如此大的差异,说“好吧,创建一个适用于所有分辨率的流畅布局”就不再可行了我们在这里讨论的是页面布局方式的根本区别。分辨率越高,人们看到的信息就越多,因此您的设计应该考虑到这一点。分辨率越低,人们看到的信息就越少,您的设计也应该能够处理这种情况。

    问题是,如果你试图让你的设计一刀切,你会遇到不可调和的分歧。在1280960中,四列文本可能会为你的内容产生最简洁、最有条理、最可见的结构,但是给一个800600显示器上的人四列文本只会产生一团乱麻。相反,在800600时工作得相当舒适的单栏设计在1280960时看起来会痛苦地拉伸。

    传统上,一个答案是简单地限制页面的宽度,将其锁定在一个固定的宽度,在800像素(或您选择的基本分辨率)或以上的宽度下产生良好、可读的行长度。然而,这往往不公平地限制了那些利用高质量技术的人。分辨率较高的用户从他们的投资中得不到任何好处;他们只是在内容的两边获得了更多的空间。

    最近的统计(www.thecounter.com/stats/2006/August/res.php)表明,屏幕分辨率为800600的用户约占市场的16%,约55%的用户分辨率为1024768,约21%的用户分辨率高于1024768(任何特定网站的实际统计数据将因受众而异)。通过设计800600的分辨率,你在为少数人的情况惩罚你的大多数用户,尽管是相当大的少数人。

    那么,有没有一种方法可以让大屏幕用户从辛苦获得的像素中受益,而不损害低分辨率用户的利益呢?是的,通过提供不同尺寸的不同设计。

    起初,这可能听起来工作量过大。但是由于基于标准的布局的灵活性,很可能甚至很容易使用完全相同的HTML标记并通过改变CSS提供不同分辨率的不同设计。

    通过比较UX杂志(www.uxmag.com)和白皮书(www.whitepages.com.au)网站的不同布局,如图图9-1到图9-4")所示,你可以看到,页面的设计美学不必为了适应不同的浏览器大小而有很大的改变。大多数情况下,只需对主要内容区域进行重组,就足以创建更流畅的布局,最大限度地利用屏幕空间。针对更宽屏幕优化的布局通常会降低页面高度,从而在折叠上方显示更多内容,使用户无需滚动即可看到页面的更多部分。假设你的标题、菜单、表单和其他网站附件都是用一些漂亮的、健壮的CSS编码的,它们应该很容易适应任何一种设计。

    图9.1。UX杂志网站布局针对800600的最大化浏览器窗口进行了优化

    图9.2。UX杂志网站布局针对1024768的最大化浏览器窗口进行了优化

    图9.3。针对较窄的浏览器窗口(宽度小于1200像素)优化的白页网站布局

    图9.4。针对更宽的浏览器窗口(宽度大于1200像素)优化的白页网站布局

    尽管窗口大小通常与屏幕分辨率有关,但两者并不相同。浏览器窗口不一定要最大化,所以不能假设浏览器大小会和屏幕分辨率匹配。根据轶事证据,1024768和更低分辨率的用户倾向于用最大化的窗口浏览,而分辨率更高的用户更有可能用多个未最大化的窗口进行多任务处理。

    我在这里提出的解决方案没有基于屏幕分辨率的假设(即使它被称为依赖于分辨率的布局)。我们的目标是浏览器窗口的布局,所以如果大屏幕上的用户碰巧在小窗口中浏览,他们仍然会得到最佳的小窗口布局。

    与任何替代样式表一样,首先需要定义基本样式。你的目标是哪个基线人群?目前,800600通常被认为是最低的普通桌面分辨率,所以我们将使用它作为我们的默认大小。

    接下来,您需要决定哪个(些)决议将获得一个替代样式表。什么分辨率会从不同的布局中获得最大的好处?您可以为许多不同的分辨率提供许多不同的布局,但是为了简单起见,我们将只创建一个备选样式表。我们将使用1024768作为备用布局的开关。它不像800600到12801024那样激进,但仍然提供了足够的空间来保证布局的改变。

    图9-5显示了我们的基本设计,针对800600进行了优化。它是流动的,所以它也适用于较小的屏幕。图9-6显示了我们针对1024768和更高分辨率的设计。

    图9.5。针对800600优化的示例页面

    图9.6。针对1024768优化的示例页面

    这两种布局之间有两个主要变化:

    较大样式的内容呈现在页面的四列中,而较小样式的内容保持在一列中。四列布局可以在更高的分辨率下更好地利用空间,并降低页面高度。在较小的屏幕尺寸下,列变得太窄而没有用,因此单列产生更好的内容宽度。

    菜单的位置不同。当使用水平菜单时,随着菜单项数量的增加,我们经常会在较小的屏幕上遇到问题。最终,它们会绕成两行。为了解决这个问题,我们将菜单的方向从水平改为垂直,并将其放置在内容旁边。

    使用CSS,通过修改宽度和浮动元素,可以相对容易地实现这两种改变。例如,在800600中,三个主要内容面板都使用其默认的浏览器样式:跨越其容器100%的块元素。为了让它们在1024768样式表中并排排列,我们让它们向左浮动并提供一个宽度:

    .panel{float:left;width:26.5%;}这两种布局都使用了包含在resolution.htm中的完全相同的HTML标记,所以您只需要修改样式表。

    因为备用样式表是主样式表的补充,所以我们继续对800600样式表进行编码,就像我们通常所做的那样,无论如何它都会被应用。为了获得更宽的样式表,我们扩展了基本样式。我们不需要编写一个全新的样式表;我们只是修改和增加已经存在的风格。

    正如您将在本例的可下载文件中看到的,基本样式表main.css有442行。另一个样式表wide.css要小得多,只有190行。

    为了在页面上包含两个样式表,我们使用了link元素:

    但是当我们需要它的时候,我们如何打开替换样式表呢?

    我们有几个选项可以向用户提供这种新的依赖于分辨率的样式表,其中大多数都非常无效:

    在HTML中包含替代样式表,并希望用户使用的浏览器允许在替代样式表之间切换,并且意识到有替代样式表,然后会费心打开它,如果它适用于他(不会发生)。

    自动做。将更宽的样式表提供给能够处理它的浏览器。给用户最好的体验,而不用动一根手指。

    在resolution.js中要做的第一件事是检查浏览器窗口的大小:

    checkBrowserWidth();functioncheckBrowserWidth(){vartheWidth=getBrowserWidth();if(theWidth==0){addLoadListener(checkBrowserWidth);returnfalse;}if(theWidth>=960){setStylesheet("Wide");}else{setStylesheet("");}returntrue;};checkBrowserWidth()首先使用getBrowserWidth()获得浏览器的宽度:

    functiongetBrowserWidth(){if(window.innerWidth){returnwindow.innerWidth;}elseif(document.documentElement&&document.documentElement.clientWidth!=0){returndocument.documentElement.clientWidth;}elseif(document.body){returndocument.body.clientWidth;}return0;};实际上有几种方法可以确定浏览器窗口的宽度,这取决于你使用的浏览器,而getBrowserWidth()中的每个条件都符合其中一个。火狐、Mozilla、Safari、Opera使用window.innerWidth。InternetExplorer6和7使用document.documentElement.clientWidth。

    奇怪的是,document.documentElement.clientWidth在InternetExplorer5和5.5中存在,但它总是被设置为0,所以我们必须检查这一点,如果是这样的话,就默认为document.body.clientWidth。唯一的问题是body元素必须在InternetExplorer5之前存在。x可以计算出浏览器窗口的宽度,所以一旦页面被加载,我们必须重新安排对getBrowserWidth()的调用。这是在checkBrowserWidth()里面的第一个条件下完成的。如果getBrowserWidth()返回0,说明浏览器很可能是InternetExplorer5。x,所以我们创建了一个新的load事件监听器,并在进行任何样式表切换之前等待页面加载。

    addLoadListener()是一个通用的页面加载事件处理程序,它抽象了浏览器事件处理中的一些差异:

    functionaddLoadListener(fn){if(typeofwindow.addEventListener!='undefined'){window.addEventListener('load',fn,false);}elseif(typeofdocument.addEventListener!='undefined'){document.addEventListener('load',fn,false);}elseif(typeofwindow.attachEvent!='undefined'){window.attachEvent('onload',fn);}else{returnfalse;}returntrue;};这个和另一个抽象的事件处理程序包含在event_listeners.js中,因为您可能会在其他项目中经常用到它们。

    然而,大多数浏览器不需要经历繁琐的页面加载。checkBrowserWidth()将立即收到浏览器宽度,并能够检查它。这是通过一个简单的条件来完成的,我们对照预定值检查theWidth。在我们的例子中,我们使用960作为阈值,因为对于分辨率为1024768的最大化窗口大小来说,这是一个很好的安全值,如果我们减去浏览器chrome(如滚动条)的空间。如果您希望您的样式表以不同的分辨率更改,只需将该值更改为您需要的值。

    如果窗口宽度大于或等于960像素,我们通过使用适当的样式表标题调用setStylesheet()来激活替代样式表,在本例中是Wide:

    functionsetStylesheet(styleTitle){varlinks=document.getElementsByTagName("link");for(vari=0;i

    该循环完成后,所选的替代样式表将被打开,而所有其他样式表将被关闭。如果浏览器宽度不大于我们的阈值,则使用相同的函数。我们用一个空字符串("")调用setStylesheet(),这将关闭所有可选的样式表,因为它们的标题都不匹配。

    一旦所有这些都发生了,正确的样式表将被选择,页面现在应该以适合用户浏览器大小的最佳布局显示。

    最后要做的事情是添加一个事件侦听器,以便在有人调整浏览器窗口大小时使用。当某人第一次访问一个页面时,检测浏览器的大小是很好的,但是如果他改变了窗口的大小,我们就要相应地改变布局。为此,我们只需为窗口调整大小事件添加一个事件监听器,再次调用checkBrowserWidth():

    attachEventListener(window,"resize",checkBrowserWidth,false);同样,这里我使用了一个通用的事件处理程序(来自event_listeners.js),它抽象了浏览器事件处理中的一些差异:

    functionattachEventListener(target,eventType,functionRef,capture){if(typeoftarget.addEventListener!="undefined"){target.addEventListener(eventType,functionRef,capture);}elseif(typeoftarget.attachEvent!="undefined"){target.attachEvent("on"+eventType,functionRef);}else{returnfalse;}returntrue;};针对InternetExplorer5.x的优化如前所述,InternetExplorer5。x浏览器在获得浏览器宽度之前必须等待页面加载。交换样式表时,这可能会导致一点视觉闪烁。为了在某种程度上改善这一点,我们可以设置一个cookie,在用户第一次访问网站时存储浏览器宽度,然后在重复加载时使用这个值。这样,用户只会在第一次访问时得到一个闪烁。为此,我们需要修改checkBrowserWidth():

    functioncheckBrowserWidth(){vartheWidth=getBrowserWidth();if(theWidth==0){varresolutionCookie=document.cookie.match(/(^|;)res_layout[^;]*(;|$)/);if(resolutionCookie!=null){setStylesheet(unescape(resolutionCookie[0].split("=")[1]));}addLoadListener(checkBrowserWidth);returnfalse;}if(theWidth>=960){setStylesheet("Wide");document.cookie="res_layout="+escape("Wide");}else{setStylesheet("");document.cookie="res_layout=";}returntrue;};现在,一旦浏览器宽度已经确定,样式表已经切换,我们还设置了一个名为res_layout的cookie来存储应用的样式表的标题。在重复访问时,如果浏览器宽度返回为0(即,它是InternetExplorer5。x,我们检查res_layout的cookie值是否存在,如果存在,立即相应地设置样式表。这消除了闪烁。我们仍然继续添加调用getBrowserWidth()的负载监听器,所以如果用户在设置cookie后碰巧改变了浏览器的大小,我们可以将布局调整到新的宽度。

    根据用户的浏览器大小提供静态的布局选择是一回事,但是让用户个人控制他们在你的页面上看到什么以及他们在哪里看到它是另一回事。

    模块化布局为用户提供了一个视觉和行为框架,允许他们从根本上改变界面在网页上的实时显示方式。一旦设计者将内容划分为独立的内容模块,这些模块就可以被展开和折叠,它们的顺序可以被重新组织,它们在页面上的位置可以被用户改变。

    图9.7。模块化布局示例的默认视图

    图9-8显示了一个修改后的界面视图,在用户通过折叠、重组和移动的组合按照自己的喜好重新排列模块后。

    图9.8。模块化布局示例的用户自定义视图

    我们使用的例子反映了各种门户页面。用户可能会定期访问该网站以查看不同类型信息的集合,某些信息的重要性因用户而异。

    所有的界面定制都必须用JavaScript来完成。这意味着不支持JavaScript的用户代理将无法访问定制功能。这些用户将收到页面的默认视图,并能够访问所有信息,就像它是一个普通的静态网页一样。

    页面内容的高层结构相当简单。左侧的数据模块包含在各自的部分中,接着是中心内容,然后是右侧的更多数据模块:

    ...

    ...
    ...
    这里要注意的最重要的事情是,如果用户将内容从一个模块区域移动到另一个模块区域,它必须被放置到适当的容器中。

    网页的HTML不必严格遵循modular.htm的模板。然而,示例中使用的JavaScript和CSS是为该标记定制的,需要根据特定页面的布局方式进行调整。

    在每个模块区域内,我们使用一个带有类module的div将每个模块分成它自己的部分:

    扩展和折叠内容的能力并不是一个新概念,实际上非常简单。也许我们能做的最重要的事情就是让它不引人注目,容易接近。

    另一方面,没有打开JavaScript的用户不应该被提供他们无法访问的功能。这意味着允许展开/折叠的元素应该通过JavaScript本身来包含。

    JavaScript

    当页面上包含expand_collapse.js时,它会设置一个页面加载监听器,然后遍历每个模块并插入适当的HTML元素:

    initExpandCollapse()首先创建感兴趣的模块元素的数组,然后遍历该数组,找到所有的h2元素。对于每个h2,我们创建一个新的anchor元素,它包含一个img元素(我们的小展开/折叠图标),然后我们对那个anchor应用一些行为。通过使用一个anchor元素而不是span或div,我们确保了展开/折叠功能是键盘可访问的。anchor元素可通过键盘聚焦,当用户按下回车键激活它们时,会收到一个点击事件。

    我们在anchor标签上捕捉两个事件:鼠标按下和点击。mousedown侦听器需要抵消我们将用于拖放内容模块的mousedown。本质上,我们想要监听anchor上的点击,但是每当有人点击鼠标按钮时,它之前也会有鼠标按下。因为anchor在h2内部,这将触发h2的mousedown事件,所以我们需要在anchor的mousedown事件触发时取消h2的mousedown事件。这是通过mousedownExpandCollapse():完成的

    functionmousedownExpandCollapse(event){if(typeofevent=="undefined"){event=window.event;}if(typeofevent.stopPropagation!="undefined"){event.stopPropagation();}else{event.cancelBubble=true;}returntrue;};这个简短的函数主要是为了避免浏览器在事件处理上的差异。第一个条件检查一个event对象是否被传递给了函数本身。这通常由事件侦听器自动完成,但在InternetExplorer5中不会发生。x。如果事件对象不存在,我们默认为window.event,也就是InternetExplorer5。x用途。

    接下来,我们检查event对象方法stopPropagation()是否存在。这是阻止事件向上冒泡的W3C标准方法(也就是说,阻止anchor上的mousedown事件也在h2上注册)。如果stopPropagation()存在,我们称之为。然而,InternetExplorer使用名为cancelBubble的event对象的专有属性来停止事件冒泡。如果stopPropagation()不存在,我们就把event.cancelBubble设为true,这也是一样的效果。

    现在我们需要处理点击事件。您可能已经注意到,为了向anchor添加mousedown事件监听器,我们使用了来自依赖于分辨率的布局attachEventListener()的抽象函数,但是对于click事件,我们实际上使用了一个旧的事件处理程序,即onclick属性。因为Safari不允许我们停止使用W3C事件侦听器添加的默认点击事件操作,所以我们需要恢复到点属性。实际上,这不会造成太大的问题。我们将事件处理程序添加到由我们自己的脚本创建的元素中,因此它不应该附加任何其他可能冲突的事件信息。

    点击事件处理程序指向的函数是clickExpandCollapse():

    functionclickExpandCollapse(){if(!hasClass(this.parentNode.parentNode,"collapsed")){addClass(this.parentNode.parentNode,"collapsed");}else{removeClass(this.parentNode.parentNode,"collapsed");}returnfalse;};这在包围着h2的div上做了一个简单的类切换。如果那个div没有collapsed的类,我们添加这个类。如果它有一个collapsed类,我们删除这个类。这使得完全通过CSS来设计折叠和展开模块的不同视图变得容易。

    在处理clickExpandCollapse()中的元素类时,我们总是使用这些自定义函数:hasClass()、addClass()和removeClass()。这使得在同一个元素上使用多个类名变得更加容易。我已经将这些函数包含在它们自己的库文件class_names.js中,所以它们可以很容易地包含在其他项目中:

    functionhasClass(target,classValue){varpattern=newRegExp("(^|)"+classValue+"(|$)");if(target.className.match(pattern)){returntrue;}returnfalse;};functionaddClass(target,classValue){if(!hasClass(target,classValue)){if(target.className==""){target.className=classValue;}else{target.className+=""+classValue;}}returntrue;};functionremoveClass(target,classValue){varremovedClass=target.className;varpattern=newRegExp("(^|)"+classValue+"(|$)");removedClass=removedClass.replace(pattern,"$1");removedClass=removedClass.replace(/$/,"");target.className=removedClass;returntrue;};对一个元素的类进行直接的字符串比较是不正确的,因为它实际上可以包含多个类,每个类之间用空格隔开。这与您不应该对类进行直接赋值的原因是一样的,因为您可能会覆盖现有的类。hasClass()检查您正在搜索的值是否是多个类中的一个。addClass()确保您不会覆盖任何现有的类或多次添加同一个类。removeClass()只删除指定的类,而保持所有其他类不变。

    现在click事件已经就绪,每次用户单击内容模块的展开/折叠链接时,它都会根据需要添加或删除collapsed类。这就完成了我们的展开/折叠行为!

    CSS样式

    既然我们已经向页面添加了一些新元素和类,那么是时候对展开/折叠小部件进行样式化了。扩展/折叠anchor标签嵌套在h2中,所以我们可以通过CSS(来自main.css)使用它:

    .moduleh2{position:relative;}.moduleh2a{position:absolute;top:50%;right:10px;width:9px;height:9px;overflow:hidden;margin:4px000;cursor:pointer;}.moduleh2aimg{display:block;}为了让链接与h2的右边对齐,我选择了绝对定位,并使用right定位属性将它放置在距离边缘10px的位置(你也可以轻松地将元素向右浮动)。

    h2本身是相对定位的,这个对主播有重要作用。通常,当你绝对定位一个元素时,它将相对于整个页面定位;例如,如果您将它的顶部设置为0,它将移动到页面的顶部。然而,当你将一个绝对定位的元素(比如我们的anchor)嵌套在一个相对定位的元素(比如我们的h2)中时,anchor将会相对于h2进行定位。所以当我们设置anchor的right位置时,它将从h2的右边开始定位。

    链接的尺寸取决于它所包含的图像的大小。小加号和减号图标的大小是9px乘9px,所以这应该是链接的大小。实际上,包含图标的图像的大小是9px乘18px。这是因为两个图标在同一个图像文件中,如图图9-9所示。

    通过将两个图标放在同一个图像文件中,我们可以通过CSS影响展开/折叠链接的显示。通过将链接本身限制为仅一个图标的大小,然后将hidden值应用到overflow属性,我们有效地裁剪了图像的其余部分,使其看起来像只有一个图标。然后,在main.css里,我们可以在它的“盒子”里移动图像,将图标从减号切换到加号:

    图9.9。用于展开和折叠的两个图标组合在一幅图像中

    .collapsedh2aimg{position:relative;top:9px;}默认情况下,将显示减号图标,表示您可以折叠该模块。但是一旦模块被折叠,我们使用collapsed类来指定图标图像现在应该相对于它的包含元素(链接)向上移动9px,从而显示加号图标。

    显示和隐藏模块的实际内容更加容易:

    .collapsed.moduleContent{display:none;}现在展开和折叠的样式与行为相匹配,如图9-10和9-11所示,我们都完成了!

    图9.10。默认扩展视图中的日历模块

    图9.11。折叠后的日历模块

    展开/折叠是容易的部分。真正让用户控制的是能够指定模块本身的布局。我们将允许用户抓住一个模块的标题栏,拖动它在它的容器位置上下移动,或者把它换到另一个模块区域。因为重组行为完全独立于展开/折叠行为,所以我们可以将它包含在一个不同的文件modular.js中,以便于维护。

    拖放事件监听器

    设置新行为的第一步是为拖放操作创建事件侦听器:

    addLoadListener(initModular);functioninitModular(){varmodules=[document.getElementById("modules1"),document.getElementById("modules2")];for(vari=0;i

    .moduleDraggableh2{cursor:move;}当用户将鼠标悬停在一个可拖动的h2元素上时,光标变为移动光标,如图9-12中的所示。

    通过收集信息和设置变量,mousedown监听器在h2上调用的函数为模块的拖放行为做了大量工作:

    图9.12。当鼠标光标悬停在模块的标题栏上时,它的外观会发生变化。

    一旦这些差异得到解决,我们就在一个名为dragTarget的全局变量中创建一个对目标元素的父节点(围绕着h2的div)的引用,这样我们以后就可以在其他函数中使用它。

    识别出目标后,我们创建一些全局变量,帮助跟踪用户拖动模块时发生的情况。dragOrigin存储原始鼠标按下事件的坐标。每当事件被触发时,event.clientX和event.clientY记录两个坐标,这两个坐标定义了页面上事件发生的位置;在这种情况下,用户按下鼠标按钮。存储这个原始位置很重要,因为当用户移动鼠标时,我们想知道她从最初点击的位置移动了多远。

    一页地图

    是一个数组,存储了你可以拖动一个模块的所有可能的位置。你可以把它想象成一种地图。当用户拖动一个模块时,他们不会改变它在页面上的任意位置;相反,它们实际上改变了它相对于其他模块的位置。因此,我们没有用绝对坐标来指定一个模块的目的地,而是试图用它在其他模块中的位置来描述它的目的地:“将搜索模块移动到日历模块之下,星座模块之上。”为了做到这一点,我们需要创建一个页面地图,指示所有其他模块的位置。这样,当被拖动的模块在页面中移动时,我们知道被拖动的模块应该在每个静态模块的上面还是下面。不过,所有计算都是由mousemove处理程序完成的。目前,我们只关心创建地图。

    我们可以在mousemove处理程序中创建地图,但是每次鼠标移动时,都必须重新进行计算。只需按下鼠标按钮一次就可以创建地图,这样效率更高。

    为了创建映射,我们查看每个模块区域的内部,并遍历所有具有类module的div。对于那些div,我们在dragHotspots数组中创建一个新对象,它保存对模块的引用(element)、模块左上角的水平页面偏移量(offsetX)和模块左上角的垂直页面偏移量(offsetY)。最后两个属性从getPosition()函数中获取值,该函数获取一个元素并返回其位置:

    functiongetPosition(theElement){varpositionX=0;varpositionY=0;while(theElement!=null){positionX+=theElement.offsetLeft;positionY+=theElement.offsetTop;theElement=theElement.offsetParent;}return[positionX,positionY];};获取元素在页面上的位置过于复杂,但对此无能为力。元素只能辨别其相对于“偏移父元素”的位置(偏移父元素根据其定位、浮动等方式而变化)。为了获得它在页面上的绝对位置,我们必须递归地沿着偏移父树向上(使用element.offsetParent),获得每个偏移父树的位置,并将它们加在一起返回一个总数。

    一旦一个模块区域中的每个模块都被添加到dragHotspots中,有一种特殊的情况是我们将模块区域本身添加到dragHotspots中。这是为了让我们能够识别被拖动的模块何时位于模块区域中所有其他元素的下方;在这种情况下,我们把它移到最后。

    鬼魂

    创建地图后,我们需要创建可视元素,向用户指示他们正在拖动什么东西。它实际上是用户拖动的模块的副本,我们通过改变它的透明度使它看起来像幽灵一样,所以我称它为幽灵。

    我们使用getPosition()获得被拖动模块的当前位置,然后创建新的ghost元素。这是一个绝对定位的空div,包裹着被拖动模块的直接副本。空的div代替了模块区域div的约束,给了模块一个要填充的宽度;否则,它将扩展到100%的宽度。因为它被绝对定位并插入到body元素的末尾,所以它可以自由地移动到用户鼠标光标移动的任何地方。

    #ghost.module{opacity:0.65;filter:alpha(opacity=50);}你可以在图9-13中看到结果。

    为了跟踪按钮被按下时用户移动鼠标的位置,我们需要向整个文档添加一个mousemove侦听器。我们添加了一个mouseup侦听器来告诉我们用户何时释放了鼠标按钮。

    图9.13。原模块旁边的模块的幻影副本

    现在我们已经为用户拖动模块做好了充分的准备。mousedownH2()做的最后一件事是停止鼠标按下的默认动作。这可以防止浏览器在用户按下鼠标按钮时正常工作。在拖放的情况下,当拖动重影时,它会阻止页面上的文本被选中。

    随着用户四处移动鼠标,文档mousemove事件监听器将不断调用mousemoveDocument():

    mousedownDocument()然后需要使用我们的其他模块的映射来找出被拖动模块的新插入点。我们知道ghostdiv的位置,并且我们知道每个静态模块左上角的位置,所以很容易计算出ghost离哪个静态模块最近。我们希望在静态模块之前插入被拖动的模块。

    对于dragHotspots中的每一个条目,我们都快速测试一下幽灵的水平位置。如果ghost的任何部分都不在静态模块所在的模块区域的宽度内,我们就不希望将它视为被拖动模块的可行目的地。因此我们检查重影的右边缘是否在静态模块左边缘的右侧,以及重影的左边缘是否在静态模块右边缘的左侧。这意味着重影的某些部分与模块区域的宽度重叠。

    然后,我们可以关心幽灵和静态模块之间的垂直距离。为此,我们测量重影顶部和静态模块顶部之间的差异,然后将其与已经找到的最小值进行比较。如果到当前静态模块的距离小于当前最小值,则该值成为新的最小值。在检查完所有的dragHotspots条目后,我们知道是否有合适的位置可以插入被拖动的模块,如果有,在哪里。

    如果有合适的位置,我们需要向用户显示,这样他们就知道如果释放鼠标按钮,拖动的模块将被插入到哪里。为此,我们创建了一个名为ghostMarker的新元素,它只是一个位于候选插入点顶部的方形小块。ghost标记是body元素的绝对定位子元素,所以为了定位它,我们使用最近的静态模块的坐标。正如你在图9-14中看到的,通过一点CSS样式,ghost标记很好地指出了被拖动的模块将被插入的位置。

    图9.14。显示拖动模块插入位置的重影标记

    为了便于以后插入被拖动的模块,我们还创建了一个新的属性ghostMarker,它记录了正在标记哪个静态模块:ghostMarker.marked。

    如果没有一个合适的位置来插入被拖动的模块,那么当我们实际移除ghostMarker时,用户没有将ghost拖动到足够靠近某个静态模块的位置。因此,如果用户将重影从一个合适的位置移动到一个不合适的位置,它仍然不会表明他可以重新定位被拖动的模块。

    mousemoveDocument()中的最后一个操作再次停止了浏览器通常为鼠标移动执行的默认动作,防止用户拖动时发生不必要的动作。

    重新定位的模块

    当用户决定将拖动的模块放在哪里,或者不想移动它时,他将释放鼠标按钮。这是由mouseupDocument()捕获的:

    functionmouseupDocument(){detachEventListener(document,"mousemove",mousemoveDocument,false);varghost=document.getElementById("ghost");if(ghost!=null){ghost.parentNode.removeChild(ghost);}varghostMarker=document.getElementById("ghostMarker");if(ghostMarker!=null){if(!hasClass(ghostMarker.marked,"module")){ghostMarker.marked.appendChild(dragTarget);}else{ghostMarker.marked.parentNode.insertBefore(dragTarget,ghostMarker.marked);}ghostMarker.parentNode.removeChild(ghostMarker);}returntrue;};大部分繁重的工作已经完成,所以这个函数只是把事情整理一下。首先,它从文档中删除了mousemove事件侦听器,因为我们不再需要知道用户何时移动鼠标。之后,我们移除ghost元素,因为我们想要停止显示副本。

    然后我们决定将拖动的模块放在哪里。如果ghostMarker仍然存在,意味着用户在有一个有效的地方移动被拖动的模块时释放了鼠标按钮。使用ghostMarker.marked属性,我们可以看到哪个元素之前插入了被拖动的模块。我们需要检查被标记的模块是否真的是一个模块,或者它是否是我们放在模块区域末尾的额外占位符。如果是一个实际的模块(它有一个module类),我们可以使用insertBefore()方法将被拖动的模块移动到被标记的模块之前。如果是一个模块区域,我们使用appendChild()将被拖动的模块放在区域的末尾。无论哪种方式,我们都删除了重影标记,被拖动的模块现在就在它的新位置结束了,就在用户想要的地方!如果ghostMarker不再存在,我们知道被拖动的模块无处可去,所以我们可以安静地完成。

    图9-15显示了用户将一个模块从一个模块区拖动到另一个模块区的全过程。

    图9.15。将一个模块拖到另一个模块区

    本例中介绍的技术创建了一个用户可以随心所欲定制的页面。但是,如果他们第二天返回到该页面,而该页面没有保留他们的任何更改,那么这将是徒劳的。

    虽然可以从服务器下载页面,并通过JavaScript重新排列模块,但这是一个相当笨拙的过程,可能会导致用户在页面切换到他们的定制布局之前看到默认布局。

    最好的解决方案是在服务器上组装自定义布局,并按照用户的安排提供给他们。实现这一点最简单的方法是在用户的浏览器中存储一个cookie,告诉服务器用户布局的顺序,服务器可以用它来组装适当的页面。

    我们所要做的就是跟踪哪些模块在哪个模块区域以及它们的顺序。为此,我们需要确保每个模块在我们的标记中都有一个惟一的ID。一旦完成,我们可以修改mouseupDocument()函数来编写一些包含偏好数据的cookies。这个更新的功能包含在modular_cookie.js(你可以包含它而不是modular.js):

    当这些cookies被传递到服务器时,您应该能够使用它们来检查模块的顺序,并以适当的顺序将它们写入web页面。

    用户需求的多样性——无论是技术性的还是基于任务的——正在挑战传统的静态网页形式。创建动态接口是满足这些需求的方法之一。我在这里描述的两种技术展示了基于标准的web页面的灵活性如何改变我们为Web设计的方式。

    德里克

    费瑟斯通

    boxofchocolates.ca

    furtherahead.com

    德里克·费瑟斯通(DerekFeatherstone)迷人、令人惊讶、鼓舞人心,他有一种天赋,能够以全新的视角看待web开发的几乎每一个方面,并以一种重新点燃我们的热情的方式进行教学,让Web为每个人变得更好。费瑟斯通是国际知名的可访问性和web开发权威,也是受人尊敬的技术培训师和作家。

    作为关于HTML、CSS、DOM脚本和Web2.0应用程序的深入课程的创建者,Derek从不忘记支持Web标准和通用可访问性的事业。自1999年以来,他通过自己的公司theFurtherAhead(www.furtherahead.com)成为政府机构、教育机构和私营企业的抢手顾问。他丰富的经验和洞察力使他能够为观众提供直接适用的,非常简单的方法来应对网站设计中的日常挑战。

    承认吧。你想要它。你知道,你网站上的杀手锏让博客圈说“aaaaaaahhhhhh。”为你赢得重启奖的那个。让你的网站脱颖而出的那个。好吧,算了。通过为访问者提供更容易的信息和链接,让他们的生活变得更容易的那个呢?

    我们现在谈论的是老式动态HTML菜单系统的替代品,这种系统只需简单的鼠标悬停和点击,就可以访问所有的分类和子分类链接。这个替代品是滑动导航系统,它显示了很好分类的链接。

    肖恩·因曼的博客(www.shauninman.com)在他2005年的重新设计中展示了这一技术,完成了一个滑动导航和搜索标签,隐藏和暴露了他的网站的细节。他的博客类别、最近的帖子、搜索框和其他好东西都被隐藏起来,直到被一些忠实的JavaScript调用。

    在这一章中,我们将实现一个将滑动导航和信息丰富的页脚结合到一个系统中的网站,该系统为当今许多网站上的传统“选项卡式”导航增加了细节和可用性增强。而且,正如您所料,它从一开始就将可访问性考虑在内。

    网页可访问性最好被描述为一套指导原则或指南,帮助我们制作适合所有不同类型用户的网站,不管他们的能力如何。当我们编写网站代码时,我们努力将这些不同水平的能力考虑在内

    视力障碍(不同程度的失明、低视力和色盲)

    移动性或灵活性障碍(需要使用语音识别软件或硬件辅助工具来方便键盘使用或帮助补偿不同水平的精细运动控制)

    听觉障碍(例如,需要多媒体音频和视频的字幕和/或抄本)

    认知障碍(包括不同程度的阅读障碍、自闭症和其他学习障碍)

    为了考虑到这种广泛的能力,我们需要做一些简单的事情。我们确保图像有适当的替代文本,以便视力受损的人有替代的表示,他们的屏幕阅读器软件可以读给他们听。我们实现了一些解决方案,允许用户调整页面上的文本大小,以便更容易阅读。我们在前景色和背景色之间有适当的颜色对比。我们标记表单域,使用结构化标记来确保屏幕上的元素使用最好的HTML元素,如标题、段落、列表、表格、表单按钮等等。

    建设无障碍网站的一个长期问题是,作为开发人员、设计人员和内容创建者,我们几乎没有与残疾人一起工作的实践经验,以了解他们的真正需求以及我们如何避免为他们设置无障碍障碍。进入万维网联盟的网页可访问性倡议(www.w3.org/WAI)。

    WebAccessibilityInitiative(WAI)致力于让每个人都能更方便地访问Web,并制定了一套指导原则来帮助开发人员构建可访问的网站。不用担心;这不完全取决于我们。WAI还为浏览器制造商和创作工具供应商制定了指导方针,以便他们能够确保人们使用的工具能够促进可访问性。这些其他的指导方针用户代理可访问性指导方针(UAAG)和创作工具可访问性指导方针(ATAG)是重要的,但是超出了我们作为开发人员所做的范围。我们应该坚定地把注意力放在网站内容无障碍指南上(WCAG)。

    WCAG(www.w3.org/WAI/intro/wcag.php)是一套指导方针,为我们创建无障碍网站提供了一些起点。然而,这并不意味着简单地遵循指南就能保证我们的网站是可访问的。为了创建可访问的网站,我们通常需要遵循指南中的原则,然后与使用辅助技术的人一起测试我们生成的网页。这确保了我们可以两全其美。我们通过遵守指导方针来实现技术合规性,并通过对残疾人的测试,我们创造了对他们实际有用的东西。

    本章中的示例研究了WCAG的许多原理,包括用各种屏幕阅读器、语音识别软件和屏幕放大器进行测试的结果。

    要详细深入地了解可访问性,请阅读《Web可访问性:Web标准和法规遵从性》(编辑之友,ISBN:1-59059-638-2)。

    多年来,可访问性和JavaScript都是精通某个专业领域的专家的领域。这一领域的工作一直受到web开发人员代代相传的长期神话的阻碍。这个神话非常简单:为了确保你的网页是可访问的,它必须与JavaScript一起工作。

    这种误解在很大程度上是由于WCAG检查站6.3(www.w3.org/TR/WCAG10/wai-pageauth.html#tech-scripts)造成的,该检查站规定:

    当脚本、小程序或其他编程对象被关闭或不受支持时,确保页面可用。如果不可能,请在另一个可访问的页面上提供等效信息。

    1999年,当WCAG1.0发布时,这是一个合理的指导方针。屏幕阅读器和浏览器远没有今天这么先进。人们普遍认为(并传播)屏幕阅读器不理解JavaScript。开/关场景曾经相当准确。

    今天的屏幕阅读器确实理解了今天的浏览器所支持的大部分JavaScript,然而许多人仍然坚持认为这是不可能的。他们坚持WCAG检查点6.3所必需的假设:作为二进制开/关场景的可访问性和脚本。

    进入网络可访问性和辅助技术的现代时代。是的,一些残障人士可能会使用无法处理脚本的浏览器,甚至关闭JavaScript,但大多数人可能会使用支持脚本的常规浏览器。这不再是一个非黑即白的问题。确保一个页面在脚本打开或关闭的情况下工作更多的是关于互操作性,而不是的可访问性。

    因此,创建可访问的JavaScript的技巧不仅仅是确保我们的解决方案可以打开或关闭JavaScript。我们还必须确保我们的解决方案与不同能力的用户和辅助技术兼容。在我们学习本章的其余部分时,请记住这一点。

    根据我们的经验,基于标准的web开发方法为残障人士提供了基本的可访问性以及与不同设备的基本互操作性:结构化HTML、用于表示的CSS以及用于提供行为的最终JavaScript层。这种方法将在本章的例子中使用,以确保我们已经涵盖了基础知识。我们将使用语义HTML,使用CSS进行设计,并交付一个可以打开或关闭JavaScript的解决方案。一旦我们完成了这些,我们将添加更多的脚本来确保系统对于使用各种辅助技术的人来说工作良好。

    在我们开始编写代码之前,让我们先来看一下解决方案的简要概述以及实现这一切的文件(这些文件可以从本书的页面www.friendsofed.com下载):

    基本HTML文件,wscslide.html

    样式表,wscslide.css

    JavaScript函数,wscslide.js

    在最终的解决方案中,导航窗格的初始状态将如图10-3所示。

    图10.2。滑动导航功能的线框

    图10.3。导航、内容和附加导航窗格在默认位置的初始状态

    点击主链接后,导航窗格将滑动到最终位置,如图图10-4所示。

    图10.4。“暴露”状态,其中一个导航窗格位于其新位置,视觉上位于主导航的正下方

    它们代表了每个选项卡的两种“状态”:当信息被隐藏时和当信息被暴露时(当我们稍后检查解决方案的CSS和JavaScript部分时,这将是很重要的)。

    为了使任何网站或web应用程序工作,我们需要一个通过干净的HTML提供的内容和功能的坚实基础。HTML不仅应该在内容上有意义,而且应该在功能上有意义。尽管大多数人倾向于认为HTML只是内容,但它确实通过表单域和链接提供了基本的功能。在本章的后面,我们将使用这些链接作为脚本交互部分的基础。

    对于这个解决方案,我们需要实现HTML的三个主要方面:

    航行区域

    主要内容

    页脚中的附加内容

    页脚内容相当简单,包括几个部分。在本例中,我们使用了一个About部分、一个RecentPosts部分和一个Services部分。当详细查看该部分时,这些内容区域中的每一个都提供了对完整内容的一瞥,提供了各种摘要。我们将每个页脚部分包装在自己的

    中,以便稍后提供适当的样式。

    还要注意,我们在每个页脚部分添加了标题,为该部分提供了一种“标记”。为了举例,我们将这些标记为

    元素。您将需要决定

    是否适合您的使用,或者其他更低级的标题是否更合适。

    这些代码块将作为我们其余实现的基础。我们将在添加样式和功能时对其进行修改。

    这个例子的CSS相当简单,大部分都是为了修饰这个例子。我们添加一些样式来布局基本页面,指定颜色和背景图像,并格式化文本。有了这些,我们可以专注于页脚本身和我们需要的样式,让导航从顶部向下“滑动”。

    最终完成CSS需要一些工作,但是核心布局保持不变。对于这个版本的滑动导航,我们使用绝对和相对定位将导航窗格从页面底部移动到顶部。正是这个动作形成了核心CSS“开关”,使导航成为可能并保持其可访问性。主要机制只是一个链接,链接到包含我们想要的信息的页面的另一部分。当一个窗格被暴露时,它会占据页面顶部的位置,就像前面图10-4中的窗格一样。

    在JavaScript因其在Web上的使用方式而遭到诋毁的时代,内联脚本、事件处理程序和样式属性的修改只是简单的做事方式。这些特别的变化通常与修改和定义飞行高度、宽度、背景颜色和各种其他样式属性有关。

    我们已经从那些黑暗的日子里取得了显著的进步,并努力将我们的HTML从我们的CSS和JavaScript中分离出来。现代技术努力确保我们的页面在打开和关闭时都能使用JavaScript。这被称为“不引人注目的脚本”,是本书其他地方以及其他现代脚本书籍中的标准,如JeremyKeith的书DOMScripting(ED之友,ISBN:1-59059-533-5)。

    在我们目前的网络浏览器中,我们有一个更加可预测的工作环境。这种可预测性使我们能够改变高度和宽度之外的属性,并在包括CSS定位在内的预定义状态之间进行切换。将所有需要的CSS更改存储在一系列CSS规则中,我们可以简单地使用一些JavaScript来根据需要更改适当的包含元素的类。

    出于滑动导航的目的,我们有两个核心状态:

    在初始页面加载时,我们的导航窗格出现在页面底部(见图10-3)。

    当一个导航项目被激活时(用键盘或鼠标),导航窗格移动到页面顶部(见图10-4)。

    我们使用JavaScript将导航窗格的类更改为“exposed”,这使它在页面顶部导航下方有了合适的位置。我们创建一个样式规则,将任何窗格放置在正确的位置(来自样式表,wscslide.css):

    /*applytoanydivwithclass="exposed"thatisinthe*/div#dropsdiv.exposed{position:absolute;top:0;left:0;padding:0;/*addedtoremovedoubled-uppaddingwhenpositioned*/}请注意,这是可行的,因为我们将这些窗格定位在最近的相对定位的父窗格中,div#inner-wrap:

    div#inner-wrap{background-color:#ccc;color:#000;position:relative;margin:0;padding:0.5em0;}我们还使用JavaScript删除暴露的类,以将窗格返回到页面底部。

    我们可以通过多种方式结合JavaScript来实现这一点。为了维护我们坚实的HTML基础,我们使用JavaScript拦截或“劫持”导航项目上的点击,并切换导航窗格的状态。它使用了一个名为toggle的函数,可以在暴露的导航窗格和原始状态之间切换。最好将这些动态地分配给每个导航项目,但是为了清楚起见,这最终导致我们的导航链接如下:

    这是其余脚本的基础。有了这个主开关,我们就可以添加滑动行为了。

    现在,我们已经使用脚本在每个导航窗格的暴露位置和正常位置之间切换,我们可以添加脚本来将导航从主导航的“下方”滑出。我们通过在激活exposed状态时将窗格的高度改为0,并编写一个通过改变其高度来显示导航窗格的函数来实现这一点。

    作为替代,当我们激活暴露状态时,我们可以在contentdiv上放置一个适当的padding-top,以允许导航窗格位于内容之上。使用CSStop属性的负值,我们可以隐藏顶部导航下方的导航窗格,并使用JavaScript将div#inner-wrap向下滑动适当的距离。然而,在该解决方案的早期测试中,一些测试者报告了“起伏不定”的滑动行为。这在一定程度上是由于滑动了一个包含页面上所有内容的div。随着页面的变大,滑动变得不顺畅。

    这种解决方案和示例中使用的解决方案都需要额外的脚本,但是从技术角度来看,它们对可访问性都没有显著的影响。(虽然一般来说滑动导航可能会有问题,也可能没有问题,例如对于有认知障碍的人来说。)

    完成的脚本包括几个使其工作良好的附加特性:

    简单的错误检查,防止用户在标签上点击两次。一旦导航窗格“移动”,该函数就返回,而不是再次调用它。

    一种基本的重置功能,可用于将选项卡重置为其原始状态。

    常数SLIDEINTERVAL,它让我们定义重复调用Reveal函数的速度。在这种情况下,我们每65毫秒调用一次。

    我们可以对这个脚本进行一次大范围的浏览,一步一步地查看我们所做的更改。例如,我们可以详细研究动画策略。然而,我想把重点特别放在细节的可访问性方面,让大部分核心脚本自己说话。您可以在整个脚本中找到注释来详细说明发生了什么。下面是最终核心脚本的清单,wscslide.js:

    它可以在脚本打开或关闭的情况下工作。

    它使用HTML固有的核心行为,即指向同一页面上其他位置的简单链接。

    所有链接都允许键盘激活。我们没有为此做任何事情;这是固有的行为。在我们的脚本中,我们确保不做任何会剥夺键盘功能的事情。

    这是一个好消息,但这并不意味着我们没有进一步的义务。为了确保这个解决方案确实可行,我们需要做一些额外的测试。让我们来看看其中的一些测试。

    图10.5。灵活的大小调整允许在不破坏设计的情况下调整字体和导航窗格本身的大小。

    当使用屏幕放大镜时,我们注意到关闭链接没有出现在视野中。这并不比任何其他不使用缩放布局的网站更难使用。当然,可以做更多的实验来实现完全左对齐的缩放布局。

    这种特殊的解决方案似乎与语音识别软件配合得很好(DragonNaturallySpeaking用于测试),只有一个小的例外。语音识别用户能够专注于页面中的链接。他们可能会说“链接”,并显示有编号的选项,如图图10-6所示。

    图10.6。使用DragonNaturallySpeaking中的链接功能选择导航链接

    如果使用该网站的人随后打开导航窗格,则在屏幕之外的链接将不能使用编号机制。然后用户可以再次说出“link”来重新填充链接数组,给出一个编号的链接选择,如图10-7所示。

    图10.7。当导航窗格打开时,窗格中包含的链接无法使用links数组。用户需要再次说出命令“link”来重新填充阵列,如此处所示。

    如果用户重复“链接”命令,然后关闭导航窗格(或切换到另一个窗格),他会在每个链接原来所在的地方看到一个可视的“工件”(见图10-8中的例子)。这可以通过手动重新填充链接数组来解决。

    图10.8。链接数组的视觉效果。当使用DOM脚本效果在页面中移动或生成内容时,links数组不会自动更新。它要求用户通过给出适当的命令(如“link”)来手动更新它

    我们如何解决这个问题?这是我们必须再次检查可访问性和JavaScript的地方。如果我们仅仅停留在确保我们的页面在脚本打开或关闭时都可用,我们就不会意识到我们给屏幕阅读器用户带来的问题。重申一下,脚本开/关场景更多的是关于基本的互操作性,而不是关于残疾人的可访问性。

    一种可能是不返回false,让历史堆栈顺其自然。在某些情况下,这样做甚至是可取的。然而,这意味着我们在页面中得到视觉上不和谐的“跳转”,并且最终隐藏了主导航,从视图中移除了切换点。这种解决方案不是特别有用,而且很可能会让用户感到厌烦,让签署该解决方案的人无法接受。

    只使用键盘的用户会遇到许多与屏幕阅读器用户相同的问题。特别是,将焦点放在导航窗格中对于允许键盘用户正确导航至关重要。

    tabindex解决方案是可接受的吗?IBM、Mozilla和微软似乎都这么认为,尽管IBM的代表暗示他们知道这个解决方案不太正确(见www.csun.edu/cod/conf/2005/proceedings/2524.htm):

    请记住,这还不是任何W3C或其他官方标准的一部分。此时,有必要修改规则以获得完整的键盘可访问性。

    一个无效的值可能会有不可预见的后果,并且在节点上操作DOM来包含一个tabindex值(在那里它不是一个有效的属性)似乎有点笨拙。我们实际上使用JavaScript只是为了掩盖这样一个事实,即我们正在做的事情根据HTML规范是无效的。

    1tabindex策略似乎得到了行业内的支持。web超文本应用技术工作组(WHATWG,www.whatwg.org),一个由Web浏览器供应商和其他感兴趣的团体组成的组织,正在致力于开发HTML5。在该规范中,tabindex是一个允许用于任何元素的属性,并且允许负的tabindex值。

    这是最终可行的解决方案吗?也许是,也许不是。我们所知道的是,我们已经尽了最大努力来确保我们在解决方案中有一个互操作性和可访问性的基线,具体做法是:

    通过简单的HTML代码提供内容和核心功能

    确保我们使用不引人注目的脚本

    确保我们的字体是可扩展的,并同时使用前景色和背景色

    以创造性的方式使用CSS来修改事物出现的方式,同时保持逻辑、语义结构

    我们已经进行了基本测试,这使我们能够解决残疾人在使用该解决方案时将面临的许多问题。额外的测试将会告诉你这个解决方案对所有能力水平的用户是否有用。您必须对真实用户进行自己的可访问性测试。

    在你的网站上试试这里展示的技术。本章已经给了你足够的信息来开始使用你自己的可访问的JavaScript解决方案。

    欢迎来到我们基于高级标准的网页设计之旅的第一部分。不出所料,第一部分涉及高级布局技术,因此重点主要放在CSS上。最终选择在这里收录(就像这本书的所有内容一样),是因为作者有一些有点有趣和不寻常的东西要说。面对现实吧,你在网上看到过多少关于CSS布局技术的教程?

    作者们真的从帽子里拿出了一些特别的东西。Simon、Ethan和Andy展示了在精益、语义标记的严格饮食下,通过巧妙使用类值、开箱即用定位等,实现设计精美的网站的不同方法。

    Dan向您展示了即使受到内容管理系统提供的内容的限制,您仍然可以创建外观精美的网站。他还加入了一些Flash图像替换和少量DOM脚本。

    Jeff专注于使用透明png,以及CSS和HTML,在您的站点上创建一些真正令人敬畏的设计效果。

    作者谈到了他们应用时浏览器支持的不一致性,并解释了他们是如何解决这些问题的。你在这里看到的漂亮的布局是在没有借助很多黑客手段的情况下实现的!

    旅途愉快。。。

    在旅程的下一部分,你将会看到如何将有效的印刷设计技术带入网页设计世界。无论你的背景如何,你都不得不承认这两种媒体之间有很多相似之处,印刷设计师学到的一些古老的经验对他们的数字兄弟来说非常有价值。

    首先,马克专注于一个相当实验性的网页区域网格设计。他展示了网格在网站上使用时的强大功能。

    然后,Rob对印刷原则进行了有趣的研究。他展示了即使是一个简单的网站也可以通过在排版上花点心思来改变。

    两位设计师都有印刷设计的背景,这一点显而易见。我希望有更多的他们这样的人能进入网络世界。

    没有一些DOM脚本示例,哪本关于web标准的书是完整的?这就是为什么我把这本书的最后一部分致力于动态脚本技术来改善你的用户体验。

    我特意尝试选择一些技术,这些技术对于设计性更强、开发性更差的人来说不会太可怕——不要害怕用JavaScript弄脏自己的手!

    Ian首先向我们展示了他拯救世界的技术:通过使用DOM脚本来指定只打印网页的重要部分,我们避免了浪费纸张和麻烦。

    接下来,Cameron演示了通过使用一些适当的脚本,在您的网页上为您的用户提供一个更加动态的交互环境并不困难。在他的案例研究过程中,他建立了一个动态的用户界面,无论用户使用什么样的分辨率/平台访问你的网站,该界面都会自动调整以获得最佳的浏览效果。他还展示了如何通过在不同的调色板中移动内容来创建用户可以定制的界面。

    THE END

    1.东莞美发培训班学费哪个好东莞哪里有美发培训学校 中班 面授 ¥询价 1451人关注 企 14年 东莞菲菲美容美发化妆培训学校热门推荐 热门城市 栏目介绍 更多 东莞美容培训学校 东莞化妆培训学校 东莞彩妆培训机构 东莞美发培训 东莞纹绣培训机构 东莞美发培训机构 东莞美容培训机构 东莞纹绣培训班 东莞美容培训班 东莞美牙培训学校 东莞彩妆培...https://m.qinxue365.com/class/cs2091_px251/
    2.哪里有理发哪里有理发培训速成班...哪里有理发培训速成班 哪里有理发的 更新时间:2024-08-01 哪里有理发的...哪里有理发的 哪里有理发学校学费多少 更新时间:2024-08-01 哪里有理发学校学费多少...哪里有理发学校学费多少 哪里有理发的地方 更新时间:2024-08-01 ...https://news.qingflow.com/plugin/ss/index.php?s=%E5%93%AA%E9%87%8C%E6%9C%89%E7%90%86%E5%8F%91.html
    3.“医美速成班”圣嘉丽禾官网称已培育2万多名学员中新财经3月15日电(宫宏宇)央视3.15晚会曝光圣嘉丽禾南京校区微整形全科培训班,负责培训的老师有任何医师执业信息,认证中心的网站没有任何备案信息。 中新财经查阅圣嘉丽禾微整形技术培训学校官网发现,(圣嘉丽禾)隶属于香港圣嘉丽禾微整形教育学院,成立于2009年,成功办学3千多期,培育学员2万多名,收获学员好评无数。中...https://news.sina.cn/2022-03-15/detail-imcwipih8664049.d.html
    4.经济速成班第6课:通货膨胀与经济泡沫英语视频听力了解一些经济学知识可以帮助你商议经通货膨胀调整过得真正加薪。 Thanks for watching. See you next time. 感谢您的收看,我们下期见。 Thanks for watching Crash Course Economics. 感谢您收看经济速成班。 It was made with the help of all these nice people and the greatest bubble of all. 它是由一群好...https://www.kekenet.com/Article/201802/542227.shtml
    5.恋爱先生:金句频出,撩妹达人速成班半个月不进理发馆的男人,基本上就把自己给废了。(其实陈皓本人才是,看他那头厚留海,就不爽。天天大道理教育别人,自己连个女朋友还没混上) 如果一个人值得你去爱,那么这份爱情就值得你去等。 一个连自己衣服号码都不在意的人,注定当一辈子配角。 https://www.jianshu.com/p/8639471d51af
    1.热推!合肥十大理发培训机构地址美发创业全科班讲授各种烫发原理、烫发排位、受损发质越烫越健康的技术秘诀,各种吹风工具的使用方法和技巧,手吹大花、夹板造型等技术要领、使您在美发领悟中有更高的造诣和提升,达到自己独立开店做老板的水平。 精品美发全套课程,剪、染、烫设计、色彩打蜡技巧、神奇梦幻吹风造型设计、时尚发型设计,发廊经营管理、发型与...https://www.thea.cn/meifa_px_4227040-1.htm
    2.美容美发的学校(学美容美发的正规学校推荐)4、理发学校十大名校 上海有哪些美发培训学校 1、上海美发培训学校有: 沙宣美发培训学校。这是国内知名的美发教育机构,提供专业的美发技能培训,包括基础剪发技巧、烫发技术、染发技术等。学校拥有先进的设施和一流的教师团队,为学员提供实践机会和就业指导。 托尼盖美发培训学校。这所学校在上海享有较高声誉,专注于美发技...https://www.lzxxw.com/post/47871.html
    3.学美发?这些学校你一定要知道!在美发行业摸爬滚打这么多年...学美发?这些学校你一定要知道! 在美发行业摸爬滚打这么多年,很多朋友问我如何学习美发。我的建议是,选择一个专业的美发培训学校,系统地学习美发知识,从零开始练习技艺,提升自己的技能。 石家庄HQ美发培训学校 ? 优势:系统教学、随到随学、专职讲师、零基础教学 课程:美发实战班、美发基础班...https://www.yoojia.com/article/5320099248054220984.html
    4.美发培训学校10大品牌排行榜最新名单公布→十大品牌网入榜《2024年CNPP理发学校十大品牌榜中榜名录》的有:汤尼英盖、蒙妮坦、尚艺、3AM HAIR SALON、埃朵、肯洲、名丝美发学院、阿杰发艺、百美汇、柏形时尚学校等,理发学校10大品牌排行榜由CNPP品牌榜中榜大数据「研究院」和CN10排排榜技术「研究院」通过资料收集整理,并基于大数据统计及人为根据市场和参数条件变化的分析...https://www.cnpp.cn/focus/36664.html
    5.机构简介深圳理发快剪速成班深圳分校区是美业教育行业的标杆(以下简称深圳理发快剪速成班或者深圳理发快剪速成班教育),专注美容、美发、化妆、美甲、纹绣、形象设计、等专业职业培训,发展至今全国开设80家分校,拥有800多名教师团队,为社会输送数万美业人才;在彩妆、养颜、形象设计、发型设计、美容SPA会所、保健休闲等机构均有深...https://m.zysm.cn/school-57621/about.html
    6.长春新东方烹饪技工学校官网最佳理发培训班推荐,专业机构圆您美发梦! 在追求个性与时尚并重的今天,美发行业不仅成为了一个充满创意与激情的舞台,更是无数人实现自我价值与梦想的起点。对于渴望踏入这一领域或已在此行业中寻求突破的朋友而言,选择一家优质的理发培训班,无疑是迈向成功的重要一步。今天,就让我们一起探索那些能够圆您美发梦的...http://www.ccxdf.cn/13330.html
    7.起底高价植发“漩涡”:成活率成谜,培训速成班宣称三天包学会...“我抱着希望积极配合治疗长达一年,没有任何效果,要求院方全额退款,而他们的解决方案是赠送我三次中胚层治疗,或者只能退其中3次中胚层的钱。”侯女士表示这并非自己想要的解决方式。 生意 植发培训“速成”,“学得快一天就会” “零基础教学”“接触轻医美行业 掌握财富密码”…… ...https://www.bjnews.com.cn/detail/163758533414391.html
    8.zhongjia1818.com/newxr65069775/82846053.htm少有的双舱款,仔细一看发现只能洗不能烘。,_:# 而几天前,苹果刚对外宣布,其一年一度的秋季新品发布会定于北京时间9月10日凌晨1点举行。.。+ 不过,媒体也强调,由于越南基础设施的匮乏,在数据中心领域,该地尚未能吸引到太多外部目光的关注。并且相应的,在马来西亚,这些机构往往会选择马来西亚或者新加坡作为其海外...http://zhongjia1818.com/newxr65069775/82846053.htm
    9....英语语文数学在线学习4、看了课题,你们有什么疑问?剃头大师是谁?他是怎么理发的?他给谁理发?...学贵有疑,看来咱们班的同学都是会学习的孩子。下面,就让我们带着这些疑问走进课文。二、检查预习,了解人物。1.师:课前,大家已经预习过了课文,那故事中的几个人物你们找出来了吗?他们是谁?(生回答)2.师:找得非常准确,故事就是围绕...http://tui.guyuenglish.com/news/8757.html
    10.今日热点新闻15条全球疫情变异株新发现:科学家们紧急召开会议讨论防控策略 随着新冠病毒(COVID-19)持续蔓延,全球各地的卫生专家一直在密切关注病毒的变化和传播情况。近日,一种新的变异株引起了广泛的担忧,这使得“今日热点新闻15条”中又有一个重要议题浮出水面。 据报道,这种新变异https://www.qaqaxxz.cn/mei-fa-jiao-cheng/424388.html
    11.学理发的基本功课?学理发要注意什么要有什么技巧先学基本功,洗头,然后还有一些色调发型知识,再就是染烫技术,如果到店里学习一半最少要2年才可以动手剪头,既然现在都剪了就在这扎实的学,别的理发师在剪发的时候你可以在一边自己看,学一些手法,打层、主要是你的大胆学大胆做。 一、锯剪的操作技巧有以下几点: ...https://www.xkyn.com/na/sdnesdnedbhbhhwnna.htm
    12.中年逆袭35岁后再次尝试理发行业的可能性探讨在这个快节奏的社会里,人们对职业转型的需求越来越大。对于那些曾经有梦想但未能实现的人来说,35岁学理发是否还来得及,这个问题一直困扰着许多人。实际上,年龄并不是一个决定性因素,而是个人意志和行动力的体现。 首先,从学习角度出发,一切都始于基础知识的掌握。35岁时,可以通过参加短期或全职的理发课程,对自己进行...https://www.a6tea507.cn/mei-fa-jiao-cheng/400178.html
    13.粤语怎么学问题一:粤语怎么学的最快更好? 粤语的音一共有9个,合并之后有六个每个字的粤语拼音后面的数字代表是什么声调,用1-6的数字表示。这种拼音比较难学,因为差别不是很大。国语的拼音是为了方便大家用紫光拼音打出来。拿到我发的粤语输入法的,可以用粤语拼音来打。 呃 国语拼音:e 粤语拼音:ngeg1 意思:骗 举例:你...https://www.lishixinzhi.com/bb/529422.html
    14.交流发言稿通过这些年的尝试与实践,教育教学成绩有了稳定的提升。20xx届初中毕业生167人,被筠连中学录取58人,筠连县第二中学录取23人,五年制大专9人,其中进筠中创新班1人,网班4人,小尖班9人,重点班17人;20xx届初中毕业生193人,上均中录取线69人,筠连中学录取67人,筠连县第二中学录取29人,五年制大专24人,其中进筠连...https://www.cnfla.com/fayangao/2674436.html