1.1 设计代码的结构
1.1.2 文档类型、DOCTYPE切换和浏览器模式
DTD (文档类型定义) 是一组机器可读的规则,它们定义XML或 (X)HTML的特定版本中允许有什么,不允许有什么。在解析网页时,浏览器将使用这些规则检查页面的有效性并且采取相应的措施。浏览器通过分析页面的 DOCTYPE 声明来了解要使用哪个 DTD,因此知道要使用 (X)HTML 的哪个版本。
DOCTYPE 声明是 (X)HTML 文档开头处的一行或两行代码,它描述使用哪个 DTD。在下面的示例中,要使用的 DTD 是 XHTML 1.0 Strict 的 DTD:
DOCTYPE 通常 (但不总是) 包含指定的 DTD 文件的 URL 。浏览器一般不读取这些文件,而是只识别常见的 DOCTYPE 声明。
DOCTYPE 声明除了对有效性检验很重要之外,浏览器还将它们用于另一个用途。
2.浏览器模式
当浏览器厂商开始创建与标准兼容的浏览器时,他们希望确保向后兼容性。为了实现这一点,他们创建了两种表现模式:标准模式和怪异模式 (quirks mode)。在标准模式中,浏览器根据规范表现页面;在怪异模式中,页面以一种比较宽松的向后兼容的方式显示。怪异模式通常模拟老式浏览器(比如 Microsoft IE 4 和 Netscape Navigator 4)的行为以防止老站点无法工作。
对于这两种模式之间的差异,最显著的例子涉及 Windows 上 IE 专有的框模型。在 IE6 出现时,在标准模式中使用正确的框模型,在怪异模式中使用老式的专有框模型。为了维持对 IE 5 和更低版本的向后兼容性,Opera 7 和更高版本也在怪异模式中使用有缺点的 IE 框模型。
表现方面的其他差异比较小,而且是与特定浏览器相关的,包括对于十六进制颜色值不需要 #号、假设CSS中没有指定单位的长度的单位是像素,以及在使用关键字时将字号增加一级。
Mozilla 和 Safari 还有第三种模式,称为 "几乎标准的模式 (almost standards mode)",除了在处理表格的方式方面有一些细微的差异之外,这种模式与标准模式相同。
3.DOCTYPE 切换
浏览器根据 DOCTYPE 是否存在以及使用的 DTD 来选择要使用的表现方法。如果 XHTML 文档包含形式完整 DOCTYPE ,那么它一般以标准模式表现。对于 HTML 4.01 文档,包含严格 DTD 的 DOCTYPE 常常导致页面以标准模式表现。包含过渡 DTD 和 URI 的 DOCTYPE 也导致页面以标准模式表现,但是有过渡 DTD 而没有 URI 会导致页面以怪异模式表现。DOCTYPE 不存在或形式不正确会导致 HTML 和 XHTML 文档以怪异模式表现。
根据 DOCTYPE 是否存在选择表现方法的效果被称为 DOCTYPE 切换 (DOCTYPE switching) 或 DOCTYPE 侦测 (DOCTYPE sniffing)。并非所有浏览器都采用这些规则,但是这些规则很好地说明了 DOCTYPE 切换的工作方式。Eric Meyer 深入研究了这个主题,并且制作了一张图表 (http://meyerweb.com/eric/dom/dtype/dtype-grid.html) 来说明不同的浏览器如何根据 DOCTYPE 声明选择表现方法。
DOCTYPE 切换是浏览器用来区分遗留文档和符合标准的文档的手段。无论是否编写了有效的CSS,如果选择了错误的DOCTYPE,那么页面就将以怪异模式表现,其表现就可能会有错误或不可预测。因此,一定要在站点的每个页面上包含形式完整的 DOCTYPE 声明,并且在使用 HTML 时选择严格的 DTD 。
许多 HTML 编辑器会自动添加 DOCTYPE 声明。如果创建 XHTML 文档,它们还可能在 DOCTYPE 声明前面添加 XML 声明:
XML 声明是 XML 文件使用的可选声明,它定义使用的 XML 版本和字符编码类型等设置。不幸的是,如果 DOCTYPE 声明不是页面上的第一个元素,那么 IE6 会自动切换到怪异模式。因此,除非要将页面用做 XML 文档,否则最好避免使用 XML 声明。
1.2 为样式找到目标
1.2.1 常用的选择器
伪类
有时候,希望根据文档结构之外的其他条件对元素应用样式,例如表单元素或链接的状态。这要使用伪类选择器来完成。
:link 和 :visited 称为链接伪类,只能应用于锚元素。:hover、:active 和 :focus 称为动态伪类,理论上可以应用于任何元素。不幸的是,只有少数现代浏览器(比如 Firefox) 支持这种功能。IE6 和更低版本只注意应用于锚链接的 :active 和 :hover 选择器,完全忽略 :focus 。
1.2.2 通用选择器
通用选择器可能是所有选择器中最强大却最少使用的。通用选择器的作用就像是通配符,它匹配所有可用元素。与其他语言中的通配符一样,通用选择器由一个星号表示。通用选择器一般用来对页面上的所有元素应用样式。例如,可以使用以下规则删除每个元素上默认的浏览器填充和空白边:
* {
padding: 0;
margin: 0;
}
在与其他选择器结合使用时,通用选择器可以用来对特定元素的所有后代应用样式,或者跳过一级后代。在本章稍后将看到这么做的实际效果。
1.2.4 层叠和特殊性
即使在不太复杂的样式表中,也可能有两个或更多规则寻找同一元素。CSS通过一个称为层叠(cascade)的过程处理这种冲突。层叠给每个规则分配一个重要度。作者的样式表被认为是最重要的,其次是用户的样式表,最后是浏览器或用户代理使用的默认样式表。
为了让用户有更多的控制能力,可以通过将任何规则指定为 !important 来提高它的重要度,让它优于任何规则,甚至优先于作者加上 !important 标志的规则。
因此,层叠采用以下重要度次序:
- 标为 !important 的用户样式。
- 标为 !important 的作者样式。
- 作者样式。
- 用户样式。
- 浏览器/用户代理应用的样式。
- 如果样式是行内样式,那么 a = 1 。
- b = ID 选择器的总数。
- c = 类、伪类和属性选择器的属性。
- d = 类型选择器和伪元素选择器的数量。
1.2.5 继承
1.3 规划、组织和维护样式表
1.3.1 对文档应用样式
将外部样式表附着到网页上有两种方法。可以链接它们,也可以导入它们:
导入规则需要放在样式表的最前面,否则它们可能工作不正常。因为先考虑导入的样式表,然后再考虑链接的样式表,所以一定要记住链接的样式表中的规则会覆盖导入的规则。
尽管从理论上说可以将样式表导入到本身也是被导入的样式表中,但是对这种链式结构或多层嵌套的支持不完善。因此,应该避免两层以上的嵌套导入。
现在使用 Netscape 4 的人已经非常少了,所以可能不需要太为这种浏览器操心。可以省去简单的链接样式表,直接导入样式。但是 Windows 的 IE 5/6 有一种奇怪的特性,它会影响只使用导入规则的页面。当装载受影响的页面时,在最终显示样式之前,页面暂时以无样式的形式显示。这个 bug 称为 "Flash of Unstyled Content" (简称为 FOUC) bug 。在文档头放一个 link 或 script 元素可以避免这个 bug ,所以即使不为支持 Netscape 4 操心,可能仍然需要链接基本的样式表,然后再从那里导入样式表。