精通CSS:高级Web标准解决方案(第2版)

yz2061983

贡献于2011-11-23

字数:24943 关键词: CSS 前端技术 方案

 前言 尽管CSS资源的数量越来越多,但是在CSS邮件列表上仍然总是看到有人问同样的问题:如何让设计居中?最好的圆角框技术是什么?如何创建三列布局? 如果你熟悉CSS设计社区,那么寻找解决方案时无非就是回想一下某篇文章或某种技术曾在哪个网站重点介绍过。但是,如果你是CSS的初学者,或者没有时间阅读所有博客,那么这些信息可能并不好找。 CSS有些方面(比如定位模型和特殊性)比较晦涩,即使是有经验的CSS开发人员也会遇到问题。这是因为大多数CSS开发人员都是靠自学的,他们从各种文章和别人的代码中学习经验,而没有全面理解CSS规范。这也不奇怪,因为CSS规范本身十分复杂,常常还自相矛盾,它的目标读者是浏览器厂商而不是网页开发人员。 此外,还得应付浏览器问题。浏览器的bug和不一致性是现代CSS开发人员面对的一个最大问题。不幸的是,许多bug都没有很好地记载,它们的修复方法基本上只是在开发人员之间口口相传。你知道自己必须以某种方式做某件事,否则在某种浏览器中就会出问题。但是,你记不住是在哪种浏览器中会出问题,也说不清为什么会出问题。 所以,我产生了写这么一本书的想法。这本书将最有用的CSS技术汇总在一起,集中介绍实际的浏览器问题,从而弥补人们欠缺的CSS知识。本书会帮助你加快学习CSS的进程,使你的编码技术很快达到CSS专家的水平。 读者对象 本书适合具有HTML和CSS基础知识的任何人 阅读。无论你是刚刚接触CSS设计,还是已经开发纯CSS站点好几年了,书中都有适合你的内容。如果你已经使用CSS一段时间了,但还没有达到专家级水平,那么你能够从本书获得最大的收益。本书为你提供了各种实用的建议和示例,可以帮助你精通现代CSS设计。 本书结构 本书前3章讨论基本的CSS概念和最佳实践,帮助你轻松地入门。你将学习如何建立代码结构和添加注释,了解CSS定位模型的细节以及浮动和清理的工作原理。你也许已经掌握了其中的许多内容,但是可能会发现自己有遗漏或理解不充分的地方。因此,前3章是不错的CSS入门材料,也可以帮助你重温已经知道的知识。 介绍了基本知识之后,后面5章讨论核心CSS技术,比如操纵图像、链接和列表、设计表单和数据表格,以及进行纯CSS布局。每一章都由浅入深,最后讨论比较复杂的示例。在这几章中,你将学习如何创建圆角框、带透明阴影的图像、标签页式导航条和交互式按钮。许多情况下,我会先展示传统技术,然后说明如何用CSS制作出同样的效果。如果你想研究本书中的示例,可以从www.cssmastery.com或www.friendsofed.com下载所有示例代码 。 浏览器bug是许多CSS开发人员最头疼的问题,所以本书中的所有示例都着眼于创建跨浏览器的技术。此外,本书还用一整章讨论bug和bug修复。在这一章中,你将全面学习bug捕捉技术,学会在bug作乱之前就发现并消灭它,甚至还会学习是什么造成了IE中许多看似毫无规律的CSS bug。 最后两章是真正的"大餐"。Simon Collison和Cameron Moll是两位最杰出的CSS设计人员,他们将本书讨论的各种技术组合成两个精彩的实例来研究。从而,你不但会学习这些技术的工作原理,而且会看到如何将它们用在实际项目中。 本书可以从头到尾地阅读,也可以放在计算机旁边作为参考资料,随时查阅提示、技巧和技术,决定权在你。 本书约定 本书使用了几个约定,需要注意。本书采用了以下术语。 "HTML"指HTML和XHTML这两种语言。 除非特别声明,"CSS"是指CSS 2.1规范。 "Windows的IE 6和更低版本"指Windows的IE 5.0~6.0。 "现代浏览器"是指最新版的Firefox、Safari、Opera、IE 7以及IE 7以上版本。 本书中的所有HTML示例都应该嵌套在一个有效文档的中,同时,CSS包含在外部样式表中。偶尔为了尽量简短,HTML和CSS放在了同一个代码示例中。但是在真实的文档中,这些代码需要放在各自的位置上才能正常工作。 最后,对于包含重复数据的HTML示例,我们不会列出每一行,而是适时地使用省略号表示部分代码。 目录 第1章 基础知识 7 4.6 小结 82 1.1 设计代码的结构 7 第5章 对链接应用样式 83 1.1.1 标记简史 8 5.1 简单的链接样式 83 1.1.2 文档类型、DOCTYPE切换和 5.2 让下划线更有趣 85 浏览器模式 18 5.2.1 简单的链接修饰 85 1.1.3 有效性验证 19 5.2.2 奇特的链接下划线 86 1.2 小结 21 5.3 已访问链接的样式 87 第2章 为样式找到应用目标 22 5.4 为链接目标设置样式 87 2.1 常用的选择器 22 5.5 突出显示不同类型的链接 88 2.2 通用选择器 24 5.6 创建类似按钮的链接 91 2.3 高级选择器 24 5.6.1 简单的翻转 92 2.3.1 子选择器和相邻同胞选择器 24 5.6.2 图像翻转 93 2.3.2 属性选择器 26 5.6.4 CSS精灵 95 2.3.3 层叠和特殊性 29 5.6.5 用CSS 3实现翻转 96 2.3.4 继承 33 5.7 纯CSS工具提示 98 2.4 规划、组织和维护样式表 34 5.8 小结 100 2.4.1 对文档应用样式 34 第6章对列表应用样式和创建导航条 101 2.4.2 样式指南 37 6.1 基本列表样式 101 2.5 小结 39 6.2 创建基本的垂直导航条 102 第3章 可视化格式模型 38 6.3 在导航条中突出显示当前页面 105 3.1 盒模型概述 38 6.4 创建简单的水平导航条 106 3.1.1 IE和盒模型 40 6.5 创建图形化导航条 108 3.1.2 外边距叠加 41 6.6 简化的"滑动门"标签页式导航 110 3.2 定位概述 43 6.7 Suckerfish下拉菜单 112 3.2.1 视觉格式化模型 43 6.8 CSS图像映射 114 3.2.2 相对定位 44 6.9 远距离翻转 124 3.2.3 绝对定位 45 6.10 对于定义列表的简短说明 130 3.2.4 浮动 47 6.11 小结 131 3.3 小结 53 第7章 对表单和数据表格应用样式 132 第4章 背景图像效果 54 7.1 对数据表格应用样式 132 4.1 背景图像基础 54 7.1.1 表格特有的元素 134 4.2 圆角框 57 7.1.2 数据表格标记 135 4.2.1 固定宽度的圆角框 57 7.1.3 对表格应用样式 136 4.2.2 山顶角 62 7.1.4 添加视觉样式 137 4.3 投影 67 7.2 简单的表单布局 139 4.3.1 简单的CSS投影 68 7.2.1 有用的表单元素 140 4.3.2 来自Clagnut的投影方法 70 7.2.3 其他元素 142 4.4 不透明度 73 7.2.4 修饰 144 4.5 图像替换 78 7.3 复杂的表单布局 145 4.5.1 FIR 79 7.3.1 可访问的数据输入元素 146 4.5.2 Phark 80 7.3.2 多列复选框 147 4.5.3 sIFR 80 7.3.3 表单反馈 150 7.4 小结 152 第10章 实例研究:Roma Italia 207 第8章 布局 153 10.1 关于这个实例研究 207 8.1 计划布局 153 10.2 基础 209 8.2 设置基本结构 156 10.2.1 着眼于HTML 5 210 8.3 基于浮动的布局 158 10.2.2 reset.css 211 8.3.1 两列的浮动布局 158 10.3 1080布局和网格 212 8.3.2 三列的浮动布局 161 10.4 高级CSS 2和CSS 3特性 215 8.4 固定宽度、流式和弹性布局 163 10.4.1 网站需要在每种浏览器中 8.4.1 流式布局 164 看起来完全一样吗 216 8.4.2 弹性布局 166 10.4.2 属性选择器 217 8.4.3 流式和弹性图像 168 10.4.3 box-shadow、RGBa 8.5 faux列 170 和text-overflow 218 8.6 高度相等的列 173 10.5 字体链接和更好的Web排版 221 8.7 CSS 3列 176 10.5.1 按以前的方式设置font-size 221 8.8 CSS框架与CSS系统 177 10.5.2 标点符号悬挂 222 8.9 小结 181 10.5.3 多栏文本布局 224 第9章 bug和修复bug 183 10.5.4 @font-face 225 9.1 捕捉bug 183 10.5.5 Cufón,向@font-face 9.2 捕捉bug的基本知识 189 发展的过渡手段 228 9.2.1 尽量在一开始就避免bug 190 10.6 用AJAX和jQuery增加交互性 230 9.2.2 隔离问题 190 10.6.1 AJAX 230 9.2.3 创建基本测试案例 191 10.6.2 jQuery 231 9.2.4 修复问题,而不是修复症状 191 10.6.3 使用AJAX和jQuery实现搜索 232 9.2.5 请求帮助 192 10.7 小结 234 9.3 拥有布局 192 第11章 实例研究:Climb the Mountains 235 9.3.1 什么是布局 192 11.1 关于这个实例研究 235 9.3.2 布局的效果 193 11.2 样式表的组织和约定 237 9.4 解决方法 195 11.2.1 screen.css 238 9.4.1 IE条件注释 195 11.2.2 reset 239 9.4.2 关于hack和过滤器的一个 11.2.3 使用条件注释的IE样式表 239 警告 196 11.3 网格灵活性 240 9.4.3 明智地使用hack和过滤器 197 11.4 用body类控制导航 241 9.4.4 应用IE for Mac带通过滤器 197 11.4.1 突出显示当前页面 241 9.4.5 应用星号HTML hack 198 11.4.2 控制blockquote所处 9.4.6 应用子选择器hack 199 的层 244 9.5 常见bug及其修复方法 199 11.5 战略性地选择元素 245 9.5.1 双外边距浮动bug 199 11.5.1 深层后代选择器 245 9.5.2 3像素文本偏移bug 200 11.5.2 :first-child伪类 248 9.5.3 IE 6的重复字符bug 201 11.5.3 相邻同胞选择器 249 9.5.4 IE 6的"藏猫猫"bug 202 11.6 透明度、阴影和圆角 250 9.5.5 相对容器中的绝对定位 203 11.6.1 我们的目标 251 9.5.6 停止对IE的批评 204 11.6.2 说明图像覆盖和RGBa透明度 252 9.6 分级浏览器支持 204 11.6.3 组合类 254 9.7 小结 206 11.6.4 border-radius 255 11.6.5 box-shadow 256 11.7.2 主海拔图 260 11.7 定位列表和显示内容 257 11.8 小结 266 11.7.1 圆角 259 序 在网页设计的精彩世界里,实现同一个目标有千百种方法,而且新的方法还在不断地出现。对于特定的问题没有唯一正确的解决方法,丰富的选择使我们这些网页设计人员受益良多,同时也困扰着我们。这些选择虽然能使网页设计变得生动有趣,但同时也会令人无所适从。本书将帮助你减少麻烦,理清头绪。 Andy Budd多年来一直在编写、设计和宣讲基于标准的网页设计,我们现在有幸在本书中亲眼目睹他以简洁清晰的方式讲授最重要的CSS技术。本书提供了一套网页设计人员不可或缺的解决方案、技巧和建议。 有些图书中仅仅提出一种实现某一目标的正确方法,我很不喜欢这样的做法,Andy所做的正好相反,他为各种任务提供了多种方法,如对链接应用样式,创建标签页式导航,使用节省时间的CSS 3解决方案,或创建固定、流式的、灵活的布局,这些都有多种途径加以实现,书中还针对如何消除使用CSS设计时出现的那些恼人的浏览器bug给出了许多提示。掌握了常见设计元素的这些时髦漂亮的设计方法,你就可以做出更明智的选择。 不只如此,Andy还邀请两位出色的设计人员将这些技术组合在一起,通过两个实例研究向我们展示这些基本技术如何组合在一起。长期以来,我一直推崇Cameron和Simon的作品,看了他们写的两个绝佳实例,讨论流式布局、无懈可击的布局和灵活多样的样式解决方案,真的是受益匪浅。 好了,现在请开始深入研究并逐步消化这千百种设计方法,祝你早日成为精通CSS的高手。 Dan Cederholm,经典著作Web Standards Solutions 一书的作者 第1章 基础知识 人类天生就是一种好奇的动物,我们都很喜欢摆弄新鲜玩意儿。这不,最近我买了一台新的iMac,还没看说明书呢,自己就先把它鼓捣了一番。我们喜欢自己去琢磨,对新东西形成自己的看法。我们会自己先胡乱摸索一阵子,发觉不对劲了,才会去查阅手册。 学习CSS(层叠样式表)最好的一种方式是直接开始使用它。实际上,我认为大多数人学习Web编程的过程都是这样:先从博客上看到了一些出色的效果,于是通过查看源代码研究它们是如何实现的,然后就在自己的个人网站上大胆尝试。人们几乎不会先去读完整的CSS规范,这些规范能把任何人送入梦乡。 修改别人的代码是很好的起步方法,但是如果不小心的话,就可能误解重要的概念,或者给日后造成问题。这一点我很清楚,因为我犯过好几次了。本章将讲解一些基本的但常常被误解的概念,并讨论如何让HTML和CSS保持清晰且结构良好。 在本章中,你将学习以下内容: 设计代码的结构; 有意义的文档的重要性; 命名约定; 什么时候使用ID和类名; 微格式; HTML和CSS的不同版本; 文档类型、DOCTYPE切换和浏览器模式。 1.1 设计代码的结构 大多数人不关心建筑物的地基。但是,如果没有坚固的地基,建筑物的主体也就不会存在了。虽然本书讨论的是高级的CSS技术,但是如果没有结构良好且有效的HTML文档,那么我们要做的许多事情都是不可能实现的(至少实现起来非常困难)。 在本节中,你将明白为什么结构良好且有意义的HTML文档在基于标准的CSS开发中非常重要,还将学习如何丰富文档的意义,从而让自己的开发工作更轻松。 1.1.1 标记简史 早期的Web仅仅是一系列相互链接的研究文档,使用HTML添加基本的格式和结构。但是,随着万维网的流行,HTML开始用来表现页面。人们结合使用字体和粗体标签来创建所需的视觉效果,而不只是用标题元素突出显示页面的标题。表格成了一种布局工具而不是显示数据的方式,人们使用块引用(blockquote)来添加空白而不是表示引用。Web很快就含义不清,成了字体和表格标签的大杂烩。Web设计者把这样的标记称为"标签汤"(见图1-1)。 (图1-1) 网页变得越来越具表现力,代码却变得越来越难以理解和维护了。WYSIWYG(所见即所得)编辑器让设计者可以摆脱这些复杂性,它宣称可以提供全新的图形布局环境。遗憾的是,这些工具并没有使事情简化,反而添加了它们自己的复杂标记。使用FrontPage或Dreamweaver等编辑器能够通过简单的鼠标操作构建复杂的表格布局,但是嵌套的表格和"分隔线GIF"把代码弄得非常混乱(见图1-2)。更糟糕的是,这些布局极其脆弱,很容易被破坏。因为标记中有许多无意义的代码,很容易意外删除错误的标签,整个布局就可能会崩溃。另外,由于代码的复杂性,要找到bug几乎是不可能的,这时从头编写页面往往比寻找bug更容易。如果是大型网站,情况会更复杂。因为网站的表现锁定到了各个页面,所以即使是最小的全站修改,也必须进行细致的"搜索并替换"。我曾经由于轻率地执行"搜索并替换",导致弄坏了不止一个网站。因此,页面模板很快就不同步了,即使是简单的修改,也需要手工编辑网站上的每个页面。 表格本来不适合用来实现布局,所以David Siegel发明了一种聪明的解决方法。为了避免表格水平或垂直收缩,Siegel建议使用1像素的透明GIF。把这些隐藏的图像放在它们自己的表格单元格中,然后垂直或水平伸缩它们,这样就可以人为地控制单元格的最小宽度,从而保护布局不被破坏。这种图像也称为"shim GIF",因为Dreamweaver中使用这个文件名。在基于表格的老式布局中常常会看到这种图像。好在这种做法已经过时了,现在代码中通常没有这些混乱的表现性元素。 HTML并没有被看做简单的标记语言,反而得到了复杂、混乱和容易出错的坏名声。因此,许多人害怕直接编写代码,这导致人们过分依赖于可视化编辑器,造成整整一代设计者不知道如何编写代码。 千禧年之际,Web设计业简直是一团糟,必须采取措施了。 (图1-2) 就在这种背景下,CSS出现了。有了CSS,就可以控制页面的外观,并且将文档的表现部分与内容分隔开。现在,只需在一个地方进行站点修改,修改就会贯彻到整个系统。可以去掉表现标签(比如字体标签),而且可以使用CSS而不是表格来控制布局。标记返朴归真,人们又开始对底层代码感兴趣了。 文档又有意义了。浏览器的默认样式可以被覆盖,所以可以将某些内容标为标题,而不需要为它指定大号的、加粗的、难看的字体。可以创建列表,而这些列表不一定要用一系列项目符号来表示,可以使用没有关联样式的块引用。开发人员开始按照HTML元素的原义使用它们,无需管它们的外观(见图1-3)。 (图1-3) 1. 意义的重要性 有意义的标记为开发人员提供了几个重要的好处。与表现性的页面相比,有意义的页面更容易处理。例如,假设需要修改页面中的一个引用,如果这个引用加上了正确的标记,那么很容易搜索代码,找到第一个块引用元素。但是,如果这个引用只是另一个段落元素标签,就很难寻找了。再举一个更复杂但不太现实的例子,假设你需要在主页中添加一栏,只需把新内容放在右边,然后在CSS中更新宽度。要想在基于表格的布局中完成相同的任务,就需要在表格中添加一列,修改colspan设置,修改所有单元格的宽度,修改所有shim GIF的宽度。实际上,为了完成这个简单的修改,必须修改整个页面结构。 除了人之外,程序和其他设备也可以理解有意义的标记(也称为语义标记)。例如,搜索引擎可以识别出标题(因为它被包围在h1标签中)并予以重视。屏幕阅读器的用户可以依靠标题进行页面导航。 对于本书来说,更重要的是,有意义的标记可以简便地将元素调整为你所需的样式。它在文档中添加结构并且创建一个底层框架。可以直接设置元素的样式,而不需要添加其他标识符,因此避免了不必要的代码膨胀。 HTML包含丰富的有意义元素,比如: h1、h2等; ul、ol和dl; strong和em; blockquote和cite; abbr、acronym和code; fieldset、legend和label; caption、thead、tbody和tfoot。 因此,如果元素有恰当的含义,就应该使用。 几年来,在博客、邮件列表和开发人员论坛上,对于使用CSS还是表格有许多争论。出现这些争论常常是由于一部分开发人员习惯了基于表格的方法,他们不愿意学习新的技能。我可以理解他们的想法,因为基于CSS的布局最初看起来的确很难,尤其是当前的方法似乎仍然可行时,他们更不愿意接受新东西。但是,CSS的好处非常多,包括代码更少、下载更快和更容易维护等。大多数专业开发人员已经认识到Web标准的好处,而且大多数组织都不愿意按老方法做。因此,如果你仍然在使用基于表格的布局,会越来越难找到工作。好在这些老习惯正在被摒弃,新一代开发人员已经很难忍受麻烦的表格布局了。 2. ID和类名 有意义的元素会提供很好的基础,但是可用元素并不全面。HTML 4是作为简单的文档标记语言创建的,而不是界面语言。因此,没有用于内容区域或导航栏等的专用元素。虽然可以使用XML创建自己的元素,但是由于它太复杂,这在目前还不太现实。 HTML 5能为开发人员提供更丰富的元素,有望解决其中一部分问题。这包括header、nav、article、section和footer等结构性元素,以及data inputs和menu元素等新的UI特性。为了准备迎接HTML 5,许多开发人员已经开始采用这些名称作为ID和类名的命名约定。 次优的解决方案是使用现有的元素,并且通过添加ID或类名给它们赋予额外的意义。这会在文档中添加额外的结构,并给样式提供有用的"钩子"(hook)。因此,可以建立一个简单的链接列表,并且给它分配ID nav,从而创建出定制的导航元素: ID用于标识页面上的特定元素(比如站点导航),而且必须是唯一的。ID也可以用来标识持久的结构性元素,例如主导航或内容区域。ID还可以用来标识一次性元素,例如某个链接或表单元素。 一个ID名只能应用于页面上的一个元素,而同一个类名可以应用于页面上任意多个元素,因此类的功能强大得多。类非常适合标识内容的类型或其他相似的条目。例如,假设有一个新闻页面,其中包含多篇新闻,代码如下所示。 不必给每篇新闻分配不同的ID,可以给所有新闻分配一个类名news。 3. 为元素命名 在分配ID和类名时,一定要尽可能保持名称与表现方式无关。例如,如果希望所有表单通知消息显示为红色的,可以给它们分配类名red。只要页面上没有其他红色的元素,这就没问题。但是,如果还希望让4个必需的表单标签也显示为红色,就必须猜测这个类引用的是哪种元素,这时情况就开始有些混乱了。想象一下,如果在整个网站上到处使用表现性元素,代码会多么混乱。如果决定把表单通知由红色改为黄色,就更复杂了。在这种情况下,必须修改所有类名,否则名为red的元素就会显示为黄色。 因此,应该根据"它们是什么"来为元素命名,而不应该根据"它们的外观如何"来命名。这种方式会让代码更有意义,并且避免代码与设计不同步。对于前面的示例,不要给通知分配类名red,而是应该分配更有意义的名称,比如.warning或.notification(见图1-4)。有意义的类名的最大优点是可以在整个网站中重用它们。例如,还可以在其他类型的消息上使用.notification类,可以根据它们在文档中的位置应用完全不同的样式。 在写类名和ID名时,需要注意区分大小写,因为浏览器认为.andybudd和.andyBudd是不同的类名。处理这个问题最好的方式是使用统一的命名约定。为了容易辨认,我总是采用完全小写的类名和ID,多个单词之间用连字符分隔。例如,andy-budd比andyBudd清楚得多。 4. ID还是类 常常很难决定一个元素应该使用ID还是类名。一般原则是,类应该应用于概念上相似的元素,这些元素可以出现在同一页面上的多个位置,而ID应该应用于不同的唯一的元素。但是,究竟哪些元素是概念上相似的,哪些元素是唯一的? 例如,假设你的网站顶部包含主导航,在搜索结果页面的底部包含基于页面的导航,在页脚上还有另一个导航。是给它们分配不同的ID(比如main-nav、page-nav和footer-nav),还是都给它们指定nav类,然后根据它们在文档中的位置应用样式?我以前喜欢使用前一种方法,因为它的针对性更强一点儿。但是,这有几个问题。如果我现在需要把搜索结果导航放在搜索页面的顶部和底部,或者需要在页脚中有两级导航,那会怎么样? 如果使用大量ID,很快就会难以找到唯一的名称,最终不得不创建非常长、非常复杂的命名约定。因此,现在我比较喜欢使用类名。只有在目标元素非常独特,绝不会对网站上其他地方别的东西使用这个名称时,才会使用ID。换句话说,只有在绝对确定这个元素只会出现一次的情况下,才应该使用ID。如果你认为以后可能需要相似的元素,就使用类。保持命名约定通用,并且使用类,就不会出现一长串ID选择器都与非常相似的样式相关联的现象: 只需用一个普通的类替代它们: 由于类具有灵活性,所以它们是非常强大的。同时,它们也可能被过度使用或滥用。CSS新手常常在几乎所有东西上添加类,从而试图更精细地控制它们的样式。早期的WYSIWYG编辑器也倾向于在应用样式的每个地方都添加类。许多开发人员在使用编辑器生成的代码学习CSS时继承了这个坏习惯。这种现象称为"多类症"(classitis),在某种程度上,这和使用基于表格的布局一样糟糕,因为它在文档中添加了无意义的代码。 在前面的示例中,通过使用一个与新闻相关的类名,每个元素都被标识为新闻的一部分。这使新闻标题和正文可以采用与页面其他部分不同的样式。但是,不需要用这么多类来区分各个元素。可以将新闻条目放在一个部分中,并且加上类名news,从而标识整个新闻条目。然后,可以使用层叠(cascade)来识别新闻标题和文本。 只要你发现类名中出现了重复的单词,比如news-head和news-link或者section-head和section-foot,就应该考虑是否可以把这些元素分解成它们的组成部分。这会让代码更"组件化",会大大提高灵活性。 以这种方式删除不必要的类有助于简化代码,使页面更简洁。稍后,将简要讨论CSS选择器和为样式寻找目标。无论如何,这种对类名的过度依赖是完全不必要的。如果你发现自己添加了许多类,那么这很可能意味着你的HTML文档的结构有问题。 5. div和span 有助于在文档中添加结构的一个元素是div元素。许多人误以为div元素没有语义。但是,div实际上代表部分(division),它可以将文档分割为几个有意义的区域。所以,通过将主要内容区域包围在div中并分配content类,就可以在文档中添加结构和意义。 为了将不必要的标记减到最少,应该只在没有现有元素能够实现区域分割的情况下使用div元素。例如,如果使用主导航列表,就不需要将它包围在div中。 可以完全删除div,直接在列表上应用类: 过度使用div常常称为"多div症"(divitus),这是代码结构不合理而且过分复杂的一个信号。一些CSS新手会尝试用div重建自己原来的表格结构。但是,这只是用一套不必要的标签替换了另一套不必要的标签。实际上,应该使用div根据条目的意义或功能(而不是根据它们的表现方式或布局)对相关条目进行分组。 div可以用来对块级元素进行分组,而span可以用来对行内元素进行分组或标识: 尽管目标是让代码尽可能简洁且有意义,但是有时候为了以自己希望的方式显示页面,无法避免添加额外的无语义的div或span。如果是这样,那也不必过分为此担心。我们正处在一个过渡时期,CSS 3有望提供更强大的文档控制能力。而且,实际需要常常比理论出现得早。关键是知道在什么时候必须进行折中,并且要有正确的原因进行折中。 6. 微格式 由于HTML中缺少相应的元素,很难突出显示人、地点或日期等类型的信息。为了解决这个问题,有一组开发人员决定开发一套标准的命名约定和标记模式来表示这些数据。这些命名约定基于vCard和iCalendar等现有的数据格式,现在称为微格式(microformat)。下面以我的联系信息为例,代码采用hCard格式。 微格式让我们可以以一种特定的方式标记数据,让其他程序和服务可以访问它。一些人编写了脚本,可以提取出以hCalendar格式标记的事件信息,并把它直接导入日历应用程序(见图1-5和图1-6)。 (图 1-5) (图 1-6) 还有一些人编写了插件,让Firefox可以提取出以hCard格式标记的联系信息,并通过蓝牙发送到手机上(见图1-7和图1-8)。 (图1-7) (图1-8) 当前有9个正式的微格式,还有14个格式草案。包括: 用于日期、日历和事件的hCalendar 用于人和组织的hCard 用于人之间的关系的XFN 用于产品说明的hProduct(草案) 用于原料和烹调步骤的hRecipe(草案) 用于产品和事件审查的hReview(草案) 用于博客帖子等片段式内容的hAtom(草案) 许多大型网站已经支持微格式了。例如,Google Maps在地图搜索结果中使用hCard格式标记地址信息。类似地,Yahoo!的许多特性支持微格式,包括流行的Flickr照片共享网站。Yahoo!的Kelkoo购物搜索引擎中使用hListing格式,发布了2600万条使用微格式的信息。在网站上添加采用微格式的数据非常容易,所以我建议尽可能使用微格式。 这里只简要介绍了微格式可以实现的功能。如果需要了解更多信息,请阅读John Allsopp撰写的Microformats: Empowering Your Mark-up for Web 2.0,还可以在http://microformats.org查阅正式规范。 7. 不同的HTML和CSS版本 CSS有多个版本,所以知道要使用哪个版本是很重要的。CSS 1在1996年末成为推荐标准,其中包含非常基本的属性,比如字体、颜色、外边距。CSS 2在1998年发布,它添加了高级概念(比如浮动和定位)以及高级的选择器(比如子选择器、相邻同胞选择器和通用选择器)。 万维网联盟(W3C)的行动非常缓慢,所以尽管CSS 3的开发工作在新千年到来之前就开始了,但是距离最终的发布还有相当长的路要走。为提高开发和浏览器实现的速度,CSS 3被分割为多个模块,这些模块可以独立发布和实现。CSS 3包含一些令人兴奋的新特性,包括一个高级布局模块、全新的背景属性和一批新的选择器。其中一些模块原计划于2009年下半年发布。但是,目前还没什么进展,而且一些模块在发布前夕又回到了"最后公告"或"工作草案"状态,所以很难确定实际发布会多少个模块。希望到2011年会有许多模块成为正式的推荐标准。更让人担心的是,一些模块还没有开始开发,其他模块好几年没有更新了。如此缓慢的开发进度让人觉得CSS 3似乎不可能全部完成了。 不过,尽管有一些拖延,还是有许多浏览器厂商已经实现了CSS 3规范中比较有意思的一些特性。因此,目前已经可以使用许多新的选择器了。 因为预期从CSS 2到CSS 3的发布之间时间会很长,2002年启动了CSS 2.1的开发。这是CSS 2的修订版,它计划纠正一些错误,并且更精确地描述CSS的浏览器实现。CSS 2.1正在逐渐完成,因此我建议使用这个CSS版本。 HTML 4.01于1999年末成为推荐标准,这是大多数人目前使用的HTML版本。2000年1月,W3C发布了HTML 4.01的XML版并命名为XHTML 1.0。XHTML 1.0和HTML 4.01之间的主要差异是它遵守XML编码约定。这意味着与常规的HTML不同,所有XHTML属性必须包含引号,所有元素必须是封闭的。因此,以下代码在HTML中是合法的,而在XHTML中不合法: 在XHTML 1.0中,必须写成下面这样: XHTML 1.1比XHTML 1.0更接近XML。这两种语言之间没有实际的差异。但是,有一个重大的概念性差异。XHTML 1.0页面可以作为HTML文档,而XHTML 1.1页面是作为XML发送给浏览器的。这意味着,即使XHTML 1.1页面只包含一个错误(比如未编码的&符号),Web浏览器也不会显示页面。大多数网站开发人员显然不喜欢这样,所以XHTML 1.1不受欢迎。 是把XHTML 1.0页面作为HTML提供,还是应该坚持使用HTML 4.01?对于这个问题仍然有争论。但是,显然不应该使用XHTML 1.1,除非使用正确的mime类型,而且能够容忍一个错误导致整个页面无法显示。 HTML 5相对较新,是一个不断变动的规范草案。但是,它的发展势头很强,一些流行的浏览器已经开始着手支持它了。XHTML 2的开发非常缓慢而且过时了,让开发人员失去了信心。因此,一批开发人员决定开发自己的规范,由此催生出了HTML 5。这一行动非常成功,HTML 5已经成为正式的W3C项目,而XHTML 2的开发则停止了。 前面提到过,HTML 5的目标是建立一种现代的标记语言,可以更好地反映在Web上发布的信息类型。因此它引入了新的结构性元素,比如header、nav、article、sections和footer。它还包含一批新的表单特性,可以大大简化Web应用程序开发。 1.1.2 文档类型、DOCTYPE切换和浏览器模式 DTD(文档类型定义)是一组机器可读的规则,它们定义XML或HTML的特定版本中允许有什么,不允许有什么。在解析网页时,浏览器将使用这些规则检查页面的有效性并且采取相应的措施。浏览器通过分析页面的DOCTYPE声明来了解要使用哪个DTD,由此知道要使用HTML的哪个版本。 DOCTYPE声明是指HTML文档开头处的一行或两行代码,它描述使用哪个DTD。在下面的示例中,要使用的DTD是XHTML 1.0 Strict的DTD: DOCTYPE通常--但不总是--包含指定的DTD文件的URL。例如,HTML 5就不需要URL。浏览器一般不读取这些文件,而是只识别常见的DOCTYPE声明。 DOCTYPE当前有两种风格,严格(strict)和过渡(transitional)。顾名思义,过渡DOCTYPE的目的是帮助开发人员从老版本迁移到新版本。因此,HTML 4.01和XHTML 1.0的过渡版本仍然允许使用已经废弃的元素,比如font元素。但这些语言的严格版本禁止使用废弃的元素,从而把内容和表现分隔开。 1.1.3 有效性验证 除了根据语义加标记之外,HTML文档还需要用有效的代码来编写。如果代码是无效的,浏览器会尝试解释标记本身,有时候会产生错误的结果。更糟的是,如果发送具有正确的MIME类型的XHTML文档,理解XML的浏览器将不显示无效的页面。因为浏览器需要知道要使用什么DTD才能正确地处理页面,所以对页面进行有效性验证时要求有DOCTYPE声明。 可以使用W3C验证器(一个验证器bookmarklet)或Firefox Web Developer Extension等插件检查HTML是否是有效的。许多HTML编辑器现在内置了验证器,还可以在计算机上本地安装W3C验证器。验证器会指出页面是否是有效的,如果是无效的页面,它还会指出原因是什么(见图1-9)。 (图 1-9) 有效性验证很重要,因为它有助于找到代码中的bug。因此,尽早和经常进行有效性验证是个好习惯。但是,有效性验证太苛刻了,许多好页面由于很小的错误(比如&符号没有编码)或者因为遗留的内容而无法通过有效性验证。所以,尽管有效性验证很重要,但是在实际中,我们需要有一定的常识。 代码验证工具有很多种。可以访问http://validator.w3.org/并且输入自己的URL来对自己的站点进行在线验证。但是,如果要经常进行验证(这是个好习惯),那么每次都输入自己的URL有点儿麻烦。我使用的是一个方便的验证器bookmarklet(也称favelet),这是一小段可以存储在浏览器的书签或收藏夹中的JavaScript。单击这个书签就会触发JavaScript动作。对于验证器bookmarklet,它通过W3C验证器运行当前页面并显示结果。在http://favelets.com上可以找到这个验证器bookmarklet和其他许多方便的Web开发bookmarklet。 如果使用的浏览器是Firefox,那么可以下载和安装各种插件。在大量验证器插件中,我个人喜欢的是Web Developers Extension插件。除了可以验证HTML和CSS之外,它还可以执行许多其他任务,比如描述各种HTML元素、关闭样式表以及在浏览器中编辑样式。可以从http://chrispederick.com/work/firefox/web-developer/下载Firefox Web Developers Extension,这是使用Firefox的CSS开发人员必须具备的插件。另一个出色的工具是Firefox Validator Extension,可以从http://users.skynet.be/mgueury/mozilla/下载它。 还有一个用于IE 6和IE 7的开发人员工具栏,可以从http://tinyurl.com/7mnyh下载。尽管它的特性不如Firefox工具栏那么丰富,但是仍然非常有用。IE 8浏览器中直接构建了一套开发工具,Safari 4也是如此。 DOCTYPE声明除了对有效性验证很重要之外,还被浏览器用于另一个用途。 1. 浏览器模式 当浏览器厂商开始创建与标准兼容的浏览器时,他们希望确保向后兼容性。为了实现这一点,他们创建了两种呈现模式:标准模式和混杂模式(quirks mode)。在标准模式中,浏览器根据规范呈现页面;在混杂模式中,页面以一种比较宽松的向后兼容的方式显示。混杂模式通常模拟老式浏览器(比如Microsoft IE 4和Netscape Navigator 4)的行为以防止老站点无法工作。 对于这两种模式之间的差异,最显著的一个例子与Windows上IE专有的盒模型有关。在IE 6出现时,在标准模式中使用的是正确的盒模型,在混杂模式中使用的则是老式的专有盒模型。为了维持对IE 5和更低版本的向后兼容性,Opera 7和更高版本也在混杂模式中使用有缺点的IE盒模型。 呈现方面的其他差异比较小,而且是与特定浏览器相关的,包括对于十六进制颜色值不需要#号、假设CSS中没有指定单位的长度的单位是像素,以及在使用关键字时将字号增加一级。 Mozilla和Safari还有第三种模式,称为"几乎标准的模式(almost standards mode)",除了在处理表格的方式上有一些细微的差异之外,这种模式与标准模式相同。 在Firefox中,可以使用Web Developer Extension查看页面的呈现模式。如果网站以标准模式呈现,工具栏上会显示一个绿色的钩;若以混杂模式呈现,则显于红色的叉。IE 8中的开发工具也显示浏览器使用的模式。 2. DOCTYPE切换 浏览器根据DOCTYPE是否存在以及使用的哪种DTD来选择要使用的呈现方法。如果XHTML文档包含形式完整的DOCTYPE,那么它一般以标准模式呈现。对于HTML 4.01文档,包含严格DTD的DOCTYPE常常导致页面以标准模式呈现。包含过渡DTD和URI的DOCTYPE也导致页面以标准模式呈现,但是有过渡DTD而没有URI会导致页面以混杂模式呈现。DOCTYPE不存在或形式不正确会导致HTML和XHTML文档以混杂模式呈现。 根据DOCTYPE是否存在选择呈现模式,被称为DOCTYPE切换或DOCTYPE侦测。并非所有浏览器都采用这些规则,但是这些规则很好地说明了DOCTYPE切换的工作方式。要了解更全面的内容,可查阅网站http://hsivonen.iki.fi/doctype/,这里的图表说明了不同浏览器如何根据DOCTYPE声明来选择呈现方法。 DOCTYPE切换是浏览器用来区分遗留文档和符合标准的文档的手段。无论是否编写了有效的CSS,如果选择了错误的DOCTYPE,那么页面就将以混杂模式呈现,其行为就可能会有错误或不可预测。因此,一定要在站点的每个页面上包含形式完整的DOCTYPE声明,并且在使用HTML时选择严格的DTD。 许多HTML编辑器会自动添加DOCTYPE声明。如果创建XHTML文档,一些老的编辑器还可能在DOCTYPE声明前面添加XML声明: XML声明是XML文件使用的可选声明,它定义使用的XML版本和字符编码类型等设置。不幸的是,如果DOCTYPE声明不是页面上的第一个元素,那么IE 6会自动切换到混杂模式。这个问题在IE 7中已经纠正了,但是除非要将页面用做XML文档,否则最好避免使用XML声明。 1.2 小结 在本章中,你了解了语义性命名约定和有意义的标记如何让代码更容易阅读和维护,还了解了ID和类名之间的差异,以及各自适用的场合。我们还介绍了CSS和HTML可用的版本,以及浏览器决定如何处理这些差异的方式。 在下一章中,我们将回顾一些基本的CSS选择器,学习一些新的CSS 3选择器,还要学习特殊性和层叠,以及如何通过组织和计划样式表来简化维护。 第2章 为样式找到应用目标 有效且结构良好的文档为你要应用的样式提供了一个框架。要想使用CSS将样式应用于特定的HTML元素,需要想办法找到这个元素。在CSS中,执行这一任务的样式规则部分称为选择器(selector)。 在本章中,我们学习以下内容: 常用的选择器; 高级选择器; 新的CSS 3选择器; 特殊性和层叠的作用; 计划和维护样式表; 如何在代码中加注释。 2.1 常用的选择器 最常用的选择器类型是类型选择器和后代选择器。类型选择器用来寻找特定类型的元素,比如段落或标题元素,只需指定希望应用样式的元素的名称。类型选择器有时候也称为元素选择器或简单选择器。 后代选择器可用来寻找特定元素或元素组的后代。后代选择器由其他两个选择器之间的空格表示。在这个示例中,只缩进是块引用的后代的段落元素,其他所有段落不受影响。 这两种选择器适合于应用那些应用范围广的一般性样式。要想寻找更特定的元素,可以使用ID选择器和类选择器。顾名思义,这两种选择器用于寻找那些具有指定ID或类名的元素。ID选择器由一个#字符表示,类选择器由一个点号表示。下面示例中的第一条规则使简介段落中的文本以粗体显示,第二条规则让日期显示为绿色: 前面提到过,许多CSS开发人员过度依赖类选择器和ID选择器。如果他们希望以一种方式对主内容区域中的标题应用样式,而在第二个内容区域中采用另一种方式,那么他们很可能创建两个类并且在每个标题上应用一个类。一种简单得多的方法是结合使用类型、后代、ID和类这几种选择器: 这是一个非常简单明朗的示例。但是,让你吃惊的是,只使用前面讨论的4种选择器就可以成功地找到许多元素。如果你发现自己在文档中添加了许多不必要的类,那么这可能是文档结构不合理的一个警告信号。这时应该分析这些元素之间的差异。你常常会发现唯一的差异是它们在页面上出现的位置。不要给这些元素指定不同的类,而应将一个类或ID应用于它们的祖先,然后使用后代选择器定位它们。 伪类 有时候,我们需要根据文档结构之外的其他条件对元素应用样式,例如表单元素或链接的状态。这要使用伪类选择器来完成。 :link和:visited称为链接伪类,只能应用于锚元素。:hover、:active和:focus称为动态伪类,理论上可以应用于任何元素。大多数浏览器都支持这个功能。但是,IE 6只注意应用于锚链接的:active和:hover选择器,完全忽略:focus。IE 7在任何元素上都支持:hover,但是忽略:active和:focus。 最后,值得指出的是:通过把伪类连接在一起,可以创建更复杂的行为,比如在已访问链接和未访问链接上实现不同的鼠标悬停效果。 2.2 通用选择器 通用选择器可能是所有选择器中最强大却最少使用的。通用选择器的作用就像是通配符,它匹配所有可用元素。与其他语言中的通配符一样,通用选择器由一个星号表示。通用选择器一般用来对页面上的所有元素应用样式。例如,可以使用以下规则删除每个元素上默认的浏览器内边距和外边距: 在与其他选择器结合使用时,通用选择器可以用来对某个元素的所有后代应用样式,或者跳过一级后代。在本章稍后将看到这么做的实际效果 2.3 高级选择器 CSS 2.1和CSS 3有其他许多有用的选择器。不过,虽然大多数现代浏览器支持这些高级选择器,但是IE 6和更低版本不支持。好在在创建CSS时考虑到了向后兼容性。如果浏览器不理解某个选择器,那么它会忽略整个规则。因此,可以在现代浏览器中应用样式和易用性方面的改进,同时不必担心它在老式浏览器中造成问题。但是要记住,在对于站点功能或布局很重要的任何元素上,都应该避免使用这些高级选择器。 2.3.1 子选择器和相邻同胞选择器 第一个高级选择器是子选择器。后代选择器选择一个元素的所有后代,而子选择器只选择元素的直接后代,即子元素。在下面的示例中,外层列表中的列表项显示一个定制的图标,而嵌套列表中的列表项不受影响(见图2-1): 图2-1 子选择器指定列表的子 元素的样式,但是不影 响它的孙元素 IE 7和更高版本都支持子选择器。但是,在IE 7中有一个小bug,如果父元素和子元素之间有HTML注释,就会出问题。 在IE 6和更低版本中,可以使用通用选择器模拟子选择器的效果。为此,先在所有后代上应用你希望子元素具有的样式。然后,使用通用选择器覆盖子元素的后代上的样式。所以,要实现与前面的子选择器示例相同的效果,可以这样做: 有时,你可能需要根据一个元素与另一个元素的相邻关系对它应用样式。相邻同胞选择器可用于定位同一个父元素下某个元素之后的元素。可以使用相邻同胞选择器让顶级标题后面的第一个段落显示为粗体、灰色,并且字号比后续段落略微大一点儿(见图2-2)。 图2-2 可以使用相邻同胞选择器对标题后面的 第一个段落应用样式,这样就不需要使用多余的类 与子选择器一样,如果在目标元素之间有注释,这在IE 7中也会出问题。 2.3.2 属性选择器 顾名思义,属性选择器可以根据某个属性是否存在或属性的值来寻找元素,因此能够实现某些非常有意思和强大的效果。 例如,当鼠标悬停在具有title属性的元素上时,大多数浏览器会显示一个工具提示。可以使用这种特性解释某些内容(比如首字母缩拼词和缩写词)的含义: 但是,如果不把鼠标悬停在这个元素上,那么没有任何迹象能够表明存在这一额外信息。为了解决这个问题,可以使用属性选择器对具有title属性的acronym元素应用与其他元素不同的样式--在下面的示例中,在它们下面加上点。还可以在鼠标悬停在这个元素上时将鼠标指针改为问号,表示这个元素与众不同,从而提供更多的上下文相关信息。 除了根据某个属性是否存在对元素应用样式之外,还可以根据属性值应用样式。例如,使用rel属性值nofollow链接的站点无法从Google获得评级收益(ranking benefit)。以下规则在这种链接旁边显示一个图像,以此表示不推荐这个目标站点: 包括IE 7的现代浏览器都支持这些选择器。然而,由于IE 6不支持属性选择器,可以利用它们对IE 6应用一种样式,对更符合标准的浏览器应用另一种样式。例如,Andy Clarke利用这种技术为IE 6提供网站的黑白版本(见图2-3),为其他所有浏览器提供彩色版本(见图2-4)。 一些属性可以有多个值,值之间用空格分隔。属性选择器允许根据属性值之一寻找元素。例如,XFN微格式允许在锚链接的rel属性中添加关键字来定义你与站点的关系。假设某个站点属于我的同事,我就可以在博客上的链接中添加co-worker关键字来表示这一关系。然后可以在这位同事的姓名旁边显示一个特殊的图标,以此表明我和这个人一起工作。 图2-3 Andy Clarke使用属性选择器和其他技术 为IE 6提供网站的黑白版本 图2-4 更现代的浏览器显示的彩色版本 2.3.3 层叠和特殊性 即使在不太复杂的样式表中,要寻找同一元素可能有两个或更多规则。CSS通过一个称为层叠(cascade)的过程处理这种冲突。层叠给每个规则分配一个重要度。作者的样式表是由站点开发者编写的,被认为是最重要的样式表。用户可以通过浏览器应用自己的样式,这些样式表的重要度低一级。最后是浏览器或用户代理使用的默认样式表,它们的重要度是最低的,所以你总是可以覆盖它们。为了让用户有更多的控制能力,可以通过将任何规则指定为!important来提高它的重要度,让它优先于任何规则,甚至优先于作者加上!important标志的规则。这种设置能够满足特殊的可访问性需求,例如如果用户有某种读写障碍,可以使用中等对比度的用户样式表。 因此,层叠采用以下重要度次序。 标有!important的用户样式。 标有!important的作者样式。 作者样式。 用户样式。 浏览器/用户代理应用的样式。 然后,根据选择器的特殊性决定规则的次序。具有更特殊选择器的规则优先于具有一般选择器的规则。如果两个规则的特殊性相同,那么后定义的规则优先。 1. 特殊性 为了计算规则的特殊性,给每种选择器都分配一个数字值。然后,将规则的每个选择器的值加在一起,计算出规则的特殊性。可惜特殊性的计算不是以10为基数的,而是采用一个更高的未指定的基数。这能确保非常特殊的选择器(比如ID选择器)不会被大量一般选择器(比如类型选择器)所超越。但是,为了简化,如果在一个特定选择器中的选择器数量少于10个,那么可以以10为基数计算特殊性。 选择器的特殊性分成4个成分等级:a、b、c和d。 如果样式是行内样式,那么a = 1。 b等于ID选择器的总数。 c等于类、伪类和属性选择器的数量。 d等于类型选择器和伪元素选择器的数量。 使用这些规则可以计算任何CSS选择器的特殊性。表2-1给出了一系列选择器以及相应的特殊性。 表2-1 特殊性示例 初看上去,上面的特殊性和更高的未指定的基数可能有点儿让人糊涂,所以再解释一下。基本上,用style属性编写的规则总是比其他任何规则特殊。具有ID选择器的规则比没有ID选择器的规则特殊,具有类选择器的规则比只有类型选择器的规则特殊。最后,如果两个规则的特殊性相同,那么后定义的规则优先。 在修复bug时特殊性极其重要,因为你需要了解哪些规则优先及其原因。例如,假设有以下这组规则,你认为两个标题会是什么颜色的? 令人吃惊的是,两个标题都是灰色的。第一个选择器由两个ID选择器组成,因此它具有最高的特殊性。后面一些选择器看起来更复杂,但是因为它们只包含一个ID,所以特殊性总是低于第一个选择器。 如果你遇到了似乎没有起作用的CSS规则,很可能是出现了特殊性冲突。请在你的选择器中添加它的一个父元素的ID,从而提高它的特殊性。如果这能够解决问题,就说明样式表中其他地方很可能有更特殊的规则,它覆盖了你的规则。如果是这种情况,你可能需要检查代码,解决特殊性冲突,让代码尽可能简洁。 2. 在样式表中使用特殊性 在编写CSS时特殊性非常有用,因为它可以对一般元素应用一般样式,然后在更特殊的元素上覆盖它们。例如,如果你希望站点上大多数文本是黑色的,但介绍说明文本是灰色的。可以这样做: 对于小网站,这很好。但是,在大型站点上,你会发现例外情况越来越多。例如,你可能希望新闻文章上的介绍文本是蓝色的,而主页上的介绍文本使用灰色背景。每当创建更特殊的样式时,可能需要覆盖一些一般规则。这可能需要一些额外的代码。而且,因为元素可以从许多地方获得样式,情况可能变得非常复杂。 为了避免过分混乱,我尽量保持一般性样式非常一般,特殊样式尽可能特殊,这样就不需要覆盖特殊样式了。如果发现不得不多次覆盖一般样式,那么从更一般的规则中删除需要覆盖的声明,并且将它显式地应用于需要它的每个元素,这样可能比较简单。 3. 在主体标签上添加类或ID 一种有意思的特殊性用法是在主体(body)标签上应用类或ID。这样做之后,就可以根据页面或在站点范围内覆盖样式。例如,如果希望新的页面具有特殊的布局,那么可以在主页的主体元素上添加一个类名,并且使用它覆盖样式: 有时候,在特殊页面上需要覆盖这些样式,比如在新闻存档页面上。在这种情况下,可以在主体标签上添加ID来标识这个页面。 使用类标识页面类型,使用ID标识特定页面,就可以非常灵活地控制站点的设计和布局。我很喜欢使用这种方法编写可维护的代码。 2.3.4 继承 人们常常将继承和层叠混为一谈。尽管它们初看上去有点儿相似,但是这两个概念实际上是很不一样的。好在,继承是一个非常容易理解的概念。应用样式的元素的后代会继承样式的某些属性,比如颜色和字号。例如,如果将主体元素的文本颜色设置为黑色,那么主体元素的所有后代也显示黑色的文本。对于字号,也是这样的。如果将主体的字号设置为1.4 em,那么页面上的所有内容应该会继承这个字号。我说"应该会"是因为Windows的IE和Netscape在继承表格中的字号方面有问题。为了解决这个问题,必须指定表格应该继承字号,或者在表格上单独设置字号。 如果在主体上设置字号,你会注意到页面上的任何标题都没有采用这个样式。你可能会认为标题没有继承文本字号。但是,实际上是浏览器的默认样式表设置了标题字号。直接应用于元素的任何样式总会覆盖继承而来的样式。这是因为继承而来的样式的特殊性为空。 继承这一性质非常有用,因为它使开发人员不必在元素的每个后代上添加相同的样式。如果打算设置的属性是继承而来的属性,那么也可以将它应用于父元素。可以编写: 但是下面的写法更简单: 正如恰当地使用层叠可以简化CSS,恰当地使用继承也可以减少代码中选择器的数量和复杂性。但是,如果大量元素继承各种样式,那么判断样式的来源就会变得困难。在Firefox中可以使用Firebug查明样式的来源(图2-5)。 图2-5 Firebug是一个方便的Firefox附加组件,可以用它检查各个元素,查明它们的样式的来源 2.4 规划、组织和维护样式表 站点越大、越复杂,图形越丰富,CSS就越难管理。本节将讨论管理代码的方法,包括按逻辑对样式进行分组以及通过添加注释使代码更容易阅读。 2.4.1 对文档应用样式 可以将样式放在style标签之间,从而直接在文档头上添加样式,但是,这不是对文档应用样式的好方法。如果要创建使用相同样式的另一个页面,那么就不得不在新页面上复制CSS。如果以后要修改样式,那么就不得不在两处都进行修改。幸好CSS允许将所有样式放在一个或多个外部样式表中。将外部样式表附加到网页上有两种方法。可以链接它们,也可以导入它们: 除了导入到HTML文档之外,还可以从另一个样式表导入样式表。因此,你可以从HTML页面链接基本样式表,然后将复杂的样式表导入这个样式表: 把CSS分割为多个样式表是一种常见的做法,我在本书的第1版中也推荐过这种方法。但是,最近的浏览器基准测试已经表明,导入样式表比链接样式表慢。 在使用多个CSS文件时,还有两个与速度相关的问题。首先,多个文件会导致从服务器发送更多数据包,这些数据包的数量(而不是内容)会影响下载时间。另外,浏览器只能从同一个域同时下载数量有限的文件。对于老式的浏览器,这个限制常常只是两个文件,现代浏览器把这个限制提到了8个。因此,如果有3个样式表,那么在老式浏览器中必须等下载完前两个文件,才能开始下载第三个。由于这些原因,使用结构良好的单一CSS文件可以显著提高下载速度。 使用单一CSS文件还能够把代码集中在一个地方。为了便于维护,我过去建议分割代码。但是,总是很难判断某一声明是与站点的布局相关,还是与排版相关。它常常与两者都相关,最终你会随意选择安置它的位置。分割代码还意味着必须打开多个样式表,经常要在文件之间切换。最现代的CSS编辑器中内置了代码折叠等特性,所以现在编辑单一文件非常容易。由于这些原因,我现在倾向于使用单一CSS文件而不是多个小文件。当然,应该根据站点的实际情况做出决定,没有硬性规定。 在编写自己的样式表时,你可能很清楚它们的结构、曾经遇到的问题以及为什么采用某种方式。但是,如果6个月之后再来看这个样式表,你很可能已经忘了许多事情。另外,你可能需要将自己的CSS交给其他人去实现,或者其他开发人员以后需要编辑你的代码。因此,对代码进行注释是一种好做法。 在CSS中添加注释非常简单。CSS注释以/*开头,以*/结束。这种注释称为C风格的注释,因为C语言中使用这种注释。注释可以是单行的,也可以是多行的,而且可以出现在代码中的任何地方。 如果CSS文件非常长,那么寻找特定的样式会很困难。一种改进方法是在每个注释头中添加一个标志。这个标志仅仅是头文本前面的一个额外字符,一般不会出现在CSS文件中。搜索这个标志和注释头中的前几个字母,就可以立即找到要寻找的文件部分。所以,在下面的示例中,搜索"@group typ"就会立即找到样式表中的版式部分: OS X编辑器CSS Edit就可使用这种格式创建一种简单但有效的样式表导航方法。 1.设计代码的结构 为了便于维护,最好把样式表划分为几大块。显然,常常把最一般的规则放在最前面。这包括应用于body标记的、应该由站点上所有元素继承的样式。接下来是可能需要的所有全局reset样式,然后是链接、标题和其他元素。 完成一般样式之后,开始处理更特殊的样式和辅助样式。这些是在整个站点中使用的一般类,包括表单和错误消息等方面。然后,处理布局和导航等结构性元素。 随着在样式表中的移动,我们在一层样式上构建另一层样式,处理的样式越来越特殊。处理完页面结构元素之后,我们把注意力转到与特定页面相关的组件上。最后,在文档的底部处理覆盖和例外情况。整个文档的结构像下面这样: 一般性样式 主体样式 reset样式 链接 标题 其他元素 辅助样式 表单 通知和错误 一致的条目 页面结构 标题、页脚和导航 布局 其他页面结构元素 页面组件 各个页面 覆盖 这里使用一种风格统一的大注释块分隔每个部分。 并非所有东西都能够自然地分成定义明确的块,这需要开发人员进行判断。请记住,代码的分隔越细致、越合理,就越容易理解,而且能够更快地找到要寻找的规则。 因为我的许多CSS文件可能具有相似的结构,所以我可以创建一个预先加上注释的CSS模板供所有项目使用,从而节省时间。还可以添加在所有站点上都使用的常用规则,形成某种原型CSS文件,这可以节省更多的时间。这样的话,在开始新项目时就不必总是重复以前的工作。在本书的下载代码中可以找到一个原型CSS文件示例。 2. 自我提示 对于复杂的大型项目,在CSS文件中添加临时的注释常常对开发有帮助。这些注释可以提醒你在启动前需要完成哪些工作,或者提醒你提供列宽度等常用值的查询表。 例如,如果设计中使用了许多种颜色,你可能常常需要到图形应用程序中查询十六进制值,然后再返回到文本编辑器。这非常浪费时间,所以一些人认为需要CSS变量。尽管这是一个很有意思的主意,但是这会让CSS更接近真正的编程语言,可能让非程序员畏惧它。因此,我常常使用一种简单的方法。我在样式表的开头添加一个小的颜色查询表,这样就可以在开发期间经常参考它。完成开发之后,我通常会删除它。 为了使注释更有意义,可以使用关键字来区分重要的注释。我使用@todo来表示某些东西需要在以后进行修改、修复或复查,用@bugfix表示代码或特定浏览器遇到的问题,用@workaround表示并不完善的权宜之计: 用编程术语来说,这些关键字称为gotcha,它们在以后的开发阶段中非常有帮助。实际上,这些词汇都是CSSDoc项目(http://cssdoc.net)的一部分,这个项目的目的是为样式表开发一套标准的注释语法。 3. 删除注释和优化样式表 注释会使CSS文件显著加大。因此,你可能需要从样式表中去掉一些注释。许多HTML/CSS和文本编辑器都有"搜索并替换"选项,因此从代码中删除注释很容易。另外,还可以使用几种在线CSS优化器(比如www.cssoptimiser.com/上提供的优化器)。优化器不但能够删除注释,还可以删除空白,这可以从代码中去掉额外的字节。如果要从当前使用的样式表中删除注释,一定要保留带注释的版本。管理这个过程的最好方法是创建一个部署脚本,当你让修改的内容在生产环境中生效时,它自动地删除注释。但是,因为这是一种高级技术,可能只适用于很大的复杂站点。 减小文件大小的最好方法可能是启用服务器端压缩。如果使用Apache服务器,那么应该安装mod_gzip或mod_deflate。所有现代浏览器都可以处理用GZIP压缩的文件并进行即时解压。这些Apache模块探测浏览器是否能够处理这种文件,如果可以,就发送压缩的版本。服务器端压缩能够将HTML和CSS文件减小大约80%,这可以减少对带宽的占用,大大加快页面的下载速度。如果无法使用这些Apache模块,那么仍然可以按照http://tinyurl.com/8w9rp上的教程的说明对文件进行压缩。 2.4.2 样式指南 大多数Web站点有多个开发人员,而大型站点甚至有多个团队负责处理站点的不同方面。程序员、内容管理员和其他前端开发人员可能需要了解代码的元素和设计是如何工作的。因此,建立样式指南是一种非常好的做法。 样式指南可以是一个文档、网页或小型站点,它们解释代码和站点的视觉设计是如何组合在一起的。最基本的样式指南应该描述一般性设计原则,比如如何处理标题和其他排版元素,网格结构的设计方式是什么,以及使用哪个调色板。好的样式指南还应该描述文章、新闻条目和通知等重复元素的处理方法,决定它们应该如何实现和不应该如何实现。更详细的样式指南甚至可以包含编码标准,比如使用的XHTML/CSS版本、选择的可访问性级别、浏览器支持细节和一般的编码最佳实践(见图2-6)。 图2-6 样式指南示例 样式指南是帮助维护或实现站点的好方法。通过制定一些简单的原则,可以确保站点的开发以可控制的方式进行,同时防止样式随着时间的推移变得散乱。样式指南还非常有助于向新职员或承包商介绍他们不熟悉、可能很复杂的系统。 糟糕的是,及时更新样式指南需要花费大量精力,所以它们常常很快就与当前的站点不同步了。因此,我们更喜欢使用一种动态的样式指南形式,我们称之为"模式组合"(见图2-7)。 图2-7 WWF International站点的模式组合的一部分。实际 页面的长度大约是这里显示的5倍,包含这个站点上可能出现的每种排版和布局组合 模式组合是一个页面或一系列页面,它们使用当前的样式表显示站点上可能出现的每种样式排列组合,从标题级别和文本样式直到特定的内容和布局类型。这些页面为后端和前端开发人员提供极有价值的资源,让他们可以方便地构建页面组合。因为它们使用当前的样式表,所以也可以用它们进行回归测试,检查对CSS的修改是否导致了问题。 2.5 小结 在本章中,我们回顾了常用的CSS 2.1选择器,学习了一些新的CSS 3选择器;详细了解了特殊性的作用以及如何使用层叠控制CSS规则的结构,帮助规则找到目标;还学习了如何通过合理的注释和样式表结构提高可维护性。 在下一章中,我们将学习CSS盒模型,讨论如何实现外边距叠加及其原因,以及浮动和定位是如何工作的。

下载文档,方便阅读与编辑

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 20 金币 [ 分享文档获得金币 ]
3 人已下载

下载文档

相关文档