精通 HTML5、CSS3 和 XML Web 标准(二)

原文:Web Standards Mastering HTML5, CSS3, and XML

协议:CC BY-NC-SA 4.0

四、服务和配置

web 文档的正确外观和处理不能简单地通过应用严格的、无错误的标记来保证。Web 服务器配置对网站的外观、操作和行为有重大影响。文档应该使用正确的媒体类型和字符编码。内容协商可用于向支持相应媒体类型的浏览器提供各种文档版本。XHTML 文档可以作为 HTML 或 XML 提供,但是在处理上有很大的不同。XML 文件由比 SGML 解析器更容易出错的 XML 解析器处理。XHTML 作为 XML 存在着文档根本无法呈现的风险。另一方面,向后兼容的服务不能利用严格 XML 标记的好处。将 HTML 和 XHTML 从服务器发送到呈现引擎有几个方面,所有这些都应该被考虑以实现正确的设置。

在本章中,您将学习如何配置您的网站、浏览器和服务器,以便正确地提供 web 文档。熟悉最重要的 MIME 类型对于正确提供 web 文档及其使用的文件至关重要,例如样式表、图像、音频和视频文件、ZIP 存档和 office 文档。除了互联网媒体类型,您还将学习域名配置;URIs、URL 和 urn 的区别;基本目录的应用;和实践来消除文件扩展名。

HTTP 头

万维网上数据通信的基础是超文本传输协议(HTTP)。它是一种网络协议,在客户端-服务器计算模型中充当请求-响应协议。在这种模型中,典型的客户端是 web 浏览器,而在网站主机上运行的应用是服务器。在每次查询过程中,客户机向服务器提交一条 HTTP 请求消息。作为回报,服务器向客户机发送一个包含附加数据的响应消息,例如关于请求的完成状态信息,该消息与 web 文档一起从服务器发送到用户代理。这些报头字段构成了 HTTP 报头。报头字段确定 HTTP 通信的参数。HTTP 请求用于指示哪些内容类型和字符集是可接受的(AcceptAccept-Charset)、消息发送的日期和时间(Date)、域名(Host)、代表用户代理的字符串(User-Agent,等等。

正如您在清单 4-1 中看到的,HTTP 响应提供了服务器名称(Server)、返回数据的备用位置(Content-Location)以及响应过期的日期和时间(Expires)。Vary字段确认缓存的响应是否可以使用,而不是重复请求。隐私偏好项目平台(P3P)策略可以通过P3P字段进行设置。资源的特定版本的标识符由ETag提供。这些是最常见的 HTTP 头字段,但还有更多,所有这些都在 RFC 4229 [1]中有描述。

清单 4-1。 HTTP 报头示例

HTTP/1.1 200 OK Date: Fri, 10 Sep 2010 10:05:08 GMT Server: Apache/2.2.16 (Unix) PHP/5.3.3 Content-Location: index.html Vary: negotiate,accept-language,accept-charset TCN: choice P3P: policyref=http://example.com/p3p.xml Cache-Control: max-age=21600 Expires: Fri, 10 Sep 2010 16:05:08 GMT Last-Modified: Fri, 21 Aug 2009 22:18:49 GMT ETag: "3668bab8;37e77d1c" Accept-Ranges: bytes Content-Length: 11537 Connection: close Content-Type: text/html; charset=UTF-8 Content-Language: en

互联网媒体类型(MIME)

互联网媒体类型(也称为哑剧类型内容类型)决定了浏览器处理网络文件的方式。它们是网站的文件格式标识符。因此,为网站组件和网页设置正确的媒体类型至关重要。

多用途互联网邮件扩展(MIME)规范是由互联网工程任务组在 1992 年提出的(关于 IETF 的更多信息,参见第一章)。大多数规范都以 IETF/ISOC 征求意见稿(RFC)的形式提供。尽管最初的 MIME 概念是为格式化非 ASCII 消息而设计的,但它在 web 浏览器中被用来呈现或处理(X)HTML 之外的文件。IANA 注册对互联网媒体类型进行了标准化(同样,参见第一章了解更多关于 IANA 的信息)[2]。非标准 MIME 类型和子类型可以通过它们的前缀来识别,因为它们都以x-开头。特定于供应商的子类型以vnd.开头,而个人子类型以prs.开头。

媒体类型至少由两部分组成:类型、子类型和可选参数。

XML 数据可以分配给两种 MIME 媒体类型:application/xmltext/xml。RFC 3023 [3]对它们进行了定义。此外,MIME 类型可以通过后缀+xml来识别。从 web 标准化组织的角度来看,最重要的媒体类型是为 XHTML 注册的 XML 媒体类型,即在 RFC 3236 [4]中定义的application/xhtml+xml。虽然 XHTML 文档可以使用application/xhtml+xmlapplication/xmltext/xml媒体类型,但是 W3C 推荐将 XHTML 作为 XML 使用其专用的 MIME 类型application/xhtml+xml [5]。然而,如果没有正确的 XML 头,使用这种媒体类型不能保证正确的 XML 处理(更多关于 XML 头的信息,见第三章)。此外,Internet Explorer 6 和更早的 IE 版本不呈现作为application/xhtml+xml的文档内容;相反,系统会提示用户下载该文件。


高级版本 S/MIME 也支持消息加密。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 注意如果 XHTML 网页的媒体类型设置为text/html,它将被解析为 HTML。如果媒体类型设置为application/xhtml+xml,浏览器会将文档解析为 XML。这是一个巨大的差异!使用正确 MIME 的 XHTML 文件不能包含一个错误;否则,文档将不会被呈现,XML 解析器将给出一个错误,正如前面在第一章和第三章中提到的。

另一种注册的 XML 媒体类型是application/atom+xml,它用于由提议的标准 RFC 4287 [6]定义的 Atom 联合格式(参见第八章)。这种类型的其他常用 XML 媒体类型有application/rss+xml(RSS;参见第八章)、application/mathml+xml(MathML;参见第三章),image/svg+xml(SVG;参见第三章),以及application/xslt+xml(XSLT;参见第五章。MIME 类型的完整列表发布在 IANA 网站上[7]。

HTTP 头的Content-Type字段将数据格式描述为 MIME 媒体类型(清单 4-2 )。此外,该条目还可以提供文档的字符编码(如前面在第二章中所讨论的)。

***清单 4-2。*一个内容类型的例子

Content-Type: application/xhtml+xml; charset=UTF-8

web 页面的 MIME 类型也可以用meta元素在文档级设置,如清单 4-3 中的所示。

***清单 4-3。*带有meta元素的 MIME 类型声明

<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />

一般来说,MIME 类型text/html用于 HTML 文档,application/xhtml+xml用于 XHTML 文档。然而,XHTML 文档可以同时支持这两者(我们将在本章后面看到)。

种类繁多的互联网媒体类型并不固定。自定义 MIME 类型也可以在 IANA 注册[8]。

常见媒体类型

下面几节列出了最常见的媒体类型。请注意,这绝不是一个完整的列表。

特定应用的媒体类型

表 4-1 总结了最常见的特定于应用的 MIME 类型。


2 不能在 IE8 或更早版本中使用

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

特定于供应商的媒体类型

表 4-2 总结了最常见的特定于供应商的 MIME 类型。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在不久的将来,与广泛使用的文件格式相关联的非标准化 MIME 类型很可能会被注册。application/x-dvi代表与设备无关的文档。LaTeX 文件的 MIME 类型application/x-latex也还没有标准化。Adobe Flash 文件可能会有已经广泛使用的媒体类型,application/x-shockwave-flash。可能与application/x-rar-compressed MIME 类型相关联的 RAR 存档文件也仍然没有标准化。

音频媒体类型

表 4-3 总结了最常见的音频 MIME 类型。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图像媒体类型

表 4-4 总结了最常见的图像 MIME 类型。

多部分对象媒体类型

表 4-5 总结了最常见的多部分对象介质类型。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

文字媒体类型

表 4-6 总结了最常见的文本媒体类型。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

视频媒体类型

表 4-7 总结了最常见的视频媒体类型。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

上菜 XHTML

提供 XHTML 有两种方法,这两种方法各有优缺点。下面几节将对它们进行描述。

将 XHTML 作为 HTML

在网络的早期,HTML 是唯一的标记语言。几年后,新的创新出现了,这些创新是 HTML 所不能覆盖的。XML 规则被加入其中,创造了 XHTML,一种新的标记语言。这些规则也是将 HTML 文档转换成 XHTML 时应该应用的规则,正如前面在第三章中讨论的。

但是,HTML 4.01 的词汇或多或少被保留了下来;因此,它类似于 XHTML 1.0。因此,XHTML 文档可以作为 HTML 提供给呈现引擎。这种方法提供了向后兼容性。媒体类型可以用来请求浏览器将 XHTML 作为 HTML 而不是 XML 来处理。如果一个 XHTML 文档的媒体类型被定义为text/html,那么渲染引擎会像解析 HTML 一样解析网页。如果给定媒体类型为application/xhtml+xml,浏览器将把文档作为 XML 处理。

默认情况下,一些服务器和服务器端脚本平台(PHP、ASP 等)将text/html媒体类型应用于 web 内容。XHTML 的“肮脏秘密”是几个带有 XML 解析器的浏览器将文档视为带有 XHTML 语法的text/html,将DOCTYPE视为 HTML。 3 但是向后兼容是有代价的:XML 令人印象深刻的特性根本无法在以这种方式服务的 XHTML 中使用。如果文档不能充分发挥其潜力,那么应用严格的规则又有什么意义呢?在向后兼容性不是主要问题的地方,解决方案是将 XHTML 作为 XML。

将 XHTML 作为 XML

在编程语言等许多环境中,错误是完全不被接受的。代码可靠性强烈依赖于标记结构和正确性。浏览器拒绝呈现无效 XHTML 标记的行为可能看起来很烦人;然而,浏览器有一个很好的理由这样做。充满错误的 HTML 文档通过猜测开发人员的意图来处理。浏览器不能每次都成功完成这项任务,也不能保证结果。此外,渲染引擎的误差容限提供了各种结果。

有些情况下错误是不可容忍的。例如,在科学出版中,数学方程式的表达应该是可靠的。如果这样的文档发布在 Web 上,并且在 XHTML 中嵌入了 MathML,那么错误是不可容忍的,因为后果可能会花费数百万甚至是致命的。这是 XML 解析器对错误极度敏感的主要原因。

作为一个 XML 语言家族,XHTML 本来是作为 XML 来使用的。这种方法享有 XML 的所有好处。然而,这也涉及到严重的风险。Web 文档作为application/xhtml+xml请求浏览器根据 XML 的规则处理它们。因为无效的 XHTML 标记根本不会在 web 浏览器中呈现,所以在将 XHTML 作为 XML 提供时应该格外小心。源代码中错误位置的一个简单字符会导致 XML 解析错误消息,而不是网页内容(正如第一章中已经暗示的)。大概这也是 HTML 一直被大部分内容作者和开发者所偏爱的原因之一。然而,真正的 web 标准化人员不应该害怕编写纯 XHTML 代码。如果您学会了如何使用前一章中描述的实践,您不仅能够创建无错误的 XHTML 文档,还能够创建任何类型的结构化标记。


真正的 XML 解析器,比如 Firefox 或 Safari,考虑的是文档的 MIME 类型(由服务器发送),而不仅仅是文件语法和文档类型。

尽管现代浏览器支持 MIME 类型,但一些老的浏览器不支持。保持与旧浏览器的向后兼容性并支持现代浏览器的高级 XML 应用的一个选择是称为内容协商的技术。可以通过.htaccess 4 设置或者使用服务器端脚本语言来完成。

HTTP 规范定义了为同一资源的不同版本服务的机制[60]。文档类型、文档语言和图像类型就是一些例子[61]。首选的和可接受的文档格式——在我们的例子中,是 HTML 和 XHTML 文件之间的首选——可以在 HTTP 头中定义,如清单 4-4 所示。

***清单 4-4。*HTTP 报头中的内容协商

Accept: text/html, application/xhtml+xml, application/xml; q=0.9, */*; q=0.8

使用前面的例子,浏览器可以指定 HTML 和 XHTML 优先于 XML。“相对质量参数”(q)及其值(qvalue)被认为如下。所有没有指定偏好值的项目都获得默认值1(在本例中为text/htmlapplication/xhtml+xml)。application/xml的指定值为0.9,所有其他格式为0.8。按降序排序的优先级值揭示了实际的优先级,换句话说,1表示text/htmlapplication/xhtml+xml,而0.9表示application/xml,而0.8表示任何其他内容类型。

在 Apache 服务器上,应该将清单 4-5 中所示的指令添加到您的.htaccess(或httpd.conf)文件中,以设置正确 MIME 类型所需的 HTTP 头。

**清单 4-5。**在text/htmlapplication/xhtml+xml之间的偏好

Options +Multiviews AddType application/xhtml+xml;qs=0.8 AddType text/html;qs=0.9

“源的质量”参数(qs),在我们的例子中设置为0.8,决定了AddType指令是否应用指定的 MIME 类型。由于application/xhtml+xmlqs值小于text/htmlapplication/xhtml+xml将只被兼容的浏览器使用;否则,首选版本将是 MIME 类型text/html

内容协商也可以用服务器端脚本语言实现。清单 4-6 、 4-7 和 4-8 总结了最常见的实现。

***清单 4-6。*PHP 中的内容协商

$accept = $_SERVER["HTTP_ACCEPT"]; $ua = $_SERVER["HTTP_USER_AGENT"]; if (isset($accept) && isset($ua)) {   if (stristr($accept, "application/xhtml+xml") || stristr($ua, "W3C_Validator")) {     header("Content-Type: application/xhtml+xml");   } }


4web 服务器上的通用配置文件(注意是以句点开头,没有扩展名)。

***清单 4-7。*ASP 中的内容协商

Dim strAccept, strUA strAccept = Request.ServerVariables("HTTP_ACCEPT").Item strUA = Request.ServerVariables("HTTP_USER_AGENT").Item If InStr(1, strAccept, "application/xhtml+xml") > 0 Or InStr(1, strUA, "W3C_Validator") > 0   Then Response.ContentType = "application/xhtml+xml" End If

***清单 4-8。*ASP 中 C#的内容协商。网

string accept = Request.ServerVariables["HTTP_ACCEPT"]; string ua = Request.ServerVariables["HTTP_USER_AGENT"]; if (accept != null && ua != null) {   if (accept.IndexOf("application/xhtml+xml") >=0 || ua.IndexOf("W3C_Validator") >= 0) {     Response.ContentType = "application/xhtml+xml";   } }

前面的代码使用自己的语法执行内容协商。例如,在 PHP 中,$_SERVER数组中包含的服务器变量用于评估用户代理的 HTTP Accept 头,并通过header函数设置适当的 MIME 类型(清单 4-6 )。

URIs、URL 和 urn

一个统一资源标识符 ( URI )是一个在互联网上标识一个名称或一个资源的字符串(RFC 2396 [62])。URIs 可以归类为统一资源定位符(URL;RFC 1738 [63])、统一资源名称 ( URNs )或两者。URN 定义了资源的身份,而 URL 提供了查找资源的方法(包括协议和路径)。URIs 经常被错误地用作 URL 的同义词,尽管 URI 是一个更广泛的术语(RFC 3305 [64])。URN 和 URL 都是 URI 的子集,但它们通常是不相交的集合。

URL 最著名的例子是万维网上的网站地址。清单 4-9 显示了通用的 URL 语法。

***清单 4-9。*网址语法

protocol://domain:port/path?query_string#fragment_identifier

协议 ( 方案名)后面跟一个冒号。URL 的其他部分取决于所使用的方案。通常有一个域名或 IP 地址,一个可选的端口号,以及一个可选的资源或脚本路径。PHP 或 CGI 脚本之类的程序可能有一个查询字符串。URL 的结尾可以是可选的片段标识符。

因为这些部分中有许多是可选的,所以省略了其中的一个或多个部分。清单 4-10 显示了一个例子,其中http是协议,[www.masteringhtml5css3.com](http://www.masteringhtml5css3.com)是域,路径指向shop目录。

***清单 4-10。*一个典型的网址

http://www.masteringhtml5css3.com/shop/

URI 引用在标记语言中被广泛使用,例如,作为 HTML 中a元素的href属性的属性值,或者作为 XML DTD 中SYSTEM关键字之后的系统标识符。

执着的 URIs

所有网络用户都知道,当浏览器地址栏中输入的网站地址无法检索时,会是什么样子。当用户单击网页的超链接时,也会发生同样的情况。

URIs 失去联系有很多原因。最简单的原因是文件已被移动到另一个文件夹或已从服务器上删除。另一个原因是服务器上应用的技术已经改变。例如,一家公司过去应用 CGI 脚本,但最近改用 Perl。在这种情况下,位于cgi-bin目录中的文件的 URIs 已经过时。

只有在少数情况下,停止维护 URIs 是可以接受的,例如公司或组织已经关闭。然而,应该消除无原因的变化。

设计不良的 URIs 是网页上大量死链接的罪魁祸首。将 URIs 设计成在未来几十年都可以使用是一项相当复杂的任务。

设计 URIs

可以通过最小化其中提供的信息来持久地设计 URIs[65]。更新文档的作者可能不同于原始文档的作者,因此作者不应包括在内。主题也应该被删除,因为它变化非常快。例如,一个网络技术博客应该使用目录名markup,而不是当前最新技术的确切名称(XHTML11HTML5)。表示文档状态的目录名,如draftlatest不应该在 URIs 使用,因为文档状态会随着时间而改变。每个文档的最新版本都需要一个持久的 URI。

网站的某些部分可能只对成员开放。还应取消 URIs 的查阅,因为文件可能会从私人部门转移到公共部门,反之亦然。

在 URIs 最常提供的无用信息是文件扩展名。目前被认为是最先进的技术和工具可能会在不久的将来发生变化,或者开发人员可能会改变应用的技术。更改 URIs 不仅会影响网页或网页组件的可查找性,还会影响您的维护任务。精心选择的目录名是合乎逻辑的,很少应该在标记的引用中更改。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示使用名称scriptscripts作为您存储网站脚本文件的目录,而不要使用phpjavascript,因为如果您以后采用进一步的脚本语言,网站文件中的 URIs 将反映一种特定的语言,而不是一个通用的名称。同样,目录名stylestylescssxsl更实用,名字newsfeedrssatom更吉利。名字imagesjpg好听,一个doc或者docs目录可以容纳从 PDF 到 Word 文档的多种文档,而不仅仅是某一种类型。

表示软件机制的目录名,如cgi-bin,也应该从 URIs 中删除。他们可能会改变。主题名称、公司部分、访问级别或安全级别也不适合 URIs。分类可以改变。创建日期是固定的,因此可以提供。请记住,通过代理和重定向,多个 web 服务器可以隐藏在一个明显的服务器中。

除了为用户和机器提供描述性的名称,URIs 应该简单、稳定和易于管理。正确设计的 URIs 是语义网的基础部分[66]。

域名

Web 资源可以通过唯一的 IP 地址来定位。然而,它们很难被记住。因此,在大多数情况下,域名被用来代替。图 4-1 显示了域名和 URL 的关系;[www.example.com](http://www.example.com)是节点example.com的子域,节点example.comcom域的子域。域名语法规则由 RFC 1035 [67]、RFC 1123 [68]和 RFC 2181 [69]定义。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

***图 4-1。*网址内的域名

子域树最多可以包含 127 级。每个标签最多可包含 63 个字符。根据 RFC 2181,域名的全长是 253 个字符。

传统的域名不能包含基于拉丁字母的带有音调符号的字符、非拉丁字符或文字。随着国际化域名(IDN)的引入,可以用本地字母和文字表示多种语言的名称和单词。

域名在注册之前应该仔细考虑。它们应该容易记忆和拼写[70]。还有 SEO 方面的考虑。虽然一个人的名字多年来通常保持不变,但一个产品或技术的名字可能会改变。例如,随着高清时代的开始,一家 DVD 商店的老板可能已经从销售 DVD 转向销售蓝光。但是包含 DVD 字样的域名还是代表老技术。如果使用了电影电影这个词,这个域名就不会过时。找到一个合适的域名,仍然是免费的,并包含流行的关键字,可以是一个真正的挑战。

没有 WWW

虽然www.子域名在网络上很常见,但一些网站管理员认为它已经过时或不合适[71]。类似于不使用request@mail.example.com格式的邮件服务器,web 服务器可以允许通过主域访问网页。

在 Apache 服务器上,通过将清单 4-11 中的代码添加到.htaccess文件中,可以将www.从域内的 URIs 中移除。它的名字代表超文本访问。该文件提供目录级的访问控制,可用于授权、认证、重定向、阻塞、定制错误响应和缓存控制。

**清单 4-11。**用.htaccess配置从 URIs 移除www.

RewriteEngine On RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC] RewriteRule ^(.*)$ http://example.com/$1 [R=301,L]

这段代码使得没有必要从网站的每个超链接中逐个删除www.。然而,很大一部分网站管理员不同意将www.从 URIs 移除。根据他们的推理,www.是一个提醒,万维网(WWW)只是互联网上众多服务之一。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示之前的代码实际上并不需要,因为域名注册价格中通常包含无限数量的子域名。一种常见的做法是,域所有者将主域和www子域指向 web 服务器的同一个目录。换句话说,[www.domain.com](http://www.domain.com)是首选的 URI,检索domain.com的用户被重定向到[www.domain.com](http://www.domain.com)。这样,无论有没有www,用户都可以访问相同的内容。

Base href

前面几节讨论了绝对 URL。由于许多网页组件位于与域相关联的根目录的子目录中,因此也可以使用相对 URL。然而,它们更短,并且不总是方便的。例如,如果层次太深,并且样式表位于一个网页上面三个目录的styles目录中,那么路径就会变得相当长(清单 4-12 )。

***清单 4-12。*复杂网站中的漫漫长路

<link rel="stylesheet" type="text/css" href="**../../../styles/main.css**" />

如果所有的位置都是根据根目录声明的话,情况会有所不同(清单 4-13 )。

***清单 4-13。*为网站设置基本目录

<base href=**"**http://example.com/**"** />

指定的 URL 用作文档中所有相对 URL 的基础。通过将base元素添加到文档头,可以简化最初的例子(清单 4-14 )。

***清单 4-14。*根据基目录的短路径

<link rel="stylesheet" type="text/css" href="**styles/main.css**" />

消除文件扩展名

创建永久 URIs 的关键技术之一是删除文件扩展名。在 Apache 等基于文件的 web 服务器上,可以通过内容协商【73】来完成。我们在本章前面使用了内容协商来设置 MIME 类型之间的优先级;现在我们将使用它来创建文件类型的优先顺序。因此,文件扩展名可以保留在文件中,但可以安全地从链接中删除[74]。

使用类型映射文件,Apache 服务器可以检查目录中具有给定名称和任何扩展名的所有文件,并选择适当的文件(优先级最高的文件)。类型映射文件优先于文件扩展名(即使启用了隐式文件名模式匹配的特殊搜索,多视图)。高质量图像文件变体的优先级可通过qs参数设置。在清单 4-15 中,文件logo.svg将被用于引用没有扩展名的文件的所有 URIs。如果目录中没有该文件的 SVG 版本,将使用 PNG 版本。

**清单 4-15。**由qs参数设置的文件类型的优先顺序

`URI: logo

URI: logo.svg
Content-type: image/svg+xml; qs=0.8

URI: logo.png
Content-type: image/jpeg; qs=0.5`

qs值从0.0001.000不等。永远不会选择qs值为0.000的变体。不同变体的条目由不能在条目内使用的空行分隔。

对于拥有成百上千个文件的大型站点来说,显式设置特定文件变量的路径是不可行的。Apache 服务器上内容协商的第二个选项是使用 MultiViews 搜索特性,服务器在目录中执行隐式文件名模式匹配,并从结果中进行选择。MultiViews 是消除文件扩展名的一个很好的选择,它有助于容易维护(如果将使用新的文件版本)和优化标记(因为链接更短)。多视图可以在服务器配置或.htaccess文件中启用(清单 4-16 )。

***清单 4-16。*多视图启用

<Directory /home/www/example/htdocs> Options + MultiViews </Directory>

现在,当服务器接收到对不存在 img/logoimg/logo的请求时,服务器在images目录中搜索所有名为logo.*的文件,根据每个文件的扩展名分配 MIME 类型。然后,服务器根据偏好选择最佳匹配,并交付该资源。例如,让我们假设images目录包含以下文件变量:logo.svglogo.pnglogo.gif。当有一个针 img/logo`的查询时,优先顺序将被考虑在对该查询的回答中(清单 4-17 )。

***清单 4-17。*图像文件格式的优先顺序

Accept: image/svg+xml; q=.8, image/png; q=.5, image/gif;q=0.2, */*;q=0.1

启用多视图时,服务器将搜索引用的目录,并以最高质量(由于最高优先级)交付图像,换句话说,logo.svg。这是在中实现的,这种方式使得 HTML/XHTML 文件中的 URIs 不需要包含文件扩展名,这使得维护更容易并且减小了文件大小。URIs 现在可以忽略资源背后的技术。由于example.cimg/logo.svg变成了example.cimg/logo,整个场地使用的 logo 嵌入也从<img src="logo.svg" alt="Company logo">变成了<img src="logo" alt="Company logo">

虽然以.html.php结尾的 URI 在不久的将来可能会保持不变,但即使是广泛使用的文件类型在几年内也可能会很快过时或不太常用。Flash 动画(.swf)可能会被更改为 HTML5 标记(.html),PNG 图像(.png)可能会被更改为 SVG 版本(.svg),等等。因此,所有当前创建的网站内部链接以及其他网站上的外部链接都将无效。

万维网联盟已经掌握了消除链接中的扩展名。即使网站的图像在链接中也没有扩展名(文件有扩展名),因此如果图像将被改变,例如从logo.pnglogo.svg,那么在数百个 web 文档中指向该文件的链接不应该被修改。

带有扩展名的引用仍然可用;然而,它们不允许服务器选择当前可用的和未来的格式中的最佳者。另一方面,通过类型地图声明或启用多视图搜索【75】,多年来使用的光栅图像可以立即更新为新的 SVG 版本。不带扩展名的文件名为内容类型通用,带扩展名的文件名为内容类型专用

有一个所有 web 服务器都支持的特殊文件,叫做index.html。当用户没有在地址栏中指定文件时,浏览器默认打开该文件(通过内容协商,扩展名不仅可以是.html,还可以是.php.jsp.aspx等等)。这就是为什么不需要在域名末尾输入文件名和扩展名如[www.example.com/index.html](http://www.example.com/index.html)就可以打开网站的原因。这种服务器行为也可用于创建对站点内网页的永久访问。不是将about.htmlservices.htmlportfolio.htmlcontact.html文件添加到域的根目录,而是将它们作为 index.html 文件提供在它们自己的子目录中。因此,网站的页面可以作为[www.example.com/about/](http://www.example.com/about/)[www.example.com/services/](http://www.example.com/services/)等访问,而没有文件扩展名。当然,如果在服务器上设置了每个目录的默认文件,也可以保留原始文件名。但是,在这种情况下,如果网站的宿主提供商发生变化,也应该迁移服务器设置。

命名空间 URIs

命名空间 URIs 用于唯一标识 XML 应用,并将其与其他 XML 语言区分开。当您希望将元素或属性与特定的 XML 名称空间相关联时,与名称空间 URI 相关联的前缀非常方便。虽然名称空间 URI 不一定指向特定的文档,但是很多都指向,比如 XHTML 1 使用的[www.w3.org/1999/xhtml](http://www.w3.org/1999/xhtml)名称空间。 x /5(之前在第三章中讨论过)。前面的名称空间 URI 将让 XML 解析器知道文档中使用的元素和属性来自 XHTML 词汇表。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 注意命名空间 URIs 可能揭示了相应的规范或标准,但许多只是占位符。

即使它们通常被设计成稳定的,名称空间也可能随着时间的推移而演变。为了消除这个问题,名称空间通常在purl.org【77】注册为持久统一资源定位符。如果它们指向的资源发生变化,可以在purl.org上的配置文件设置中修改 URI,这将为最新的 URI 提供永久地址。

XML 名称空间应该由相应的 W3C 推荐标准[78]控制。

总结

在本章中,您学习了 HTTP 头的一般结构,它提供了服务器发送的 web 文档的信息。到目前为止,您已经知道了最常见的 MIME 类型及其声明,这可以用来确保浏览器能够正确处理您的 web 站点组件。您还知道如何在服务器上使用内容协商来消除文件扩展名,这使得将来的维护更加容易。此外,您还学习了如何正确地服务 XHTML,这非常重要,因为用作application/xhtml+xml的 XHTML 文档将由 XML 解析器解析,而不是由对错误不太敏感的 HTML 解析器解析。你知道如何设计 URIs 来最大化他们的持久性。

到目前为止,您已经准备好创建符合标准的标记,并使用适当的设置来提供网站文件。在下一章中,你将学习使用层叠样式表(CSS)将网站内容从其表现中分离出来的技术。

参考文献

  1. 诺丁汉 M,Mogul J (2005) HTTP 标题字段注册。RFC 4229。互联网协会。tools.ietf.org/html/rfc4229。于 2011 年 8 月 15 日访问
  2. IANA (2007)哑剧媒体类型。互联网号码分配机构。www.iana.org/assignments/media-types/。2011 年 1 月 1 日访问
  3. Murata M,Laurent S,Kohn D (2001) XML 媒体类型。互联网协会。tools.ietf.org/html/rfc3023。2010 年 10 月 8 日访问
  4. Baker M,Stark P (2002)“应用/xhtml+xml”媒体类型。互联网协会。tools.ietf.org/html/rfc3236。2010 年 10 月 8 日访问
  5. Masayasu I (2002) XHTML 媒体类型。W3C 注释。万维网联盟。www.w3.org/TR/2002/NOTE-xhtml-media-types-20020801/。2010 年 10 月 8 日访问
  6. Nottingham M,say re R(eds)(2005)Atom 联合格式。互联网协会。tools.ietf.org/html/rfc4287。2010 年 10 月 8 日访问
  7. IANA (2007)哑剧媒体类型。互联网号码分配机构。www.iana.org/assignments/media-types/。2010 年 10 月 8 日访问
  8. IANA (2002)申请媒体类型。互联网号码分配机构。www.iana.org/cgi-bin/mediatypes.pl。2011 年 1 月 1 日访问
  9. Nottingham M,say re R(eds)(2005)Atom 联合格式。提议的标准。互联网协会。tools.ietf.org/html/rfc4287。2010 年 11 月 22 日访问
  10. Gregorio J,de Hora B (eds) (2007)原子出版协议。提议的标准。互联网协会。tools.ietf.org/html/rfc5023。2010 年 11 月 22 日访问
  11. Hoehrmann B (2006)脚本媒体类型。互联网协会。tools.ietf.org/html/rfc4329。2011 年 1 月 1 日访问
  12. crock Ford D(2006)JavaScript 对象符号(json)的应用/json 媒体类型。RFC 4627。互联网协会。tools.ietf.org/html/rfc4627。2011 年 1 月 1 日访问
  13. Carlisle D,Ion P,Miner R(eds)(2010)MathML 实例的媒体类型选择。数学标记语言(MathML)3.0 版。W3C 推荐。万维网联盟。www.w3.org/TR/MathML3/appendixb.html2011 年 1 月 2 日访问
  14. 自由 N,博伦斯坦 N (1996)八位流亚型。在:多用途互联网邮件扩展(MIME)第二部分:媒体类型。RFC 2046。互联网协会。tools.ietf.org/html/rfc2046。2011 年 1 月 1 日访问
  15. 冈萨尔维斯 I,菲佛 S,蒙哥马利 C (2008)奥格媒体类型。RFC 5334。互联网协会。tools.ietf.org/html/rfc5334。2011 年 1 月 1 日访问
  16. Taft E,Pravetz J,Zilles,Masinter L (2004)应用/pdf 媒体类型。RFC 3778。互联网协会。tools.ietf.org/html/rfc3778。2011 年 1 月 1 日访问
  17. 多用途因特网邮件扩展(MIME)第一部分:因特网消息体的格式。RFC 2045。互联网工程任务组。tools.ietf.org/html/rfc2045。2011 年 2 月 18 日访问
  18. 自由 N,博伦斯坦 N ( 1996) PostScript 亚型。在:多用途互联网邮件扩展(MIME)第二部分:媒体类型。RFC 2046。互联网协会。tools.ietf.org/html/rfc2046。2011 年 1 月 1 日访问
  19. Swartz A (2004)应用/rdf+xml 媒体类型注册。RFC 3870。互联网协会。www.ietf.org/rfc/rfc3870.txt。2011 年 1 月 2 日访问
  20. IANA(2007)MIME 类型应用/rtf 的注册。互联网号码分配机构。www.iana.org/assignments/media-types/application/rtf。2011 年 1 月 3 日访问
  21. 莱文森 E (1995) SGML 媒体类型。互联网号码分配机构。www.rfc-editor.org/rfc/rfc1874.txt。2011 年 1 月 3 日访问
  22. Hoschka P (2006)应用/smil 和应用/smil+xml 媒体类型。RFC 4536。互联网协会。www.ietf.org/rfc/rfc4536.txt。2011 年 1 月 3 日访问
  23. Baker M,Nottingham M (2004)“应用/soap+xml”媒体类型。RFC 3902。互联网协会。tools.ietf.org/html/rfc3902。2011 年 1 月 1 日访问
  24. Prud’hommeaux E,Seaborne A (2007)互联网媒体类型、文件扩展名和 Macintosh 文件类型。in:RDF 的 SPARQL 查询语言。万维网联盟。www.w3.org/TR/2007/CR-rdf-sparql-query-20070614/#mediaType。2011 年 1 月 3 日访问
  25. Beckett D,Broekstra J (eds) (2007)互联网媒体类型、文件扩展名和 Macintosh 文件类型。In: SPARQL 查询结果 XML 格式。万维网联盟。www.w3.org/TR/2007/CR-rdf-sparql-XMLres-20070925/#mime。2011 年 1 月 3 日访问
  26. Baker M,Stark P (2002)“应用/xhtml+xml”媒体类型。RFC 3236。互联网协会。tools.ietf.org/html/rfc3236。2011 年 1 月 1 日访问
  27. Murata M,St.Laurent S,Kohn D (2001) XML 媒体类型。RFC 3023。互联网协会。tools.ietf.org/html/rfc3023。2011 年 1 月 1 日访问
  28. 凯 M(编辑)(2007)XSLT 媒体类型。在:XSL 转换(XSLT)版本 2.0 中。W3C 推荐。万维网联盟。www . w3 . org/TR/2007/REC-XSLT 20-2007 01 23/# media-type-registration。2011 年 1 月 3 日访问
  29. 保罗·林德纳(编辑)(1993)注册新的 MIME 内容类型/子类型应用/zip。互联网号码分配机构。www.iana.org/assignments/media-types/application/zip。2011 年 1 月 1 日访问
  30. ashbridge M(2006)MIME 类型应用的注册/vnd.google-earth.kml+xml。互联网号码分配机构。www . iana . org/assignments/media-types/application/vnd . Google-earth . KML+XML。2011 年 1 月 3 日访问
  31. ashbridge M(2006)MIME 类型应用的注册/vnd.google-earth.kmz。互联网数字地址分配机构。www . iana . org/assignments/media-types/application/vnd . Google-earth . kmz。2011 年 1 月 3 日访问
  32. 林德纳 P (1993)注册的媒体类型申请/msword。互联网号码分配机构。www.iana.org/assignments/media-types/application/msword2011 年 1 月 2 日访问
  33. gill SS(1996)MIME 类型应用的注册/vnd.ms-excel。互联网号码分配机构。www . iana . org/assignments/media-types/application/vnd . ms-excel。2011 年 1 月 3 日访问
  34. gill SS(1996)MIME 类型应用的注册/vnd.ms-powerpoint。互联网号码分配机构。www . iana . org/assignments/media-types/application/vnd . ms-PowerPoint。2011 年 1 月 3 日访问
  35. 舒伯特 S (2009)应用/vnd . oasis . open document . graphics MIME 类型。互联网号码分配机构。www . iana . org/assignments/media-types/application/vnd . oasis . open document . graphics。2011 年 1 月 2 日访问
  36. 舒伯特 S (2009)应用/vnd . oasis . open document . presentation MIME 类型。互联网号码分配机构。www . iana . org/assignments/media-types/application/vnd . oasis . open document . presentation。2011 年 1 月 2 日访问
  37. 37.舒伯特 S (2009)应用/vnd . oasis . open document . spread sheet MIME 类型。互联网号码分配机构。www . iana . org/assignments/media-types/application/vnd . oasis . open document . spread sheet。2011 年 1 月 2 日访问
  38. 舒伯特 S (2009)应用/vnd . oasis . open document . text MIME 类型。互联网号码分配机构。www . iana . org/assignments/media-types/application/vnd . oasis . open document . text。2011 年 1 月 2 日访问
  39. 尼尔森 M (2000)音频/mpeg 媒体类型。RFC 3003。互联网协会。tools.ietf.org/html/rfc3003。2011 年 1 月 1 日访问
  40. barbato L(2008)Vorbis 编码音频的 RTP 有效载荷格式。RFC 5215。互联网协会。tools.ietf.org/html/rfc5215。2011 年 1 月 1 日访问
  41. Windows Media Services 的 Microsoft Support (2003) MIME 类型设置。KB 288102。微软公司。support.microsoft.com/kb/288102。2011 年 1 月 2 日访问
  42. 弗莱舍曼 E (1998)波和 AVI 编解码器注册。RFC 2361。互联网协会。tools.ietf.org/html/rfc2361。2011 年 1 月 1 日访问
  43. Boutell T 等人(1997) PNG(便携式网络图形)规范版本 1.0。RFC 2083。互联网工程任务组。tools.ietf.org/html/rfc2083。2011 年 1 月 1 日访问
  44. Randers-Pehrson G (2009)媒体类型图像/png 的注册。互联网号码分配机构。www.iana.org/assignments/media-types/image/png。2011 年 1 月 2 日访问
  45. Andersson O 等人(2008)图像/svg+xml 的媒体类型注册。In:可缩放矢量图形(SVG) Tiny 1.2 规范。W3C 推荐。www.w3.org/TR/SVGTiny12/mimereg.html。2011 年 1 月 2 日访问
  46. Parsons G,Rafferty J (2002)标记图像文件格式(TIFF)-图像/tiff MIME 子类型注册。RFC 3302。互联网协会。tools.ietf.org/html/rfc3302。2011 年 1 月 1 日访问
  47. Butcher S (ed) (2003)供应商树- vnd.microsoft.icon .互联网数字地址分配机构。www . iana . org/assignments/media-types/image/vnd . Microsoft . icon。2011 年 1 月 2 日访问
  48. Levinson E(1998)MIME 多部分/相关内容类型。RFC 2387。互联网协会。tools.ietf.org/html/rfc2387。2011 年 1 月 2 日访问
  49. Masinter L (1998)从表单返回值:多部分/表单数据。RFC 2388。互联网协会。tools.ietf.org/html/rfc2388。2011 年 2 月 18 日访问
  50. Galvin J,Murphy S,Crocker S,Freed N(1995)MIME 的安全多部分:多部分/签名和多部分/加密。RFC 1847。互联网工程任务组。tools.ietf.org/html/rfc1847。2011 年 1 月 2 日访问
  51. Lie H,Bos B,Lilley C (1998)文本/css 媒体类型。RFC 2318。互联网协会。tools.ietf.org/html/rfc2318。2011 年 1 月 2 日访问
  52. Shafranovich Y (2005)逗号分隔值(CSV)文件的通用格式和 MIME 类型。RFC 4180。互联网协会。tools.ietf.org/html/rfc41802011 年 1 月 2 日访问
  53. “文本/html”媒体类型。RFC 2854。互联网协会。tools.ietf.org/html/rfc2854。2011 年 1 月 2 日访问
  54. Hoehrmann B (2006)脚本媒体类型。RFC 4329。互联网协会。tools.ietf.org/html/rfc4329。2011 年 1 月 2 日访问
  55. Gellens R (2004)文本/普通格式和 DelSp 参数。互联网协会。tools.ietf.org/html/rfc3676。2011 年 1 月 2 日访问
  56. Lim Y,Singer D(2006)MPEG-4 的 MIME 类型注册。RFC 4337。tools.ietf.org/html/rfc4337。2011 年 1 月 2 日访问
  57. 冈萨尔维斯 I,菲佛 S,蒙哥马利 C (2008)奥格媒体类型。RFC 5334。互联网工程任务组。tools.ietf.org/html/rfc5334。2011 年 1 月 2 日访问
  58. 林德纳·P(编辑)(1993 年)。MIME 内容类型/子类型视频/quicktime 的注册。互联网号码分配机构。www.iana.org/assignments/media-types/video/quicktime。2011 年 1 月 2 日访问
  59. Windows Media Services 的 Microsoft Support (2003) MIME 类型设置。微软公司。support.microsoft.com/kb/288102。2011 年 1 月 2 日访问
  60. 诺丁汉 M,Mogul J (2005) HTTP 标题字段注册。互联网协会。tools.ietf.org/html/rfc4229。2010 年 10 月 8 日访问
  61. Fielding R,Irvine UC,Gettys J,Mogul J,Frystyk H,Masinter L,Leach P,Berners-Lee T (1999)超文本传输协议-HTTP/1.1。万维网联盟和互联网协会。www.w3.org/Protocols/rfc2616/rfc2616-sec14.html。2010 年 10 月 8 日访问
  62. Berners-Lee T,Fielding R,Masinter L (1998)统一资源标识符(URI):一般语法。RFC 2396。互联网协会。tools.ietf.org/html/rfc2396。2011 年 1 月 18 日访问
  63. 伯纳斯-李 T,马辛特 L,麦卡希尔 M(编辑)(1994 年)统一资源定位器(网址)。RFC 1738。互联网工程任务组。tools.ietf.org/html/rfc1738。2011 年 1 月 18 日访问
  64. Mealling M,dene nberg R(eds)(2002)W3C/IETF URI 计划兴趣小组联合报告:统一资源标识符(URIs)、URL 和统一资源名称(urn):澄清和建议。RFC 3305。互联网协会。tools.ietf.org/html/rfc3305。2011 年 1 月 18 日访问
  65. 伯纳斯-李 T (1998)酷 URIs 不改变。万维网联盟。www.w3.org/Provider/Style/URI。2010 年 12 月 13 日访问
  66. Sauermann L,Cyganiak R (eds),Ayers D,vlkel M(2008)语义网的酷 URIs。W3C 兴趣小组说明。万维网联盟。www.w3.org/TR/cooluris/。2011 年 2 月 18 日访问
  67. Mockapetris P (1987)域名-实施和规范。RFC 1035。互联网工程任务组。tools.ietf.org/html/rfc1035。2011 年 1 月 19 日访问
  68. Braden R (ed) (1989)互联网主机的要求-应用和支持。RFC 1123。互联网工程任务组。tools.ietf.org/html/rfc1123。2011 年 1 月 19 日访问
  69. Elz R,Bush R (1997)对 DNS 规范的说明。RFC 2181。互联网工程任务组。tools.ietf.org/html/rfc2181。2011 年 1 月 19 日访问
  70. 尼尔森 J (2007) URL 作为用户界面。雅各布·尼尔森。www.useit.com/alertbox/990321.html。2011 年 1 月 19 日访问
  71. 没有 WWW (2008) www。已弃用。no-www.org/。2011 年 1 月 19 日访问
  72. 汉普顿 M (2011) www。不推荐使用。迈克尔·汉普顿。www.yes-www.org/。2011 年 1 月 19 日访问
  73. Fielding R,Irvine UC,Gettys J,Mogul J,Frystyk H,Masinter L,Leach P,Berners-Lee T (1999)内容协商。输入:超文本传输协议-HTTP/1.1。互联网协会。www.w3.org/Protocols/rfc2616/rfc2616-sec12.html。2010 年 10 月 8 日访问
  74. TASF (2011)内容协商。Apache HTTP 服务器版本 2.0。阿帕奇软件基金会。httpd.apache.org/docs/2.0/content-negotiation.html。2011 年 1 月 23 日访问
  75. TASF (2011)阿帕奇模块修改 _ 协商。阿帕奇软件基金会。httpd . Apache . org/docs/2.0/mod/mod _ negotiation . html # type maps。2011 年 1 月 23 日访问
  76. Berners-Lee T (ed) (2011)命名空间随时间而变化。在:W3C 命名空间的 URIs。万维网联盟。www.w3.org/2005/07/13-nsuri。2011 年 2 月 18 日访问
  77. OCLC,泽费拉(2011)持久统一资源定位器(PURL)。OCLC 在线计算机图书馆中心有限公司。purl.org。2011 年 2 月 18 日访问
  78. Bray T,Hollander D,Layman A,Tobin R,Thompson HS(eds)(2009)XML 1.0 中的名称空间(第三版)。W3C 推荐。万维网联盟。www.w3.org/TR/xml-names/。2011 年 2 月 18 日访问

五、样式表

网站标准化的金科玉律是将内容和外观分开。XHTML 元素消除了样式属性。样式表应该在外部文件中提供。CSS 中提供的样式定义与早期 HTML 文档中应用的内联样式具有相似的特性。然而,命名约定和附加机制经常令人困惑。除了代码有效性之外,还有其他一些特性,如范围、属性值继承和分隔符的顺序,也应该考虑这些特性以获得优化的 CSS 文件。

在这一章中,你将学习常用的网站样式标准,包括一般的 CSS 语法规则和对每个网站都至关重要的选择器语法。在研究了不同 CSS 版本的属性之间的差异之后,您将对标准化问题和提供向后兼容性的挑战有一个坚实的理解。您还将熟悉 CSS 规则集优化的基本原则。此外,您将分析渲染引擎用于确定要应用的样式的方法。

层叠样式表

层叠样式表 ( CSS )是 W3C 推出的一种样式表语言(style language)。层叠是指确定样式规则优先级的过程。CSS 用于定义结构化文档的表示语义。它提供了对 HTML 和 XHTML 文档及其元素的视觉和听觉特征的控制。一些典型的特征是,例如,字体、颜色、背景、边距、边框和层。CSS 提供了一个强大的特性,不仅支持可视媒体,还支持在不同类型的设备上运行的特殊浏览器:媒体类型。CSS 不仅支持最常用的视觉媒体类型,还支持其他媒体类型,这些媒体类型可以按如下方式分组:

  • 听觉:听觉浏览器的属性。例子:pitchpitch-rangeplay-duringrichnessvoice-family
  • 交互:允许用户交互的设备属性。例子:nav-downnav-indexnav-leftnav-rightnav-up

尽管与 web 文档相关的大多数样式都是视觉的,CSS 也支持听觉属性,包括音量、说话、暂停、提示、空间属性和声音特征。它们用于听觉表达,例如当一个文档被转换为纯文本并输入到屏幕阅读器时。除了提高可访问性,听觉样式表在在线教育、娱乐、车内使用等方面也有潜力。

  • 分页和不连续:分割成一页或多页的文件内容属性,如要打印的文件页面。例子:image-orientationpagepage-break-beforepage-break-insidepage-policysize
  • 语音:语音样式属性。例子:cuecue-aftercue-beforemarkmark-aftermark-beforepausespeak-headerspeak-numeralspeak-punctuationspeech-ratestress

正如您将在本章后面看到的,大多数 CSS 属性都是可视属性,或者可以应用于所有媒体,但也有许多属性是为特定媒体类型设计的。

CSS 的主要概念之一是将 HTML/XHTML 内容与外观分开,换句话说,将样式与结构区分开来。另一个目标是集中化,这意味着从一个位置提供对多个文档样式的完全控制。

尽管 CSS 主要用于样式化(X)HTML web 文档,但它也可以应用于所有种类的 XML 文档,例如 XUL 或 SVG [1 ]。在 SVG 中,许多 CSS 属性在样式中被重用,例如字体属性、文本属性和其他可视属性。SVG 还使用 CSS 特性,比如 CSS 语法、选择器、外部样式表、级联、继承和 at-rules,稍后将详细描述其中的每一项。由于 SVG 是一个 XML 应用,内部 CSS 样式表可以作为 CDATA 部分提供(清单 5-1 )。

***清单 5-1。*在 SVG 中嵌入 CSS

`<?xml version="1.0" standalone="no"?>

              Here is my title `

CSS 甚至可以在有或没有 MathML 的情况下用于数学符号,MathML 是在第三章第一部分中讨论的标记语言,它是专门为在网络上发布方程式和数学符号而设计的 [2 , 3 ]。

级别、配置文件和模块

CSS 的各种版本通常被称为 CSS 级别。每个 CSS 级别都基于前一个级别,并添加了新的属性和功能。三个最重要的版本是 CSS1、CSS 2.1 和 CSS3。

为特定设备创建的至少一个 CSS 级别的子集被称为 CSS 简档,例如 CSS 打印简档 [4 、CSS 电视简档 [5 、以及 CSS 移动简档 [6 。

构成 CSS3 的规范被称为 CSS 模块

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 注意配置文件不等于媒体类型,这是在 CSS2 中引入的。

下面几节将介绍三个主要的 CSS 版本。

CSS1

CSS Level 1 是第一个级联样式表规范,发布于 1996 年。它是 W3C 推荐的,但是它的开发已经被 W3C [7 ]关闭了。CSS1 引入了字体属性、元素颜色、对齐、表格、边距、边框、填充和定位的样式。CSS1 属性可以应用于唯一标识的元素或元素组。

CSS2 和 CSS 2.1

CSS Level 2 是作为 CSS1 的超集开发的,并且已经扩展了几个新特性。最重要的是层顺序(z-index)、三种元素定位(absoluterelativefixed)、aural媒体类型和双向文本。

CSS Level 2 Revision 1,通常缩写为 CSS 2.1 [8 ],多年来一直是 Web 上最终的样式解决方案。CSS 2.1 在 2011 年成为 W3C 推荐标准。

CSS3

CSS3 的开发始于 2005 年。与其他 CSS 规范相比,CSS3 是模块化的 [9 。它由单独的文档描述,如模块选择器、媒体查询、文本、背景和边框、颜色、2D 变换、3D 变换、过渡、动画和多栏。这些模块处于不同的开发和浏览器实现阶段。直到最近,只有少数模块被标准化了,比如色彩模块 [10 ]。

CSS3 中引入了各种新的功能和特性,如border-radiusbox-shadowbackground-origin;HSL、HSLA 和 RGBA 的颜色声明;text-shadowtext-overflowword-wrapbox-sizing;属性选择器;多栏布局;网络字体;和演讲。

语法和惯例

由不存在的属性、不正确的值、格式错误的声明等引起的解析错误可以通过遵循正确的 CSS 语法来消除。该语法确保了 CSS 在语法上的正确性,这使得浏览器能够正确地处理解析规则、选择器、属性、值和单元符号。虽然基本规则是相似的,但是每个 CSS 版本都有自己的语法 [11 ]。作为 CSS 2.1 的超集,CSS3 引入了额外的语义约束。

标识符和类别

ID 和类标识符应该总是以字母开头。因为这些标识符对应于idclass标记属性,并且因为具有id属性的元素在网页中是唯一的,所以 ID 标识符可以用于样式化页面的唯一元素。如果相同的样式应用于多个元素,应该使用类标识符。标识符名称区分大小写。强烈推荐使用字母a–z和数字0–9,尽管下划线和连字符也是允许的。名字应该有意义和语义。应该使用唯一的名称。

单位

CSS 支持多个测量值,这些测量值汇总在表 5-1 中。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 尽管种类繁多,但大部分时间只使用其中三种单位:%empx

颜色声明

CSS 中有几种表示颜色的符号。以下部分提供了一个简要的概述,这是很重要的,因为颜色声明的例子将在整个章节的演示规则集中大量使用。

十六进制表示法

十六进制表示法是目前为止 CSS 中声明颜色最常用的表示法。在网页上使用的 RGB 颜色空间中,任何颜色都可以通过加色混合来表示,使用三种颜色的不同强度变量:红色、绿色和蓝色(RGB)。三种基色的 256 种色调足以混合任何颜色,因为人眼不能区分强度差为 1/256 的任何两种相邻的红色、绿色或蓝色色调。由于每个通道有 256 个色调,每个通道的值从 0 到 255(十六进制表示法中的00ff)不等;0 是通道最暗的阴影,255 是最亮的。

十六进制数字系统应用位置(也称为位值)符号。与十进制数字系统的 10 个数字相反,十六进制系统中有从09af的 16 个符号(字母代表从1015的值)。最后一个符号对应于乘以 16 的 0 次2的值,最后一个符号之前的符号代表乘以 16 的 1 次幂的值,依此类推。

因此,十六进制的符号09对应十进制的相同数字,而十六进制的a等于十进制的10b11c12d13e14f15。可以通过位值计算更多的数字(从0开始)。比如十六进制值e8对应十进制值232,因为 14 161+8 160= 14 16+8 1 = 224+8 = 232。从十进制到十六进制的转换可以类似地执行,但是计算过程相反。比如十进制记数法中的86是十六进制记数法中的56,因为 86/16 = 5.375,所以第一位数字是 5。5 16=80,余数是 6,是第二位数,因为 5 161+6 160= 5 16+6 1 = 80+6 = 86。

在 CSS 中,十六进制颜色声明以一个数字符号(#)开始,后面是六个十六进制(hex)值,每个通道两个。它们被用来任意混合颜色。比如纯红色可以通过#ff0000设置。换句话说,红色通道的强度最大(ff),而绿色和蓝色的强度最小(00)。同样,纯绿色是#00ff00,而纯蓝色是#0000ff。如果每个通道的值都设置为00,则结果为黑色(#000000)。如果所有值都是最大值,则得到白色(#ffffff)。如果每个通道的值相同,结果是灰色阴影(清单 5-2 )。

***清单 5-2。*为所有段落声明灰色字体颜色

p {   color: #898989; }

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示如果每个通道的两位数相同,可以通过省略第二位来缩写。例如,#f00代表红色,#0f0代表绿色,#00f代表蓝色,#000代表黑色,#fff代表白色等等。

RGB 和 RGB(a)符号

RGB 模型中每个颜色通道的饱和度也可以用十进制数或百分比来声明(清单 5-3 )。

***清单 5-3。*简单的 RGB 符号

p {   color: rgb(0, 255, 0) /*  equivalent to rgb(0, 100%, 0), #00ff00 and #0f0 */ }


任何非零的 0 次幂都是 1。

CSS 2.1 支持前面的符号,但在 CSS3 中已经扩展了颜色的透明度(alpha 通道)。这种符号被称为 RGB(a)。例如,透明度为 75%的纯绿色(相当于 25%的不透明度)可以如清单 5-4 中的所示进行声明。请注意,alpha 始终是一个百分比(从 0 到 1 的值),而不是像其他颜色一样从 0 到 255。

***清单 5-4。*CSS3 中的一个 RGB(a)符号

p {   color: rgb(0, 255, 0, **0.25**); }

HSL(a)符号

在 CSS 中,颜色也可以用 HSL(a)符号来表示,其中颜色由它们的色调、饱和度和亮度来表示。第一个值可以是 0 到 360 之间的数字,而第二个和第三个值可以声明为百分比。alpha 通道的工作方式与 RGB(a)相同(清单 5-5 )。

***清单 5-5。*HSL(A)符号中的透明色

#warning {   background-color: hsl(240, 78%, 50%, 0.25); }

提示如果你想使用照片或网站上看到的颜色,你可以通过多种方式获得代码。首先,您可以检查页面或站点的样式表中的颜色代码。如果不方便,还有其他技术可以得到色标。如果您的计算机上没有安装高级图像处理应用,您只需使用“打印屏幕”按钮创建一个屏幕截图,然后将其复制并粘贴到基本的图像处理应用,如 Microsoft Paint。选择拾色器工具,然后单击您选择的颜色。从“颜色”菜单中选择“编辑颜色”选项,然后单击“定义自定义颜色”。 3 你得到颜色的色相、明度、饱和度,以及红、绿、蓝分量。因为它们是以十进制提供的,所以需要用诸如 Windows Calculator 之类的应用将其转换成十六进制(在科学模式下)。如果您有比 Paint 更高级的图像操纵器,如 Adobe Photoshop,您可以在粘贴的图像上使用拾色器工具,以获得不同颜色空间和符号的颜色代码,包括十进制和十六进制。


Windows 7 中的 Paint 版本有一个功能区界面,而不是早期版本中的传统菜单。

网页安全色

在彩色电脑屏幕的最初几年,电脑只支持 256 种不同的颜色。在那个时代,216 种颜色的列表被称为网页安全色。这种跨浏览器调色板用于确保所有计算机,包括使用 256 色调色板的计算机,都能正确显示颜色。网页安全色由每个通道的003366ccff值组成(例如00ff00663300993300cc6600ff9966)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 注意从表现的角度来看,网页安全色不再有趣,因为所有现代的屏幕、显示器和投影仪都能够表现 RGB 色彩空间中的任何颜色。

颜色名称

CSS 支持 16 种基本颜色的名称。这些关键字比它们对应的十六进制值 4 ( 表 5-2 )更容易读懂。然而,强烈建议使用十六进制记数法(见第十三章)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


4 学会了用十六进制记数法调色后,使用数值就成了例行任务。

选择器语法

一个 CSS 选择器识别 CSS 样式将被应用的那些标记元素。特定的元素组由各种类型的选择器决定样式。一个 CSS 规则(或者多个声明的 CSS 规则集)的一般结构如图图 5-1 所示,可以用清单 5-6 所示的伪代码编写。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5-1。 CSS 规则结构

***清单 5-6。*CSS 规则集的伪代码

selector [, selector*2*, …, selector*n*] [:pseudo-class] {   property: value;   [property*2*: value*2*;    …   property*m*: value*m*;] }

同一个选择器的多个声明可以组织成用分号(;)分隔的组。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示虽然在规则集中省略最后一个声明后面的分号是合法的,但是强烈建议总是提供分号。它使维护和修改变得更加容易,当一个声明被移动到 CSS 中的另一个位置时变得非常方便。

例如,清单 5-7 中的规则可以写成清单 5-8 所示。

***清单 5-7。*单独声明同一个元素的规则不是最佳选择

**h1** { font-weight: bold } **h1** { font-size: 1.6em } **h1** { font-family: Verdana }

***清单 5-8。*同一元素的规则应分组

**h1** {   font-weight: bold;   font-size: 1.6em;   font-family: Verdana; }

虽然它们是等效的,但出于许多原因,第二个版本应该是首选的。首先,它更短,因此有助于码长优化。其次,其他选择器的进一步声明可能会意外地插入单行之间,使得 CSS 文件更难维护。最后,第二种排列更容易阅读,这使得开发更容易。

元素选择器

如果一个网站的所有段落都要用 Garamond 以 1.2em 的字体大小编写,那么规则集看起来就像清单 5-9 中的。

***清单 5-9。*所有段落的规则集

**p** {   font-size: 1.2em;   font-family: Garamond; }

这适用于标记中的所有段落,例如清单 5-10 中的段落。

***清单 5-10。*由清单 5-9 的规则集设置样式的段落

**<p>**  A paragraph. **</p>** **<p>**  Another paragraph. **</p>**

自然,段落的子集可能有不同的规则集,部分或全部覆盖一般规则(见本章后面的“层叠”一节)。

在前面的示例中,选择器选择了一个标记元素。这样的选择器被称为元素选择器,并自己应用相应的元素名称。花括号包含要设置样式的元素的属性,以及应该将它们更改为的值。花括号和它们之间的内容是声明块。属性-值对之间用分号分隔。属性与其值之间用冒号分隔。每行被称为一个声明声明

选择器由组合子分隔,即空格、 >+ 。在组合符和它们周围的简单选择器之间可能会出现更多的空白字符 [12 ]。

如果应用相同的 CSS 规则,选择器也可以被分组。应该使用逗号( , )作为组合符。对通用规则进行分组有助于 CSS 代码的优化。例如,清单 5-11 分别用id属性articlesrelatedlinks改变两个div元素的颜色和字体大小。

***清单 5-11。*通用规则可以分组以避免重复

**#articles, #relatedlinks** {   color: white;   font-size: 1.8em; }

班级选择器

以句点(.)开头的类选择器,选择所有class属性与其中指定的值相同的元素。由于class属性可以在一个网页中多次应用,所以类选择器可以用相同的类标识符来设计文档中任何元素的样式。例如,清单 5-12 中的规则在标记中被引用,如清单 5-13 和清单 5-14 所示。

***清单 5-12。*类选择器示例

**.abstract** {   font-size: 1.1em;  }

***清单 5-13。*清单 5-12 中的类选择器可以应用于标题

<h3 **class="abstract"**>Abstract</h3>

***清单 5-14。*同样的类选择器也可以应用于段落

`<p class=“abstract”>
 The abstract of the first Chapter

`

如果规则集应该应用于具有指定类名的某些类型的元素,则可以通过在句点之前提供元素名称来编写更具体的规则。例如,如果前面的规则只对段落有效,那么它应该通过声明所需的元素类型来扩展(清单 5-15 )。

***清单 5-15。*对所有具有类名abstract 的段落的规则

**p.abstract** {   font-size: 1.1em;  }

ID 选择器

某些标记元素在整个 web 文档中是唯一的;也就是说,它们在每个网页上只能出现一次。它们由标识符属性id识别。那些选择 web 页面上唯一元素的选择器,其id属性等于其中指定的值,这些选择器被称为 ID 选择器,并以一个散列标记(#)开始。清单 5-16 显示了一个例子。

***清单 5-16。*一个 ID 选择器示例

**#main** {   margin-left: 120px; }

清单 5-17 显示了一个应用了先前规则的标记示例。

***清单 5-17。*可应用 ID 选择器#main的示例内容

`<div id=“main”>
  The main content has a left margin of 120 pixels.

`
通用选择器

一个通用选择器匹配网页上任何元素类型的名称(任何元素,不管是什么类型)。通用选择器标有星号(*)。清单 5-18 显示了一个例子。

***清单 5-18。*通用选择器示例

*****.caution {   color: #ff2318; }

如果通用选择器不是简单选择器的唯一组件,星号可以省略(清单 5-19 )。

***清单 5-19。*可以安全省略星号的规则

.caution {   color: #ff2318; }

考虑到清单 5-20 中显示的标记,选择器div * em将匹配大多数em元素,并应用于h1 ( favorite)、p ( impressive)、第一个li元素(hybrid electric)和第二个li ( fuel efficient)中em元素的内容。在后两种情况下,*ulli匹配。

***清单 5-20。*通用选择器的示范标记

`
  


    

My favorite car


    

The Lexus CT 200h is impressive due to the following reasons:


    

  •       
  • It is a hybrid electric car.

  •       
  • It is a fuel efficient car.

  •     

    That’s why it is a nice entry-level luxury hatchback.
  

`

因为内容为entry-level luxuryem元素是div元素的直接子元素,所以*divem之间没有匹配的内容。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 注意通用选择器在 Internet Explorer 7 及更早版本中的实现并不完美。

属性选择器

属性选择器选择方括号内指定属性的每个元素。属性类型或具有特定值的属性可以用它们来设置样式。例如,通过应用清单 5-21 中所示的规则,文档中所有具有title属性的img元素都可以有一个黄色边框。

**清单 5-21。**带有属性的属性选择器示例

**img[title]** {   border-color: #ff0; }

属性选择器不仅可以用于属性,还可以用于属性-属性值对。例如,使用清单 5-22 所示的 CSS 规则,可以给网页中的所有logo.png图像添加 10 像素的边框。

***清单 5-22。*带有属性和属性值的属性选择器

**img[src="logo.png"]** {   border: 10px; }

这适用于整个网页中清单 5-23 中标记的多个实例。

***清单 5-23。*一个标记代码,其中清单 5-22 被应用

<**img src="logo.png"** alt="logo" />

子选择器

子选择器当且仅当右边的元素是左边元素的直接子元素时,选择选择器中右边的元素。在子代和祖先之间使用大于号(**>**)。清单 5-24 显示了一个例子。

***清单 5-24。*子选择器示例

**td > a** {   font-weight: bold; }

这适用于表格数据单元格内的所有超链接,例如在清单 5-25 中,但一般不影响超链接,例如在清单 5-26 中。

***清单 5-25。*清单 5-24T5 中子选择器的超链接示例

**<td><a** href="http://www.nairobicity.go.ke/"**>**Nairobi, Kenya**</a></td>**

***清单 5-26。*子选择器示例不适用于不是数据单元格子元素的锚点

**<a** href="http://www.capital.sp.gov.br/"**>**São Paulo, Brazil**</a>**

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 注意Internet Explorer 6 及更早版本不支持子选择器。

后代选择器

DOM 树上较低位置的元素样式可以由使用空格分隔的元素名称的后代选择器提供。与子选择器相比,后代选择器不要求子元素是祖先的直接子元素。清单 5-27 显示了一个例子。

***清单 5-27。*后代选择器示例

**td a** {   font-weight: bold; }

这适用于表格数据单元格内的所有超链接,例如清单 5-25 (类似于前面显示的子选择器)或清单 5-28 。然而,这个规则一般不影响超链接。

***清单 5-28。*一个锚示例,其中清单 5-27 被应用

**<td><p>**One of the unique attractions of **<a** href="http://www.nairobicity.go.ke/"**>**Nairobi, Kenya**</a>** is the Nairobi National Park.**</p></td>**

注意子选择器和后代选择器之间的区别。

相邻同级选择器

相邻同级选择器选择选择器右侧的元素,当且仅当它旁边有左侧元素的实例时。**+**符号被用作组合符。兄弟元素在 DOM 层次结构中处于同一级别。清单 5-29 显示了一个例子。

***清单 5-29。*相邻同胞选择器示例

**h2 + p** {   color: #0f0; }

该选择器适用于清单 5-30 ,但不适用于清单 5-31 和清单 5-32 。

***清单 5-30。*应用来自清单 5-29 的绿色的元素

**<h2>**Heading**</h2>** **<p>**A paragraph**</p>**

***清单 5-31。*不适用清单 5-29 中所示规则的一段

**<p>**A paragraph**</p>**

***清单 5-32。*由于段落前缺少二级标题,此处也不应用该样式

**<h1>**Heading**</h1>** **<p>**A paragraph**</p>**

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 注意IE6 或更早版本不支持相邻同级选择器。

伪班

伪类使用冒号将元素与其状态分开,是更复杂的选择器。根据超链接的状态,它们经常用于确定超链接的样式。例如,清单 5-33 适用于所有的a元素,但是只有当鼠标悬停在链接上时。

**清单 5-33。**当一个锚停留在上时应用的链接颜色

**a:hover** {   color: #000080; }

再比如清单 5-34 ,将所有已经访问过的 5 的超链接颜色改为绿色。


5 显示当前浏览器历史记录

***清单 5-34。*链接颜色设置为已访问的超链接

**a:visited** {   color: #0f0; }

伪元素

伪元素可用于为特定元素部分而非整个元素添加样式。它们也可以应用于在某些元素之前或之后插入内容。组合符是一个冒号(:)。例如,清单 5-35 中的 CSS 规则将网页中所有段落的第一个字母的字体大小改为 2 em。

***清单 5-35。*段落第一个字母的规则

**p:first-letter** {   font-size: 2em; }

属性值类型

CSS 属性值可以是以下内容:

  • 关键词(例如,auto)
  • 基本数据类型(例如,%)
  • 关键字和自定义数据的组合(例如,url('[example.cimg/book.png](http://example.cimg/book.png)')
速记符号

某些 CSS 属性可以分组到单个属性声明中。最常见的速记符号将在以下章节中介绍。

字体属性的速记符号

字体属性可以写成清单 5-36 中的完整形式,也可以写成清单 5-37 中的简写形式。

***清单 5-36。*如果要为同一个元素设置多个字体属性,规则集会变得太长

p {   font-weight: bold;   font-size: 1em;   line-height: 1.2em;   font-family: Garamond;   font-style: normal; }

***清单 5-37。*字体属性的速记符号

p { font: bold 1em/1.2em Garamond }

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 注意在第二种情况下,font-style属性没有被设置,因此取 CSS 规范中为该属性定义的默认值,即normal

背景属性的速记符号

单独的背景属性(清单 5-38 )具有简写属性background ( 清单 5-39 )。

***清单 5-38。*可缩短的独立背景属性

body {   background-color: #232323;   background-image: url('img/bg.jpg');   background-repeat: no-repeat;   background-position: 100% 0%;   background-attachment: fixed; }

***清单 5-39。*背景属性合并成一个单一的背景属性

body {   background: #232323 url('img/bg.jpg') no-repeat 100% 0% fixed; }

列表属性的速记符号

列表样式,比如在列表 5-40 中的样式,也可以通过枚举list-style速记属性的单个属性值来缩短(列表 5-41 )。

***清单 5-40。*列出可以缩短的款式

ul.tick {   list-style-image: url('tick.png');   list-style-type: none;   list-style-position: inside; }

***清单 5-41。*三个列表样式属性值的单行规则

ul.tick {   list-style: url('tick.png') none inside; }

填充、边框和边距属性的简写符号

有五个属性用于设置顶部、右侧、底部和左侧填充(分别为padding-toppadding-rightpadding-bottompadding-left)或所有这些属性以及速记属性padding。对于边框(border-topborder-rightborder-bottomborder-leftborder)和边距(margin-topmargin-rightmargin-bottommargin-leftmargin)也存在类似的约定。有多种选项可以缩短属性值枚举的顺序:

  • Four values set the padding of each side: the top, the right, the bottom, and finally the left padding (clockwise, starting from top) (Listing 5-42).

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示这个顺序值得记忆,因为它不仅可以用于填充,还可以用于边框和边距。

    ***清单 5-42。*用四个值填充速记属性

    #decor {   padding: 10px 5px 20px 30px; }

  • Three values set the top, right, and left (equally), and the bottom padding (Listing 5-43).

    ***清单 5-43。*用三个值填充速记属性

    #decor {   padding: 10px 20px 15px; }

  • Two values set an equal padding for the top and bottom sides, and then an equal padding for the right and left sides (Listing 5-44).

    ***清单 5-44。*用两个值填充速记属性

    #decor {   padding: 30px 20px; }

  • One value sets an equal padding for all sides (Listing 5-45).

    ***清单 5-45。*用一个值填充速记属性

    #decor {   padding: 10px; }

类似的简写符号可用于通过bordermargin简写属性设置 border 和 margin 属性值。进一步的填充、边框和边距属性也可以用速记符号书写。清单 5-46 显示了一个例子。

***清单 5-46。*可以缩短的边框属性

.book {   border-width: 1px;   border-style: solid;   **border-top-color: #000;**   **border-right-color: #000;**   **border-bottom-color: #000;**   **border-left-color: #000;** }

因为在这个例子中每边的边框颜色都是一样的,所以第三、四、五、六行中的属性可以写成border-color ( 清单 5-47 )。

清单 5-47。border-color速记属性设置元素每一侧的边框颜色

.book {   border-width: 1px;   border-style: solid;   **border-color: #000;** }

即使边框颜色不同,也可以通过简单地按照上、右、下、左的顺序(顺时针,从顶部开始)枚举所需的颜色,由border-color速记属性来声明。

所有先前的属性仍然可以缩短为一行,如清单 5-48 所示。

***清单 5-48。*多物业最短边界申报

.book {   border: 1px solid #000; }

实施

有三种方法可以实现 CSS。选择的方法决定了样式的范围。

  • Inline style: Styling with the most limited scope. An inline style is embedded in an (X)HTML tag to which it exclusively applies. This CSS fragment is defined by the style attribute that can be provided on most markup elements. The attribute value has the same syntax as the contents of a CSS declaration block except that the delimiting braces are omitted [13]. Listing 5-49 shows an example.

    ***清单 5-49。*内联样式声明示例

    <img src="logo.png" **style="**margin: 10px;**"** alt="logo" />

  • Embedded (internal) style: A code block usually located in the document head. Embedded styles are used for styling rules unique to that web page (the element to style does not occur in other pages on the site). Listing 5-50 shows an example.

    ***清单 5-50。*嵌入式风格的一个例子

    `
      …
    **  **
      …

    `
  • External style sheet: An external style sheet is a separate file with the .css extension that contains style rules for multiple web documents, such as an entire web site. This is a plain-text file usually encoded in US-ASCII. CSS files cannot contain the style element, just the CSS style rules themselves. Each page refers to that file with the link element in the (X)HTML head section. Listing 5-51 shows an example.

    ***清单 5-51。*链接到 XHTML 中的外部样式表文件

    **<link rel="stylesheet" type="text/css" href="**main.css**" />**

    在 XML 文档(XML、XUL、SVG 等)中,外部样式表可以由第一个文档段 [14 ] ( 清单 5-52 )中的 XML 处理指令 xml-stylesheet提供。

    ***清单 5-52。*链接到 XML 格式的外部样式表文件

    **<?xml-stylesheet type="text/css" href="**default.css**"** title="Default style" **?>**

嵌入样式会覆盖在外部 CSS 文件中声明的相应样式,这使得在为单个网页声明一些特定规则时,可以使用网站的主要样式规则。内联样式更加具体,并且局部覆盖外部样式表的样式以及嵌入的样式(如果有的话)。

样式表也可以用@import规则从其他样式表文件导入 CSS 规则。它应该在@charset规则(如果有)之后但在所有其他规则之前提供。如果额外的 CSS 文件在同一个目录结构中,那么路径就足够了(清单 5-53 )。

***清单 5-53。*重用外部样式表

**@import "**styles/alter.css**";**

包含此规则的文件的规则集将覆盖导入样式的相应规则(如果有)。例如,如果一个站点的不同页面有相同的样式,除了作为设计的一部分被修改的background-color,那么所有的样式都可以被导入并且background-color属性被覆盖(在清单 5-54 中的alter.css)。类似地,为移动设备设计的样式表可以重用主要样式,但删除背景图像 6 ,并将文档主体的最大宽度设置为当今智能手机可用的最大屏幕宽度(清单 5-54 中的mobile.css)。其他款式都是进口的,包括colorfont-family

***清单 5-54。*重用和扩展网站主 CSS 文件的样式

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

更健壮的声明提供的不是文件的路径,而是文件的 URL。清单 5-55 显示了一个例子。

***清单 5-55。*通过提供完整的 URL 导入样式表文件

@import url("http://www.example.com/alter.css");

导入样式表的应用之一是为 web 站点提供替代样式,这些样式有多种用途。例如,可以通过为不同的媒体提供不同的样式表来提高可访问性。站点的特定于媒体的 CSS 文件可以在标记中由link元素上的media属性控制,正如前面在第三章中讨论的。这种 CSS 文件的规则集有一个由站点的主 CSS 文件定义的交集。特定于媒体的规则的文件相互依赖,并且经常从彼此导入规则(清单 5-56 )。多个 CSS 文件也可以用于网站设计。


6 在这个例子中,background-image属性是使用main.css文件中的速记属性background设置的。

***清单 5-56。*导入特定媒体风格

@import url("print.css") print; @import url("mobile.css") handheld and (max-width: 480px);

显示和可视性

HTML 和 XHTML 文档的元素级别已经讨论过了。在 CSS 中,(X)HTML 元素通常可以通过以下方式显示:

  • Block: Uses the full width available, along with a new line before and after (Listing 5-57)

    ***清单 5-57。*元素显示为块的规则

    display: block;

  • Inline: Uses only as much width as needed without breaking the row (Listing 5-58)

    ***清单 5-58。*元素内联显示规则

    display: inline;

  • Not displayed: Removes the element completely from the document so it does not take up any space, even though its corresponding markup is still in the source code (Listing 5-59)

    ***清单 5-59。*无空格隐藏元素的规则

    display: none;

  • Hidden: Hides the element but still takes up space in the layout (Listing 5-60)

    ***清单 5-60。*用空格符隐藏元素的规则

    visibility: hidden;

层叠

CSS 中的 C 代表级联。它是一种机制,用于确定一组样式规则中的一个声明,这些规则应该应用于某个元素-属性对。浏览器按照以下顺序考虑三个特征来选择声明 [15 ]:

  1. Weight: The declaration with the highest weight is chosen. In CSS3, the weight of a declaration is based on the origin of the declaration and its level of importance. The origin can be of three kinds: author, user, and user agent. CSS declarations have two levels of importance: normal and important (the first one is the default level; the second one is optional and should be marked). An important declaration looks like Listing 5-61.

    ***清单 5-61。*最重要的规则

    #menu {   margin-top: 12px **!important**; }

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示级联机制的适当利用消除了对!important规则的需要。

    源自不同来源的样式表的权重按降序排列如下:

    1. 用户样式表(重要)
    2. 作者样式表(重要)
    3. 创作样式表(普通)
    4. 用户样式表(普通)
    5. 渲染引擎的默认样式表

    因此,开发人员编写的声明通常比用户样式表更重要,用户样式表比浏览器的默认样式更重要。这就是为什么链接通常用网站开发者定义的字体颜色而不是默认的锚色来呈现的原因(清单 5-62 )。

    ***清单 5-62。*CSS 文件中的规则比浏览器默认样式表中的相应规则权重更大

    a {   font-color: #12ee12; }

  2. Specificity: The declaration with the highest specificity is chosen. The specificity of selectors can be calculated as follows [16]:

    • 计算选择器中 ID 属性的数量。
    • 计算选择器中其他属性和伪类的数量。
    • 计算选择器中元素名称的数量。
    • 这些数字的串联就是特异性。
    • 负选择器的计数类似于它们的简单选择器参数。
    • 伪元素被忽略。

    在清单 5-63 中,第一个声明的特异性最低,最后一个声明的特异性最大。所有段落的字体颜色都是相同的(黑色),除了包含在一个分区中的那些段落,它们具有不同的字体颜色(绿色)。具有为class属性声明的tip值的div元素有一个更具体的规则,这使得它们的字体颜色与众不同(红色,不同于任何其他段落的颜色)。

    ***清单 5-63。*越来越具体的声明

    `p {
      color: #000;
    }

    div p {
      color: #0f0;
    }

    .tip p {
      color: #00f;
    }`

  3. 声明顺序:如果两个声明具有相同的权重、来源和特性,则选择最后一个声明(还应考虑导入的样式表)。导入的样式规则在样式表规则之前处理。进一步导入的样式表规则按照@import规则的顺序考虑。

继承

在 web 标记语言和样式表中,某些代码会被自动重用。在 CSS 中,父元素的属性值可以设置给它们的子元素。元素-属性组合的指定值是从父元素的相应计算值中复制的。这个过程叫做继承。它消除了定义简单属性的需要。例如,如果定义了 web 文档的背景色,文档中的所有容器元素、分隔线和段落都将继承该属性。当然,它们中的任何一个都可以被任意覆盖。

某些 CSS 属性值被定义为继承的。除非为这些元素-属性组合指定了值,否则该值由继承决定。

inherit值可用于通过继承确定的所有属性。例如,颜色是一种可继承的属性。然而,锚元素的颜色通常被用户代理样式表设置为蓝色。通过使用值inherit,用户代理样式表的声明可以被覆盖:所有子锚元素从父元素继承前景色的值(清单 5-64 )。

***清单 5-64。*继承的财产价值

#warning {   color: #000; } #warning a:link {   color: inherit; }

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 应该考虑的是,属性越具体,可以应用的元素就越少。正如您将在 CSS 属性概述中看到的,很大一部分 CSS 属性根本没有被继承。

范围和结构

与最初几年使用的带下划线的蓝色超链接不同,现代网站经常使用不同的颜色和装饰来适应整体设计。然而,当超链接使用虚线下划线时,链接图像共享相同的样式是相当令人沮丧的。为了解决这个问题,应该移除图像边框并设置更具体的样式。清单 5-65 显示了一个例子。

***清单 5-65。*消除一般规则声明的链接下划线的具体规则

`img {
  border: 0;
}

a.nounder {
  border-bottom: none;
}`

规则的范围对它们的应用有很大的影响。适用于同一类别中更多(大多数)元素的规则应该在网站开发的早期阶段确定。例如,如果绝大多数段落都有相同的缩进,那么这个值应该作为一个通用的 CSS 规则应用于所有的p元素(例如,p { text-indent: 3em; }),而另一个规则应该写入不同的段落类(例如,p.morein { text-indent: 5em; })。

在最佳情况下,对于那些可以作为整个网站基础的属性,范围和继承都要考虑,比如默认字体大小(清单 5-66 )。

***清单 5-66。*整个网站的默认字体大小可以从文档体继承

body {   font-size: 0.8em; }

对于那些需要不同字体大小的元素,比如标题,可以专门设置该属性(清单 5-67 ),所有其他元素继承为文档正文设置的默认字体大小。因此,没有必要为所有的pdiv元素声明字体大小,如果它们所需的字体大小是默认的,因为属性是从body元素继承的。

***清单 5-67。*覆盖先前清单中设置的默认字体大小的特定声明

h1 {   font-size: 1.4em; } h2 {   font-size: 1.2em; } h3 {   font-size: 1em; }

盒子模型

块元素的实际标记内容由可选的填充边框边距包装,称为 CSS 盒模型 ( 图 5-2)17。这些矩形框是为文档树中的某些标记元素生成的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

***图 5-2。*CSS 盒子模型

文本和图像出现在内容中。填充清除内容周围的区域。填充受框的背景颜色影响,类似于填充周围的边框区域。边距是边框周围最外面的区域。它没有背景色,是透明的。每个区域的大小可以由 CSS 属性决定。既然是可选的,也可以折叠到0(即完全消除)。

两个垂直相邻的块体元件的边缘通常会相互塌陷;也就是说,边距根据第一个框的较大底部边距的大小以及它下面的另一个框的顶部边距的大小来呈现。

IE 盒子模型 Bug

从 CSS 的第一个版本开始,所有块级元素的宽度和高度都是显式指定的,只决定可见元素的宽度或高度,填充、边框和边距是在以后应用的。在早期版本的 Internet Explorer 中,CSS 规范实现不正确,这通常被称为 Internet Explorer box 模型错误。例如,Internet Explorer 5 将内容、填充和边框包含在指定的宽度或高度内,导致框的呈现更窄或更短 [18 ] ( 图 5-3 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

***图 5-3。*W3C 和 IE5 盒子模型的比较。注意宽度的不同解释。

Internet Explorer 6 和更新的 IE 版本 7 在其符合标准的模式下应用了正确的实现,但出于兼容性的原因,当页面以怪癖模式呈现时,bug 仍然存在。

CSS 属性概述

表 5-3 总结了 CSS 属性的丰富选择。CSS1 中有 53 个属性,CSS2 中有 120 个,CSS 2.1 中有 115 个,CSS3 中有 200 多个(还在增加中)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


Mac 版的 ie 浏览器(于 2006 年停产)中没有这个漏洞。


8none 值适用于所有介质。

浏览器对 CSS 属性的支持各不相同,并且正在逐步改进。然而,即使是 CSS 2.1 属性也只是在最近才获得了或多或少的完整和正确的实现。因此,旧的浏览器不支持所有的属性,并且许多属性的实现不正确。这是多年来在不同浏览器下呈现同一个网站的巨大差异的主要原因。随着 CSS 属性在现代浏览器中的正确实现(如果不是完全实现的话),这种差异已经减少到最小。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示强烈建议谨慎应用 CSS3 规则,因为 CSS3 的大部分模块尚未标准化,浏览器支持也各不相同。造型不是一个“要么一切要么什么都没有”的命题。例如,基本的 CSS 属性——也是 CSS 2.1 和大多数浏览器所支持的——可以用来定位一个div元素,并为它提供诸如背景颜色、字体大小和边距之类的样式。尽管通过使用 CSS3 属性border-radius声明的圆角不能在旧的浏览器中呈现,但是总的布局和样式在旧的浏览器中提供了与支持 CSS3 的现代浏览器相似的外观。类似地,如果在网站上使用 Web 字体嵌入——旧版浏览器不支持——一个通用字体和至少一个通用字体系列应该被声明为后备机制(详见第九章)。

初始属性值

所有 CSS 属性都有它们的初始值,当属性值既不是通过级联也不是通过继承设置时,这些初始值就会被应用。每个属性的初始值由 CSS 规范定义。初始值是相应 CSS 属性的允许值之一。例如,颜色声明(以任何允许的格式,通常以十六进制表示),transparentinherit都是background-color属性的合法值,其中transparent是初始值,通过在 CSS 文件中声明所需的值可以很容易地覆盖它(清单 5-68 )。

***清单 5-68。*声明的值覆盖 CSS 规范定义的初始值

body {   background-color: #198c00; }

这就是为什么所有段落、分割和其他元素的背景都是透明的原因。另一个例子是列表的项目符号类型,它经常在没有覆盖的情况下使用。如果属性list-style-type的值不是开发者设置的,则使用初始值进行渲染,也就是disc。但是,它可以被该属性的任何其他允许值覆盖,包括circlesquaredecimaldecimal-leading-zerolower-romanupper-romanlower-greeklower-latinupper-latinarmeniangeorgianlower-alphaupper-alphanoneinherit。最后一个值inherit不仅可以应用于list-style-type,还可以应用于任何其他 CSS 属性,以便显式应用相应属性的初始值。

因为根元素没有父元素,所以默认情况下,它的值被设置为初始属性值。

渲染引擎的默认样式

由于呈现引擎的默认样式表包含某些属性的不同属性值,因此网站开发人员未声明的属性值在各种浏览器下可能会有所不同。由于不同的行高、边距、字体大小和其他属性,网站的整体外观通常是不一致的。尽管某些默认属性值只是略有不同,但开发人员不能依赖于呈现引擎的默认样式。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示通过覆盖渲染引擎默认样式表的 CSS 属性值,可以最小化浏览器 CSS 实现之间的不一致性。这种技术叫做 CSS 重置。最著名的 CSS 重置文件之一是由 Eric A. Meyer 编写和维护的(清单 5-69 ),可以在您的网站上免费使用 [ 19 ]。

***清单 5-69。*CSS 复位

/* http://meyerweb.com/eric/tools/css/reset/   v2.0 | 20110126   License: none (public domain) */ html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {   margin: 0;   padding: 0;   border: 0;   font-size: 100%;   font: inherit;   vertical-align: baseline; } /* HTML5 display-role reset for older browsers */ article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {   display: block; } body {   line-height: 1; } ol, ul {   list-style: none; } blockquote, q {   quotes: none; } blockquote:before, blockquote:after, q:before, q:after {   content: '';   content: none; } table {   border-collapse: collapse;   border-spacing: 0; }

XSL

虽然它并没有被广泛使用,而且只有有限的 web 开发人员熟悉它,但是自 1999 年以来,除了 CSS 之外的一种技术也可以用于样式化某些 web 文档。可扩展样式表语言 ( XSL )是一个语言家族,可用于 XML 文件的样式化、操作和转换。有三种 XSL 语言;然而,其中只有一种是样式表语言:

  • XSL 转换(XSLT):一种 XML 样式表语言,可用于将 XML 文档转换成其他 XML 文档或其他格式,如 HTML 或纯文本。原始文档保持不变,并基于现有文档创建一个新文档。
  • XSL 格式化对象 (XSL-FO):一种 XML 标记语言,用于指定 XML 文档的可视化格式。一些软件支持 XSL-FO,可以提供各种输出格式,包括纯文本、PDF、PS、SVG、PCL 和 MIF。
  • XML 路径语言(XPath):XSLT 也可以使用的非 XML 查询语言。
XSLT 样式表

XSLT 样式表由一个或多个样式表模块组成,这些模块是 XML 文档的一部分,或者单独形成整个 XML 文档。XSLT 的典型文件扩展名是.xsl.xslt。XSLT 样式表使用媒体类型application/xslt+xml

名称空间

XSLT 名称空间是[www.w3.org/1999/XSL/Transform](http://www.w3.org/1999/XSL/Transform)。但是,XSLT 处理器 [21 ]也可以识别其他(保留的)名称空间,包括:

  • 标准函数命名空间,[www.w3.org/2005/xpath-functions](http://www.w3.org/2005/xpath-functions)
  • XML 命名空间,[www.w3.org/XML/1998/namespace](http://www.w3.org/XML/1998/namespace)
  • 模式名称空间,[www.w3.org/2001/XMLSchema](http://www.w3.org/2001/XMLSchema)
  • 模式实例名称空间,[www.w3.org/2001/XMLSchema-instance](http://www.w3.org/2001/XMLSchema-instance)
结构

XSLT 样式表的结构看起来像清单 5-70 中的。

清单 5-70。 XSLT 样式表结构

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">   <xsl:import href="…"/>   <xsl:include href="…"/>   <xsl:strip-space elements="…"/>   <xsl:preserve-space elements="…"/>   <xsl:output method="…"/>   <xsl:key name="…" match="…" use="…"/>   <xsl:decimal-format name="…"/>   <xsl:namespace-alias stylesheet-prefix="…" result-prefix="…"/>   <xsl:attribute-set name="…">     …   </xsl:attribute-set>   <xsl:variable name="…">…</xsl:variable>   <xsl:param name="…">…</xsl:param>   <xsl:template match="…">     …   </xsl:template>   <xsl:template name="…">     …   </xsl:template> </xsl:stylesheet>

请注意,前面的示例显示了所有允许的元素类型;然而,样式表可能包含零个或多个这样的元素。

元素

XSLT 样式表在 XML 文档中由xsl:stylesheetxsl:transform元素表示。一个xsl:stylesheet元素必须有一个version属性。xsl:stylesheet元素可以包含以下类型的元素:xsl:importxsl:includexsl:strip-spacexsl:preserve-spacexsl:outputxsl:keyxsl:decimal-formatxsl:attribute-setxsl:paramxsl:variablexsl:namespace-aliasxsl:template。表 5-4 提供了 XSLT 1.0 元素的概述。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

XSLT 元素的应用很简单,并且遵循一般的 XML 创作原则。清单 5-71 显示了一个例子。

清单 5-71。 XSLT 元素和属性符合 XML 指南

<xsl:param name="page-header-margin">20px</xsl:param>

标准属性

几个标准属性与 XSLT 元素相关联,包括versionexclude-result-prefixesextension-element-prefixesxpath-default-namespacedefault-collationuse-when。为了将它们与作者定义的属性区分开来,它们应该用名称空间符号写成xsl:versionxsl:exclude-result-prefixesxsl:extension-element-prefixesxsl:xpath-default-namespacexsl:default-collationxsl:use-when

结合 CSS 和 XSL

XSL 还可以用作复杂的基于 XML 的文档和 CSS 格式模型之间的桥梁。因为 CSS 没有 XML 语法,所以 CSS 属性在 XSL 语法中变成了 XML 属性。主 CSS 对象是chunk。可能还需要其他对象。通常它们是其他具有功能的chunk对象,如anchor,或者更远的对象,如switch。例如,清单 5-72 中的 CSS 规则集可以用 XSL 语法编写,如清单 5-73 所示。

***清单 5-72。*要转换成 XSL 的 CSS 规则集示例

{   font-size: 1.2em;   text-indent: 1em; }

***清单 5-73。*清单 5-72 中的 XSL 等价物

<css:chunk   font-size="1.2em"   text-indent="1em">

总结

在这一章中,你学习了如何将表示和内容分开,这在网站标准化中是必要的。您知道级联样式表的语法,这是几乎每个网站都使用的语言。您已经掌握了 CSS 选择器的使用,并可以在日常工作中应用它们来精确控制那些需要样式化的元素或元素集的外观。到目前为止,您已经知道如何放心地使用 CSS 的层叠功能,这使得创建长度最佳且易于维护的 CSS 文件成为可能。您还知道如何通过应用回退机制和即使是旧浏览器也支持的属性来确保向后兼容性。您了解了 XML 文件不仅可以用 CSS 样式化,还可以用 XSL 样式化。

在下一章,你将学习服务器端脚本和 web 应用的标准化问题。

参考文献

1。Dahl strm E、Dengler P、Grasso A、Lilley C、McCormack C、Schepers D、Watt J、Ferraiolo J、Jun F、Jackson D(eds)(2011)CSS 造型。在:SVG 1.1(第二版)。万维网联盟。www.w3.org/TR/SVG/styling.html#StylingWithCSS于 2011 年 8 月 18 日访问

2。Chavchanidze G (2004)用层叠样式表格式化数学文章。安德烈·拉兹马兹数学研究所。www.princexml.com/samples/math.pdf2010 年 10 月 9 日访问

3。Bos B,Carlisle D,Chavchanidze G,Ion PDF,Miller BR(2011)A MathML for CSS Profile。W3C 推荐。万维网联盟。www.w3.org/TR/mathml-for-css/2011 年 8 月 18 日访问

4。Grant M (ed) (2006) CSS 打印配置文件。万维网联盟。www.w3.org/TR/css-print/于 2011 年 8 月 17 日访问

5。Hayes S,Adams G,elik T,Lie HW (2003) CSS 电视简介 1.0。万维网联盟。www.w3.org/TR/css-tv于 2011 年 8 月 17 日访问

6。舒伯特的 CSS 移动配置文件 2.0。万维网联盟。www.w3.org/TR/css-mobile/于 2011 年 8 月 17 日访问

7 .。Lie HW,Bos B (2008)级联样式表,级别 1。W3C 推荐标准(修订版)。万维网联盟。www.w3.org/TR/CSS1/2010 年 10 月 9 日访问

8。博斯 B、切利克 T、希克森 I、李 HW (eds) (2011)级联样式表 2 级修订版 1 (CSS 2.1)规范。万维网联盟。www.w3.org/TR/CSS21/2011 年 8 月 18 日访问

9。Meyer EA,Bos B (eds) (2001)模块描述和相关信息。请参阅:CSS3 简介。W3C 工作草案。万维网联盟。www.w3.org/TR/css3-roadmap/#module2010 年 10 月 9 日访问

10。elik T,Lilley C,Baron LD,Pemberton S,Pettit B (eds) (2011) CSS 颜色模块级别 3。万维网联盟。www.w3.org/TR/css3-color/于 2011 年 8 月 18 日访问

11。博斯 B,切利克 T,希克森 I,李 HW(编辑)(2011)CSS 2.1 语法。在:级联样式表级别 2 修订版 1 (CSS 2.1)规范中。W3C 推荐。万维网联盟。www.w3.org/TR/CSS21/grammar.html.于 2011 年 8 月 18 日加入

12。博斯 B,切利克 T,希克森 I,李 HW(编辑)(2011)选择器语法。在:级联样式表级别 2 修订版 1 (CSS 2.1)规范中。W3C 推荐。万维网联盟。www.w3.org/TR/CSS21/selector.html#selector-syntax2011 年 8 月 18 日访问

13。埃利克 T,埃特马德 EJ(编辑)(2010)语法和解析。输入:CSS 样式属性。万维网联盟。www.w3.org/TR/2010/CR-css-style-attr-20101012/#syntax。2010 年 10 月 16 日访问

14。Clark J,Pieters S,Thompson HS (eds) (2010)将样式表与 XML 文档关联 1.0(第二版)。W3C 推荐。万维网联盟。www.w3.org/TR/xml-stylesheet/2010 年 11 月 2 日访问

15。李华伟(编辑)(2005)级联。在:CSS3 模块:级联和继承。W3C 工作草案。万维网联盟。www.w3.org/TR/2005/WD-css3-cascade-20051215/#cascading2010 年 10 月 10 日访问

16。格雷兹曼 D,切利克 T,希克森 I,林斯 P,威廉姆斯 J(编辑)(2001)计算一个选择器的特异性。输入:选择器。万维网联盟。www.w3.org/TR/2001/CR-css3-selectors-20011113/#specificity2010 年 10 月 10 日访问

17。博斯 B,切利克 T,希克森 I,李 HW (2010)箱型模型。在:级联样式表级别 2 修订版 1 (CSS 2.1)规范中。W3C 工作草案。万维网联盟。www.w3.org/TR/CSS21/box.html2010 年 12 月 12 日访问

18。Silver L (2006)固定盒子,而不是在盒子外面思考。in:Internet Explorer 6 中的 CSS 增强功能。微软公司。msdn . Microsoft . com/en-us/library/bb 250395 . aspx # CSS enhancements _ topic 3。于 2011 年 8 月 19 日访问

19。Meyer EA,Meyer KS (2011) CSS 工具:重置 CSS。埃里克. a .迈耶凯瑟琳. s .迈耶。meyerweb.com/eric/tools/css/reset/于 2011 年 8 月 19 日访问

20。Clark J (ed) (1999) XSL 转换(XSLT)版本 1.0 W3C 推荐标准。万维网联盟。www.w3.org/TR/xslt2010 年 10 月 12 日访问

21。凯 M(编辑)(2007) XSL 转换(XSLT)版本 2.0。W3C 推荐。万维网联盟。www.w3.org/TR/xslt20/2010 年 10 月 12 日访问

六、脚本和应用

许多现代网页都是动态的。它们不仅仅只有句法结构和语义。不同的网站部分可以有不同的行为,并可能对用户交互作出反应。较大的站点需要需要处理的数据库。小程序可以在远程服务器或本地计算机上运行。但是,服务器端语言生成的内容往往是不正确的。尽管内容作者不能影响内容管理系统的硬编码部分,但模板通常提供了包含标准化潜力的手工编码选项。

在本章中,您将了解为什么动态内容的标准化比静态页面的标准化更具挑战性。熟悉最广泛使用的客户端和服务器端脚本语言的基本语法是至关重要的,因为用这些语言编写的小程序通常嵌入到标记中。因此,脚本嵌入可能会影响整个网页的标准符合性。您还将学习如何为脚本提供替代内容。虽然使用 web 编程语言、框架和开发平台来提供 web 应用的服务器端生成的标记的标准符合性在不断提高,但仍然有许多结果页面包含错误的情况。这些开发技术中有许多尚未标准化,但仍在全球范围内使用。因此,其中一些被认为是事实上的标准。许多技术依赖于许多其他技术,有些依赖于标准。本章提供了一些最常见的脚本和应用开发技术的快速概述;然而,这份清单无论如何都不完整。

客户端-服务器架构

分布式应用结构在资源或服务提供者(称为服务器和服务请求者(称为客户端)之间划分任务和/或工作负载,称为客户端-服务器模型。客户端和服务器通过 Web 进行通信,以交换数据和执行任务。

客户端-服务器架构代表了 web 应用中协作程序之间的关系。例如,联系人表单可以在客户端进行评估,在服务器端进行处理。

下面几节将讨论最流行的客户端和服务器端脚本和编程语言、技术和框架的一般语法和语法约定。请注意,脚本和应用的详细描述超出了本书的范围。从标准化的角度分析 Web 编程。直接嵌入到标记中的脚本对标准的符合性有相当大的影响,所以标准化组织应该关注有效的嵌入。虽然内容管理系统(CMSs)的核心在许多情况下是硬编码的,但是它们的模板可以被用户修改,这使得提供符合标准的代码片段成为可能。

脚本和标准实现

一个脚本是在运行 [1 ]之前不需要预处理(比如编译)的程序代码。web 文档的小动态组件,如当前日期或交互式内容和行为可以通过脚本语言添加。可以在网页内容上执行修改,而无需重新加载页面的新版本。使用异步 JavaScript 和 XML ( Ajax )可以在网页上添加或发送内容,也不需要重新加载新的页面版本。

客户端脚本有恒定的内容,如果仔细提供,可以产生有效的标记。另一方面,服务器端脚本提供了动态生成的内容。当检查标记错误时,作为该任务基础的程序的源代码相当复杂。此外,由服务器端脚本技术生成的标记中使用的模板在许多情况下是硬编码的,不能被内容作者修改。对拥有成千上万网页的大型网站进行验证和标准化实际上是不可能的。

依赖于存储在数据库中并由服务器端脚本处理的数据的网站的主要问题是较高的复杂性和缺乏完全控制。CMSs 使用的模板并不总是符合标准的。因此,这些模板的所有错误都存在于应用这些模板的数千个站点中。此外,脚本或数据库的单个问题会导致错误消息,而不是网页内容(图 6-1 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

***图 6-1。*内容被错误信息替换

在网页上运行的小程序和为生成网页而创建的程序有着巨大的区别。服务器端脚本语言功能强大,提供了静态内容无法实现的特性。例如,小的联系方式没有任何问题。但是,只要合适,就应该使用服务器端脚本。有数据库需求的大型网站肯定应该应用这些技术。此外,服务器端脚本可以提供相同的页眉、页脚等,作为整个 web 站点中相同标记片段的模板,可以很容易地从单个位置进行维护(与静态 web 页面相反)。但是,在不依赖于数据库和动态生成内容的网站上,应该尽量减少服务器端脚本的应用,例如小规模、小册子风格的网站。这是获得和确保完全符合标准的最直接的方法。毫无疑问,Web 上很大一部分无效标记代码是由服务器端脚本语言生成的。在许多情况下,需要额外的实践来获得有效的标记,例如处理在 PHP 会话的 URL[2]中用作参数分隔符的&字符。

客户端开发

客户端开发是指那些在客户端运行的 web 程序,一般是 web 浏览器,而不是在服务器端执行(在 web 服务器上)。根据用户输入和其他变量,客户端程序可用于在网页上提供不同的和不断变化的内容。例如,可以根据一天中的当前时间将“动态”问候添加到网页中。

Ajax

Ajax异步 JavaScript 和 XML 的缩写。它不是一种编程语言,而是一组相互关联的 web 开发技术,如 HTML、CSS、DOM、JavaScript、XML 和 XSLT。Ajax 可以在客户端创建交互式 web 应用。支持 Ajax 的网站应用可以异步地向服务器发送数据和从服务器检索数据(这就是该名称的由来)。Ajax 适合在异步交换数据时避免整页重载。这种方法确保了当前页面的显示和行为不会受到干扰。尽管名字如此,Ajax 并不需要 XMLJavaScript Object Notation (JSON),一种轻量级的基于文本的开放标准 [3 ],经常被用来代替。请求也不一定是异步的。Ajax 通常使用XMLHttpRequest对象 [4 ]来检索数据。DOM 和 JavaScript 一起用于动态显示信息,并允许用户与显示的信息进行交互。使用 Ajax 交换的数据可以使用 XSLT 操作。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 注意现代浏览器都有内置的XMLHttpRequest对象。在 IE7 之前,Internet Explorer 提供了一个名为ActiveXObject的对象。

为了演示 Ajax,清单 6-1 中的代码创建了一个链接,用文本文件的内容替换元素的内容。文档对象模型用于操作对象。对象用于让 HTTP 请求加载文件ajaxdemo.txt并显示其内容。

清单 6-1。 Ajax 演示

`

function replace() {
      http.open(“GET”, “ajaxdemo.txt”, true);
      http.onreadystatechange=function() {
        if (http.readyState == 4) {
          document.getElementById(‘repdiv’).innerHTML = http.responseText;
        }       }
      http.send(null);
    }
  `

在文档体中,我们需要一个函数调用和一个带有要替换文本的div(清单 6-2 )。

***清单 6-2。*函数调用和div原文

`


  Click here to replace text

  Original text in the markup
`

http.open()参数是在后台发送请求的异步参数。

弹性

Adobe Flex 是一个基于 Adobe Flash 技术 [5 ]的软件开发工具包(SDK),用于跨平台的富互联网应用。用户界面布局和行为由基于 XML 的声明性语言 MXML 描述,而客户端逻辑是使用 ActionScript 3.0 编程语言创建的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 注意 ActionScript 是一种面向对象的语言,是 ECMAScript 的一种方言。因此,ActionScript 是 JavaScript 语法和语义的超集。最常见的是,ActionScript 嵌入在 SWF 文件中。

例如,让我们创建一个简单的 RSS 新闻阅读器!首先,我们需要编写一个通用的 XML 声明,然后是一个 MXML 声明(清单 6-3 )。

***清单 6-3。*XML 和 MXML 宣言

`<?xml version="1.0" ?>
<mx:Application xmlns:mx=“http://www.macromedia.com/2003/mxml”>

</mx:Application>`

mx:Application中,应该定义我们的HTTPService,并为面板准备好自定义控件(DataGrid、TextArea 和 Button)(清单 6-4 )。

***清单 6-4。*自定义控件的HTTPService和面板

<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml">   <mx:HTTPService id="httpRSS" url="http://www.example.com/rss/" resultFormat="object" />   <mx:Panel id="reader" title="Simple RSS Reader" width="600">   </mx:Panel> </mx:Application>

现在是时候定义数据网格了。面板的水平尺寸应由width参数设定。RSS 文件的每个 item 标签都通过dataProvider属性绑定到一个 DataGrid 行。接下来,我们创建一个事件处理程序来显示用户选择的 RSS 条目中描述标签的内容。entries.selectedIndex变量用于确定哪个项目被点击了。通过httpRSS.result.rss.channel.item[entries.selectedIndex].description检索相应项目的描述。RSS 描述的值被分配给 TextArea 的htmlText属性(清单 6-5 )。

***清单 6-5。*为 RSS 阅读器创建数据网格

<mx:DataGrid id="entries" width="{reader.width-15}" ![images](https://gitee.com/OpenDocCN/vkdoc-html-css-zh/raw/master/docs/web-std-master-h5c3-xml/img/U001.jpg)  dataProvider="{httpRSS.result.rss.channel.item}" ![images](https://gitee.com/OpenDocCN/vkdoc-html-css-zh/raw/master/docs/web-std-master-h5c3-xml/img/U001.jpg)   cellPress= ![images](https://gitee.com/OpenDocCN/vkdoc-html-css-zh/raw/master/docs/web-std-master-h5c3-xml/img/U001.jpg)   "{body.htmlText=httpRSS.result.rss.channel.item[entries.selectedIndex].description}">   <mx:columns>     <mx:Array>       <mx:DataGridColumn columnName="title" headerText="Title" />       <mx:DataGridColumn columnName="pubDate" headerText="Date" />     </mx:Array>   </mx:columns> </mx:DataGrid>

最后,需要使用mx:TextArea标签创建一个 TextArea,需要使用click事件处理程序创建一个按钮来调用HTTPService对象上的send()方法(清单 6-6 )。

***清单 6-6。*文本区和按钮

<mx:TextArea id="body" editable="false" width="{reader.width-15}" height="400" /> <mx:Button label="Load RSS channel items" click="{httpRSS.send()}" />

html 5 API

HTML5 提供的不仅仅是新的结构化元素。HTML5 支持许多原本只能通过插件或复杂代码获得的特性 [6 ]。除了标记元素和属性,HTML5 还指定了脚本应用编程接口(API)7。本地绘图 API、本地套接字等消除了与插件相关的问题,例如缺少或禁用对漏洞问题的支持。

一些 HTML5 APIs 在 W3C 标准化下,而另一些在 WHATWG 开发下。下面几节将讨论一些最常用的 API。

html 5 画布 API

HTML5 中引入了canvas标记元素。它允许 2D 形状和位图图像的动态脚本化呈现。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 注意html 5 canvas 没有内置的场景图,这是一种通用的数据结构,用于安排图形场景的逻辑(通常是空间)表示。场景图通常由基于矢量的图形系统使用,包括 SVG。在 SVG 中,所有绘制的形状都作为一个对象存储在场景图或 DOM 中,然后呈现为位图图形。因此,如果 SVG 对象属性发生变化,浏览器可以自动重新渲染场景,这在画布上是不可能的。从这个角度来看,SVG 图形比 HTML5 画布上的形状更高级。

在清单 6-7 中,你可以看到如何在 HTML5 画布上画一个简单的三角形。首先,为不支持 HTML5 画布的旧浏览器声明一个带有替代文本内容的定制大小的画布。第二,一个script元素指定了两个变量来缩短代码,一个二维画布,一个祖母绿填充颜色,一个三角形的三个角的坐标,以及带有填充颜色的三角形。

***清单 6-7。*在 HTML5 画布上画画

`
  A triangle (requires HTML5 Canvas support)

`

IE9+、Firefox 3.0+、Chrome 1.0+、Safari 3.0+和 Opera 9.5+都支持 HTML5 画布。

html 5 文件和 DnD API

HTML5 文件 API 在 web 浏览器中提供了易于使用的文件控制。万维网联盟正在对文件 API 进行标准化。Drag & Drop (DnD) API 规范定义了一个基于事件的机制,该机制添加了额外的标记,用于声明可在网页上拖动的元素。网络超文本应用技术工作组 [9 ]正在开发 DnD API。

清单 6-8 中的代码创建了一个界面,通过浏览你计算机上的目录或使用拖放来选择文件。将使用 HTML5 文件 API 检索所选文件的名称、大小和 MIME 类型。

***清单 6-8。*文件 API 演示

`

Choose file(s)

` `  

  You can also drag and drop your files here

Retrieved file information

  •   
  • <no files uploaded yet>
`

前一个例子(<div id="drop">)中代表拖放区的分割应该使用边框或者背景色来使其可见(清单 6-9 )。

***清单 6-9。*上例的 CSS 规则集

#drop {   border: 2px dashed #f00;   padding: 10px; }

接下来,创建一个非常简单的拖放示例,其中包含五个单词,可以从一个部门拖到另一个部门,然后再拖回来。首先,声明div项,并用draggable属性使它们可拖动。然后,将它们放入一个容器div,并创建第二个div(目标)(清单 6-10 )。

***清单 6-10。*DnD 示例的标记

`


  

    

Drag the word “DnD” to the other box and back


  

  

  
My

  
dog

  
is

  
called

  
Bobby

  
`

在文档头中,声明一个script元素,并创建在以下情况发生时要调用的函数(清单 6-11 ):

  • 项目开始被拖动
  • 被拖移的项目位于另一个项目上方
  • 拖动完成
  • 被拖动的项目被放下

***清单 6-11。*处理拖拽的功能

<script>   function dragStarted(evt) {     evt.dataTransfer.effectAllowed = 'move';     evt.dataTransfer.setData("text/plain", evt.target.getAttribute('id'));     evt.dataTransfer.setDragImage(evt.target, 0, 0);   return true; } `function dragOver(evt) {
  evt.preventDefault();
}

function dragEnded(evt) {
  return true;
}

function dragDropped(evt) {
  var idDrag = evt.dataTransfer.getData(“Text”);
  evt.target.appendChild(document.getElementById(idDrag));
  evt.preventDefault();
}
`

最后,在文档头或外部文件中声明样式,包括框的布局和颜色(清单 6-12 )。

***清单 6-12。*盒子的样式

`body {
  width: 800px;
  margin: 100px auto;
}

#leftDiv, #rightDiv {
  float: left;
  width: 200px;
  height: 100px;
  margin: 50px;
  background-color: #bbdeee;
  border: 1px solid #000;
}

.word {
  width: 60px;
  height: 20px;
  margin: 5px;
  text-align: center;
  font-weight: bold;
  background-color: #ff6;
  display: inline-block;
  cursor: move;
}`

Firefox 3.6+和 Chrome 6.0+支持文件 API。Opera 11.5 支持文件 API,但不支持拖放 API。IE9 支持拖放 API,但不支持文件 API。Safari 从 4.0 版开始部分支持文件 API,在 6 版中将完全支持。

html 5 表单 API

HTML5 为input元素引入了新的属性(autocompleteautofocusformformactionformenctypeformmethodformnovalidateformtargetheightlistmaxminmultiplepatternplaceholderrequiredstepwidth),并为input元素的type属性引入了新的属性值(包括emailurl、】

例如,为一个网站的注册页面创建一个(X)HTML5 表单(清单 6-13 )。

***清单 6-13。*一张登记表

`
  
    


      
**      <input id=“mailadd” type=“email” required=“required” name=“mail”**
**       placeholder=“email@example.com” />**
    


    


      
      <input id=“passwd1” type=“password” required=“required” name=“pwd” />
    


    


      
      <input id=“passwd2” type=“password” required=“required” name=“pwd2” />
    


    


      
      
    


    


      
      
    


    


      
      
    


    


      
    


  

`
HTML5 地理定位 API

地理位置 API 提供了检索客户端设备的地理位置信息的接口。换句话说,可以在 web 浏览器中使用它来查找用户的当前位置。在用户确认请求之前,不会共享用户的位置。W3C [11 ]正在对地理定位 API 进行标准化。

清单 6-14 展示了地理定位 API 的应用示例。在示例中,setOnLoadCallback函数用于创建地图。if-then构造用于检查地理定位 API 是否受支持,获取当前位置,如果成功检索,则在地图上进行标记。如有必要,我们通知用户接受地理定位请求,否则无法确定位置。该位置被硬编码为澳大利亚阿德莱德的花园岛,直到用户启用地理定位为止。在else分支,为使用浏览器但没有地理定位支持的用户设置了一个好位置。

***清单 6-14。*检索用户的位置

`

`

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示此位置仅为近似值。在前面的例子中,我们得到一个标记,它不一定标记用户的确切位置。更复杂的界面,如 Firefox 的“位置感知浏览”测试页面,在地图上方提供了一个半透明的圆圈,而不是一个指向确切位置的标记。

iPhone 上运行的 IE9+、Firefox 3.5+、Chrome 5.0+、Opera 10.6+和 Safari 都支持 HTML5 地理位置 API。

html 5 网络存储 API

Web Storage 是一个 API,用于在浏览器(sessionStorage)中持久存储键值对数据(类似于 cookies),以及在会话之间保存的窗口本地存储(localStorage)。万维网联盟正在对网络存储 API 进行标准化。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

例如,为名称-值对的本地存储创建两个输入字段,以及一个按钮,让用户设置输入的条目(清单 6-15 )。在表中显示名称-值对。创建一个文本字段,用户可以在其中添加要在单击相关按钮后从存储的对中删除的项目。添加可用于清除存储项目的按钮。提供另一个文本字段,可以在其中键入项目名称以检索其值。因为表是由displayItems函数创建的,所以该函数应该由body元素上的onload属性作为<body onload="displayItems()">加载。

***清单 6-15。*一个localStorage例子

<form name="lsform">   <fieldset title="WebStorage">     <legend>Local storage of name-value pairs</legend>     <p> <label>Value:</label>       <input name="data">     </p>     <p>       <label>Name:</label>       <input name="name">     </p>     <p>       <input type="button" value="Set item" onclick="setTheItem()">     </p>     <table id="pairs"></table>     <p>       Enter name to remove item:       <input name="remove">       <input type="button" value="Remove item" onclick="removeTheItem()">       <input type="button" value="Clear items" onclick="clearItems()">     </p>     <p>       Enter name to retrieve value:       <input name="retrieve">       <input type="button" value="Get value" onclick="getTheItem()">     </p>     <script type="text/javascript">       function setTheItem() {         var name = document.forms.lsform.name.value;         var data = document.forms.lsform.data.value;         localStorage.setItem(name, data);         displayItems();       }       function getTheItem() {         var name = document.forms.lsform.retrieve.value;         window.alert('The value associated with the name ' + name + ' is ' + ![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=https%3A%2F%2Fgitee.com%2FOpenDocCN%2Fvkdoc-html-css-zh%2Fraw%2Fmaster%2Fdocs%2Fweb-std-master-h5c3-xml%2Fimg%2FU001.jpg&pos_id=img-vda71wAL-1724310614324)          localStorage.getItem(name));         displayItems();       }       function removeTheItem() {         var name = document.forms.lsform.remove.value;         document.forms.lsform.data.value = localStorage.removeItem(name);         displayItems();       }       function clearItems() {         localStorage.clear();         displayItems();       }       function displayItems() {         var key = "";         var pairs = "<tr><th>Name</th><th>Value</th></tr>\n";         var i = 0;         for (i = 0; i <= localStorage.length-1; i++) {           key = localStorage.key(i);           pairs += "<tr><td>" + key + "</td>\n<td>" + localStorage.getItem(key) + ![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=https%3A%2F%2Fgitee.com%2FOpenDocCN%2Fvkdoc-html-css-zh%2Fraw%2Fmaster%2Fdocs%2Fweb-std-master-h5c3-xml%2Fimg%2FU001.jpg&pos_id=img-2IZGl8rq-1724310614324)            "</td></tr>\n"; `        }
        if (pairs == “NameValue\n”) {
          pairs += “<not set>\n<not 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传            set>\n”;
        }
        document.getElementById(‘pairs’).innerHTML = pairs;
      }
    
  

`

IE 8+,Firefox 3.5+,Google Chrome 4+ ( sessionStorage从 5+开始),Safari 4+,Opera 10.50+都支持 Web 存储 API。

html 5 Web Workers API

Web Workers 是一个 API,可用于独立于任何用户界面脚本在后台执行脚本。因此,用户界面不会受到影响,所有浏览器任务都不会延迟执行。

Web Workers 中的“worker”是指存储在外部文件中的脚本,在后台加载并执行(清单 6-16 )。

***清单 6-16。*创造一个“工人”

new Worker("worker.js");

虽然复杂的 JavaScript 代码可能会使您的浏览器挂起(例如给出“无响应脚本”警告),但 Web Workers API 可以在浏览器执行事件处理、DOM 操作、查询和处理等任务时避免用户中断。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 注意由于 JavaScript 最初被设计为在单线程环境中运行——也就是说,多个脚本不能同时运行——所以 Web Workers 可以被认为是一个为 JavaScript 带来线程的 API。

在我们的示例中,我们创建了一个在后台从 0 数到 10,000 的“worker”。首先,在文档主体中需要两个按钮来开始和停止计数(两个具有唯一标识符的输入元素),并且需要一个带有标识符的段落(<p id="result">),结果将显示在该段落中(清单 6-17 )。

***清单 6-17。*Web Worker 示例的标记

`

Start/Stop the Worker

     

` `

The results

Click Start to start the Worker

`

我们还需要一个用于开始按钮的函数、一个错误事件处理程序和一个用于停止按钮的函数。实际执行计数的函数发生在一个外部.js文件中(清单 6-18 )。

清单 6-18。webworker.js文件

onmessage = function (evt) {   for (var i = evt.data, t = 10000; i < t; i++) {     postMessage(i);   }; };

IE10+、Firefox 3.5+、Chrome 5.0+、Safari 4.0+和 Opera 10.6+支持 Web Workers API。

html 5 web socket API

WebSocket API 可用于传输控制协议(TCP)套接字上的双向全双工通信。

万维网联盟正在对 WebSocket API 进行标准化。

在与 web 服务器建立 WebSocket 连接之后,可以使用onmessage事件处理程序从服务器检索数据,并通过send()方法将数据从客户端发送到服务器。

可以创建一个新的WebSocket对象,如清单 6-19 中的所示。

***清单 6-19。*一个新的WebSocket对象

var Socket = new WebSocket(http://example.com/ws/);

可选地,协议也可以在 URI 之后指定。

WebSocket 对象有两个只读属性:Socket.readyStateSocket.bufferedAmount。第一个代表连接状态(0为尚未连接,1为连接已建立,2为关闭握手,3为连接关闭或无法建立)。第二个属性给出了使用send()方法排队的字节数。

WebSocket API 支持四个事件:open(套接字连接建立)message(客户端从服务器接收数据)error(通信出错)close(连接关闭)。它们可以分别由Socket.onopenSocket.onmessageSocket.onerrorSocket.onclose事件处理程序来处理。

WebSocket 的两种方法分别是Socket.send()(send()方法通过连接传输数据)和Socket.close()(close()方法用于终止已有的连接)。

作为一个例子,我们在文档头中创建一个客户机和服务器之间的双向 TCP 套接字(清单 6-20 )。

***清单 6-20。*创建网络套接字

<script type="text/javascript">   function myWS() {     if ("WebSocket" in window) {       alert("WebSocket is supported by your Browser!");       var ws = new WebSocket("ws://localhost:9998/echo");       ws.onopen = function() {         ws.send("Message to send");         alert("Message sent…");       };       ws.onmessage = function (evt) {         var received_msg = evt.data;         alert("Message received…");       };       ws.onclose = function() {         alert("Connection closed…");       };     }     else {       alert("WebSocket is not supported by your browser!");     }   } </script>

在文档体中,应该调用myWS()函数来启动 WebSocket ( 清单 6-21 )。

***清单 6-21。*一个主播启动 WebSocket

`


  Start WebSocket

`

客户端程序现在已经准备好了,但是我们还需要一个支持 WebSocket 的服务器来测试它。比如 pywebsocket,可以作为 websocket 独立服务器,也可以作为 Apache HTTP 服务器的 WebSocket 扩展,适合测试 [15 ]。

HTTP 握手之后,TCP 套接字就可以使用了,连接是活动的;服务器和客户端都可以发送数据。

在客户端,WebSocket API 被 Firefox 4+,Google Chrome 4+,Safari 5+,Opera 11+所支持。

离线网络应用

HTML5 中的离线 web 应用功能允许在线应用不间断地工作,即使互联网连接不可用。例如,当用户找不到 Wi-Fi 热点时,可以在他们的网络邮件客户端撰写邮件。

由于浏览器在离线时无法访问网站文件,所以第一步是在一个名为offline.manifest ( 清单 6-22 )的文件中指定缓存所需的资源(一个简单的基本文件列表)。

***清单 6-22。*一个offline.manifest文件

CACHE MANIFEST index.html styles.css main.js

这个文件应该作为html元素上的manifest属性的属性值提供(清单 6-23 )。该文件应该使用 MIME 类型text/cache-manifest来提供。

***清单 6-23。*使用清单文件

<html manifest="offline.manifest">

将要求用户允许在其计算机上进行缓存。

JavaScript 使用navigator.onLine可以确定浏览器的在线/离线状态。

当浏览器离线时,可以使用前面讨论的 Web 存储 API 轻松地将数据存储在本地,也就是说,sessionStorage用于在会话期间检索数据,或者localStorage用于将值保留更长时间。

Firefox 3.5+、Chrome 1.0+、Safari 4.0+和 Opera 10.6+支持离线 web 应用。

Java 小程序

Java 是一种面向对象、结构化、命令式、跨平台的编程语言。Java 最初是由 Sun Microsystems 公司开发的,该公司现在归 Oracle 公司所有。Java 可以在客户端和服务器端的各种环境中使用,包括 applets、servlets、Swing 应用和 JavaServer Pages (JSP)。

Java 小程序是用于执行特定任务的小应用,在网站上以一种称为 Java 字节码的格式提供,可以由 Java 虚拟机(JVM)执行。尽管 Java 小程序可以被 Flash、Curl 或 Microsoft Silverlight 等替代技术所取代,但它们仍然存在于 Web 上。

一个 Java applet 应该由两个object元素和自结束参数提供。内物用三叉戟,外物用壁虎。清单 6-24 显示了一个例子。

清单 6-24。 Java 小程序嵌入有object

<object classid="java:bookflip.class"  type="application/x-java-applet"  archive="bookflip.jar"  height="120" width="120">   <param name="res" value="1" />   <param name="image1" value="01.jpg" />   <param name="link1" value="NO" />   <param name="flip1" value="0" />   <param name="image2" value="02.jpg" />   <param name="link2" value="NO" />   <param name="flip2" value="0" />   <param name="speed" value="4" />   <object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" height="120" width="120" >     <param name="code" value="bookflip" />     <param name="archive" value="bookflip.jar" />     <param name="res" value="1" />     <param name="image1" value="01.jpg" />     <param name="link1" value="NO" />     <param name="flip1" value="0" />     <param name="image2" value="02.jpg" />     <param name="link2" value="NO" />     <param name="flip2" value="0" />     <param name="speed" value="4" />   </object> </object>

每页只能呈现一次对象。正如你将看到的,Flash 对象也有类似的方法。

ECMAScript 和 JavaScript

一种广泛使用的脚本语言是 ECMAScript,它由 Ecma 国际(ECMA-262 [16 ]、ECMA-290 [17 ]、ECMA-327 [18 ]、ECMA-357 [19 ])和国际标准化组织(ISO/IEC 16262 [20 )进行标准化。ECMAScript 的互联网媒体类型为application/ecmascript,文件扩展名为.es

ECMAScript 的三种最著名的方言是 JavaScript、JScript 和 ActionScript。第一个是 JavaScript,它是 Web 上主要的客户端脚本语言。数以百万计的网站使用它来增加互动和功能。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 注意 JavaScript 不要和 Java 混淆。虽然两种语言都有类似 C 的语法,但是 JavaScript 是脚本语言,而 Java 是通用编程语言。JavaScript 有动态类型,Java 有静态类型。JavaScript 是弱类型语言,而 Java 是强类型语言。JavaScript 从人类可读的源代码中加载,而 Java 从编译后的字节码中检索。与基于原型的 JavaScript 对象不同,Java 对象是基于类的。

JScript 是 ECMAScript [21 ]的微软实现。JScript 的主要实现是 Windows Script 和 JScript .NET,JScript 的典型文件扩展名是.js.jse.wsf.wsc,如果嵌入的话还有.htm.html.asp

ActionScript 是一种面向对象的语言,最初由 Macromedia 开发,现归 Adobe Systems 所有。它是在 Adobe Flash 和前面提到的 Adobe Flex 中实现的。外部 ActionScript 文件的典型文件扩展名是.as。ActionScript 重用 ECMAScript 的 MIME 类型。

嵌入和加载 JavaScript

应用于整个网页的 JavaScript 代码通常在(X)HTML 头中声明。JavaScript 也可以在 web 文档的主体部分本地使用。在整个网站中使用的 JavaScript 代码是在外部文件中编写的。

一般来说,在网站上使用 JavaScript 有三种方式。下面几节将对它们进行讨论。

从外部文件加载 JavaScript

当同一个脚本应用于多个文档时,使用这种技术。外部 JavaScript 文件的文件扩展名为.js。这些文件的字符编码通常是 US-ASCII。用其他编码方案编码的 JavaScript 文件可能会有互操作性问题。虽然 UTF-8 是(X)HTML web 文档的最佳选择,并且可以作为默认字符编码应用于任何开发人员的文本编辑器中,但必须注意尽可能以 US-ASCII 编码 JavaScript 文件(类似于 CSS 文件)。

外部 JavaScript 文件应该只包含 JavaScript 代码(清单 6-25 )。脚本标签也必须避免(清单 6-26 )!

***清单 6-25。*标记中的 JavaScript 代码

**<script type="text/javascript">**   document.write("Nice coding"); **</script>**

***清单 6-26。*外部.js文件中的相同代码

document.write("Nice coding");

外部 JavaScript 文件可以用script元素上的src属性加载。 1 清单 6-27 显示了一个例子。

***清单 6-27。*从外部文件加载 JavaScript】

<script type="text/javascript" **src="scripts/click.js"**></script>

这种嵌入通常用于文档头中加载的脚本和任何太长而不能直接写入标记的脚本。替代样式选择器、字体大小调整器和隐藏层控制器脚本是这种方法的一些例子。


1 在 Web 的早期,language="javascript"属性-值对被用在script元素上,后来被弃用,取而代之的是type="text/javascript"

内联 JavaScript

JavaScript 也可以作为script元素的内容直接写在标记中。假设我们在文档头或外部.js文件中有清单 6-28 中所示的 JavaScript 函数和清单 6-29 中的变量。

***清单 6-28。*一个简短的 JavaScript 函数

function fourdigits(number) {   return (number < 1000) ? number + 1900 : number; }

***清单 6-29。*变数

var now = new Date(); var year = fourdigits(now.getYear());

该代码提供了当前年份,可用于“动态”版权内容,如清单 6-30 。

***清单 6-30。*内联 JavaScript 示例

Copyright © **<script type="text/javascript">document.write(year);</script>** John Smith

这是一个内联 JavaScript 代码。在这种情况下,它将表示版权符号和名称之间的当前年份,如清单 6-31 中的所示。

***清单 6-31。**列表 6-28 、 6-29 、 6-30 、*的结果

Copyright © 2011 John Smith

注意,如果 JavaScript 代码由于某种原因无法运行,文档的其他部分仍然会被呈现出来(清单 6-32 )。

***清单 6-32。*禁用 JavaScript 或不支持 JavaScript 的相同代码的结果

Copyright © John Smith

事件处理程序

JavaScript 通常用于根据用户交互(如用鼠标单击元素)来控制文档元素或浏览器窗口。

假设一个网页上有三个图像,当用户点击它们时,它们会修改层main的字体大小。清单 6-33 显示了一个可能的解决方案。

***清单 6-33。*操作字体大小的功能

function normal() {   var esize = document.getElementById('main').style;   esize.fontSize = "1.1em"; } `function larger() {
  var esize = document.getElementById(‘main’).style;
  esize.fontSize  = “1.4em”;
}

function huge() {
  var esize = document.getElementById(‘main’).style;
  esize.fontSize = “1.8em”;
}`

这三个函数既可以写在文档的script标签中,也可以写在外部文件font.js中。在后一种情况下,它们可以用script元素的src属性加载,如前面在清单 6-27 中所讨论的(文件路径和名称可以任意修改)。

现在可以用onclick属性加载适当的事件处理函数了(清单 6-34 )。

**清单 6-34。**当用户点击时加载适当函数的事件处理程序

<a href="#" **onclick="javascript:normal();"**>   <img src="img/normal.png" alt="Normal font" title="Normal" /> </a> <a href="#" **onclick="javascript:larger();"**>   <img src="img/larger.png" alt="Larger font" title="Larger" /> </a> <a href="#" **onclick="javascript:huge();"**>   <img src="img/huge.png" alt="Huge font" title="Huge" /> </a>

哪个功能将被运行取决于用户点击哪个图像链接。

确定 JavaScript 支持

JavaScript 支持可以很容易地由具有替代内容的脚本来确定,如清单 6-35 中的所示。

***清单 6-35。*带有替代内容的 JavaScript】

<script type="text/javascript">   document.write("If this text is displayed, your browser supports scripting, and ![images](https://gitee.com/OpenDocCN/vkdoc-html-css-zh/raw/master/docs/web-std-master-h5c3-xml/img/U001.jpg)    JavaScript is enabled!") </script> **<noscript>JavaScript is NOT enabled!</noscript>**

不支持 JavaScript 的浏览器会显示noscript元素的内容。

银光

Silverlight 是微软公司为开发富互联网应用而创建的免费应用框架。Silverlight 的运行时环境作为一个 web 浏览器插件提供。Silverlight 提供了许多类似于 Adobe Flash 的功能,例如动画、绘图对象、反射效果、字形等等。

Silverlight 使用可扩展应用标记语言(XAML ),而不是可缩放矢量图形(SVG)。XAML 是一种声明性的、基于 XML 的用户界面标记语言,由微软开发,在. NET 中广泛使用

与 Flash 类似,Silverlight 的一个常见嵌入选项是使用object标签(清单 6-36 )。

清单 6-36。 Silverlight 嵌入替代内容(确定支持)

<object id="SilverlightPlugin1" width="300" height="300" ![images](https://gitee.com/OpenDocCN/vkdoc-html-css-zh/raw/master/docs/web-std-master-h5c3-xml/img/U001.jpg)  data="data:application/x-silverlight-2," ![images](https://gitee.com/OpenDocCN/vkdoc-html-css-zh/raw/master/docs/web-std-master-h5c3-xml/img/U001.jpg)  type="application/x-silverlight-2" >   <param name="source" value="SilverlightApplication1.xap" />   <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=4.0.60310.0">     <img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="Get Silverlight" />   </a> </object>

Silverlight 不仅可以在您的文本编辑器中编写,还可以在 Microsoft Visual Studio 软件开发平台中编写,这使得创建与源代码同时显示的图形界面更加容易。

服务器端开发

虽然静态内容对于许多网站组件来说已经足够了,但是高级网站功能,如 web 应用、内容管理、在线银行、表单提交、数据库管理等等,都需要服务器端编程。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 客户端和服务器端编程的主要区别在于,客户端脚本由浏览器下载、解释和执行,而服务器端脚本和应用运行在服务器上。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示与客户端技术相反,客户端技术的支持要么嵌入在大多数浏览器中(例如 JavaScript),要么可以通过安装免费插件轻松设置(例如 SilverLight),而服务器端技术的支持应该由托管服务提供商提供。虽然大多数托管服务都支持 PHP 和 MySQL 等广泛采用的技术,但强烈建议您在选择服务和支付服务费用之前向提供商咨询特殊技术的支持,因为托管公司通常会拒绝安装任何不包含在其软件包中或不受其支持的软件组件(例如,FFMPEG、ionCube PHP Loader、Apache Ant、Ivy、JTA、JAXP)。有些技术依赖于其他技术,可能需要安装某些软件组件。

有各种各样的服务器端脚本和编程语言用于创建服务器端应用。下面几节描述了一些最广泛采用的方法。

cold fusion

ColdFusion 是 Adobe [23 ]提供的应用服务器,用于处理 ColdFusion 标记语言(CFML)。CFML 是一种脚本语言,使用与 HTML 结构相似的标签(这也是得名的原因)[24;它有一个类似于 PHP 的功能。除了 Adobe ColdFusion,CFML 还有几个实现,例如。NET 框架、Java 虚拟机和谷歌应用引擎。由于其可扩展性,ColdFusion 不仅是桌面环境的理想选择,也是日益流行的移动 web 应用的理想选择。

与 ColdFusion 竞争的最重要的技术是 BlueDragon [25 ]、Coral Web Builder [26 ]、IgniteFusion [27 ]、Railo [28 ]和 SmithProject [29 。

Java

在前面关于 Java 小程序的章节中已经提到了 Java 编程语言。不过服务器端也用 Java。

JavaServer Pages (JSP)是一种用于动态生成网页的 Java 技术。JSP 的语法结合了 scriptlet 元素和标记(通常是 HTML 或 XML) [30 。scriptlet 元素的内容是可能与标记混合在一起的 Java 代码。

Java 平台企业版(Java EE)是一个流行的 Java 服务器端编程平台。平台和相关的 API 在单独的规范 [31 、 32 中定义。

WebObjects 是由 Apple 开发的用于 Mac OS X 的 Java web 应用服务器和 web 应用框架。WebObjects 由苹果规范 [33 、 34 、 35 描述。

The。NET 框架

微软。NET 是一个流行的软件框架,拥有广泛的库 [36 ]。那个。NET 框架支持多种编程语言(C#、J#、VB。NET 等等)。这些语言中的任何一种都可以使用用其他语言编写的代码,这提供了高度的互操作性。框架架构的一个基础部分是名为公共语言运行时(CLR) 的应用虚拟机,它是微软对公共语言基础设施(CLI) 的实现。CLI 是 ECMA 标准(ECMA 335[37)。

的一些应用。NET 框架,如 ADO.NET、ASP.NET 和 Windows 窗体,不是前面提到的标准的一部分。

ASP.NET

Active Server Pages 通常被称为 ASP 或 ASP Classic,是由微软开发的用于创建交互式动态网页的 web 应用框架。它已经被 ASP.NET 取代,后者为网络应用和服务提供了强大的功能。典型的文件扩展名是 ASP 的.asp和 ASP.NET 文件的.aspx

正如你在清单 6-37 中看到的,通过用<%%>分隔脚本,一个 ASP 脚本可以嵌入到网页的文档体中。

清单 6-37。 ASP 脚本中的标记

`

        Simple ASP embedding example` `               **<%**     **response.write("Hello, World!")**     **%>**    `

在 2011 年在 Visual Studio 和 ASP.NET 中引入 HTML5 支持之前,ASP.NET 在大多数情况下都会生成无错误的 XHTML 标记。然而,由于 ASP.NET 不修改静态文本和非服务器标记元素,最终的标记不一定符合 XHTML 1.0 Strict 标准。根据微软的说法,一些提供可选功能的标记控件,尤其是那些具有指定其客户端行为的目标属性的控件(AdRotatorBulletedListHyperLinkHyperLinkColumnImageMapMenuItemTreeNode),可能会导致标记代码不符合标准 [39 。

C#

一种流行的编程语言,常用于。NET 是 C#(读作见夏普),已经被 ECMA [40 和 ISO [41 , 42 标准化。C#是一种多参数编程语言,它是声明性的、泛型的、函数式的和命令式的,并且具有强类型。C#应用了面向对象(基于类)和面向组件的原则。

Perl 是一种高级的、解释的、通用的动态编程语言。该语言的规范可在 Perl.org 获得。在 20 世纪 90 年代后期,Perl 因为其解析能力而成为流行的 CGI 脚本语言。Perl 的核心语法总结在“Perl 风格指南”44 中。Perl 的一个令人印象深刻的文本处理特性是,如果有足够的内存,它可以处理任意长度的文本文件。

PHP

PHP:超文本预处理器是最流行的开源服务器端脚本语言之一。它是一种跨平台的通用语言,最初是为生成动态网页而设计的。这些年来,一些程序员试图引入 PHP 的“标准化”最佳实践例如, [45 、 46 、 47 、 48 ],但都没有获得官方地位。PHP 的主要规范由 PHP 小组 [49 ]维护,它被认为是该语言事实上的标准,因为没有正式的规范。

PHP 是 ASP.NET 等竞争对手的广泛使用的、免费的、高效的替代品。

嵌入和加载 PHP

虽然一些 PHP 代码嵌入在(X)HTML 文档中,并与标记元素混合在一起,但复杂的 PHP 应用是在外部文件中提供的。

PHP 中的标记

PHP 代码通常由<?php?>或者<script language="php"></script>分隔。不可移植的短标签<?<?=以及 ASP 风格的标签如<%<%=不应该被使用。PHP 解析器只解析分隔符内的代码。在 XML 文档中(XHTML 也是如此),第一种嵌入方法提供了格式良好的 XML 处理指令。因为它们不是文档中字符数据的一部分,所以标记和 PHP 代码的组合有可能在 PHP 解析之前在服务器上提供有效的标记。

在标记中嵌入 PHP 的最简单的例子是一个“Hello World”脚本,比如hello.php ( 清单 6-38 )。

***清单 6-38。*PHP 中的“Hello World”

`

        Hello World in PHP            **    <?php echo '

Hello World

'; ?>**    `

根据适当的服务器配置,PHP 代码应该被解析,清单 6-39 中的输出将被发送到浏览器。

***清单 6-39。*解析 PHP 后的输出

`

        Hello World in PHP                **

Hello World!

**    `

结果标记验证为 HTML5。注意,为了便于理解,省略了结构元件和附加内容。

外部文件中的 PHP

外部 PHP 文件的典型文件扩展名有.php.phtml.php5.phps。外部 PHP 文件通常在开始和结束分隔符之间包含 PHP 代码。换句话说,它们以<?php开始,以?>结束。然而,许多 PHP 文件,例如用于设置的文件,不一定有结束分隔符。

include命令可以用来将指定的外部 PHP 文件的内容插入到标记中(清单 6-40 )。

***清单 6-40。*嵌入 PHP 文件

<?php include("copyright.php"); ?>

外部 PHP 文件可能包含 PHP 代码、标记或两者的组合。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示通常的做法是收集常见的(经常重复的)网页内容的标记片段,例如菜单和法律信息,并从外部 PHP 文件中嵌入它们。这种方法消除了站点常见脚本需求的冗余。

Python

Python 是一种通用的高级编程语言 [50 ]。与其他动态语言类似,Python 也经常被用作脚本语言。Python 支持多种编程范式。虽然 Python 主要是面向对象的,但也涉及到函数式编程风格。该语言的功能可以通过第三方工具进行扩展;例如,Python 代码可以作为独立的可执行文件提供。Python 解释器可用于各种操作系统,这使得 Python 成为一种跨平台语言。

红宝石

Ruby 是一种通用的、动态的、反射式的面向对象编程语言。最常见的 Ruby 实现之一是名为 Ruby on Rails 的开源 web 应用框架。Ruby 的主要文档包括 Ruby 核心参考 [51 ]、Ruby 标准库参考 [52 ]、Ruby C API 参考 [53 ]以及关于 Rails 可搜索 API 的文档 [54 。

SSJS

尽管 JavaScript 主要用于客户端,但它也有服务器端的实现。服务器端 JavaScript (SSJS)于 1996 年首次在 Netscape Enterprise Server 2.0 和 Netscape LiveWire 中实现。SSJS 开发的通用规范由 CommonJS 社区提供。服务器端 JavaScript Google Group 致力于创建跨平台的 SSJS 标准 API[56]。

客户端和服务器端技术的结合

并非所有的编程环境都是纯粹的客户端或服务器端技术。例如, Google Web Toolkit 有用 Java 编写 JavaScript 前端应用的工具。使用开发工具和框架 Pyjamas ,可以用 Python 开发 Ajax 应用和富互联网应用。一个用于开发具有客户端功能和服务器端处理的富互联网应用的开源平台是 Tersus

数据库技术

很大一部分服务器端应用和服务依赖于存储在数据库中的数据。Web 上最常用的数据库之一是跨平台关系数据库管理系统 MySQL [57 ]。它被认为是事实上的 ?? 标准,也被世界上流量最大的网站所使用。虽然它非常受欢迎,但 Ruby 和 Python 等语言经常应用 MySQL 以外的数据库服务器。Web 上其他一些常用的数据库技术有 Apache Derby [58 ]、IBM DB2 [59 ]、Firebird [60 ]、Microsoft SQL Server[61]、Oracle [62 ]、PostgreSQL [63 ]、SQLite [64 ]和 Sybase

脚本的替代内容和回退机制

在网站标准化中,为脚本提供替代内容以及为不支持脚本的用户代理设计 web 文档是至关重要的。您可以通过使用noscript元素来提供替代内容。不执行脚本,只有当浏览器配置消除了脚本或者在极少数情况下不支持script元素中使用的脚本语言时,用户代理才会呈现noscript元素的内容。没有客户端脚本支持的浏览器必须呈现noscript元素的内容。

例如,如果动态创建的数据是由script元素提供的,那么如果不支持脚本,可以使用到资源的直接链接([清单 6-41 )。

***清单 6-41。*有用的候补内容

<noscript>   <p><a href="http://example.com/news/">Latest News</a></p> </noscript>

有一种做法是注释掉标记中编写的脚本,以消除不能处理script元素的浏览器呈现元素内容。高级渲染引擎认为应该执行注释中的脚本。如果使用外部脚本文件,这可以消除注释的需要。

正如你在本章前面学到的,当 JavaScript 不被支持时,一个正确嵌入的脚本不会破坏页面布局或内容流。尽管如此,这种方法通常不能提供与脚本相同的功能或行为(提供的信息应该是相似的)。替代内容或回退机制对于 JavaScript 代码的重要性可以通过“动态”菜单得到最好的证明,这种菜单不应该只依赖于 JavaScript,因为如果 JavaScript 被禁用或脚本无法加载,站点的功能将会丢失。

让我们假设你有一个特殊的帮助屏幕,包含在一个层中,默认情况下是隐藏的(清单 6-42 ),只有当用户点击菜单“帮助”时才显示。

***清单 6-42。*一帮div默认隐藏

#help {     display: none; }

由于帮助是使用 JavaScript 显示的(清单 6-43 ),如果 JavaScript 被禁用或不被支持,帮助将不可用。

***清单 6-43。*显示隐藏的div功能

function display_help() {   document.getElementById("help").style.display = 'block'; }

一个好的回退机制是提供一个传统的超链接——看起来与调用 JavaScript 代码的链接相同,该代码在页面上方显示特殊的帮助层——作为替代内容(清单 6-44 )。如果由于缺乏 JavaScript 支持而无法显示该层,该链接将打开另一个 web 文档,其中包含 Help div将提供的相同内容。虽然“帮助屏幕”和帮助文档的视觉外观不同,但内容是相同的。他们中的一个总是可用的。

***清单 6-44。*带有回退机制的高级菜单项

`