1.2 HTML文档剖析
有几个HTML元素是所有HTML文档(也就是网页)中都必须包含的。这些元素为内容提供了框架,有了这个框架才能正确显示内容。可以把这些必要的元素想象成一个模板页面里必须得有的元素。很多网页编写工具,比如Adobe Dreamweaver,会在每次创建新HTML页面时自动给你生成一个包含这些元素的模板页面。
HTML5标准推出之后,HTML文档的结构一下子得到了极大简化。就算你的Web开发经验不多,估计都会对之前HTML和XHTML复杂的文档类型(doctype),包括过渡型和严格型,以及那些元数据标签(
)记忆犹新。所有这些,在HTML5中都已经被更简单的语法取代,而且虽然语法简单但却能够与之前的HTML版本兼容。
1.2.1 HTML模板
今天,按照HTML5语法编写的最简单的HTML页面的模板可以写成这样:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>An HTML Template</title>
</head>
<body>
<!-- 这里是网页内容 -->
</body>
</html>
模板的第一行代码是一种新语法,或者说是一种简化的DOCTYPE
,这一行就是为了声明:“以下是一个HTML文档。”注意,这个标签不用关闭。
然后是标签,也就是所谓的根级标签,因为页面中所有的其他标签都嵌套在这个标签内部,而且它的闭标签也是整个页面中的最后一个闭标签。
标签只有两个直接的子标签:
和
。
使用HTML注释标签,可以为你自己或者其他将来可能会修改这个页面的人写一些备注。HTML注释以
开头,以
-->
结尾,注释内容就写在它们中间。浏览器在加载页面时,会忽略注释,不会显示其中的内容。
帮助浏览器理解页面的信息都包含在标签中。在这个最简单的例子里,
标签里只包含
和
两个标签。其中,
标签有一个
charset
属性,它是在告诉浏览器这个页面使用的是UTF-8编码。而 标签中的文本会在页面显示时,作为整个页面的标题出现在浏览器窗口顶部的标题栏中。上面模板中页面的标题是“An HTML Template”。
关于
标签
搜索引擎会给
标签中的文字内容赋予很高的权重。而且这些文字也会作为网页标题出现在搜索结果列表中。为此,千万不要让那些“欢迎光临我的网页!”之类的废话占据你的
标签。一定要让这些文字简洁明确,而且包含目标读者在搜索你的网页内容时会使用的关键词。
而标签则包含着标记所有内容的HTML元素。接下来,我们先把原来的注释替换成另外两个标签,然后再看看页面在浏览器中显示的效果。
在上面模板的标签中,我们再添加两个标签:
<body>
<h1>Stylin' with CSS</h1>
<p>Great Web pages start with great HTML markup!</p>
</body>
图1-2展示了当前页面在浏览器中显示的效果。
图1-2 带有一个标题和一个段落的示例模板页面
浏览器把包含内容的元素在页面中自上而下地一一排列,起点是页面的左上角。仔细看一看,会发现页面中标题和段落文本的字号不一样,但字体都是Times Roman,而且标题与段落之间还有一定的间距。很显然,浏览器已经为页面应用了一些基本的样式。这些初始(默认)的样式,来自浏览器内置的一个CSS样式表,它只会为每个HTML元素添加一些最基本,当然也谈不上美观的样式。
接下来再给模板添加两个比较常用的HTML元素,一个链接,一个图片。
<body>
<h1>Stylin' with CSS</h1>
<p>Great Web pages start with great HTML markup!</p>
<a href="http://www.stylinwithcss.com">My Books</a>
<img src="images/cisco.jpg" alt="My dog Cisco" />
</body>
图1-3展示了页面现在的效果。
图1-3 页面中目前包含着标题、段落、链接和图片
链接是使用标签创建的,该标签有一个必需的属性
href
(hyperlink reference,超链接引用),其中包含着链接指向的页面的URL。
前面我们也提到过
标签,而现在你终于看到它的效果了。在这个标签里,同样是给出图片所在位置的URL,要使用src
(source,来源)而不是href
属性。
有一点你可能注意到了:虽然标题和段落是上下堆叠在一起的,但链接和图片却是并排显示的。为什么会这样呢?因为标题和段落是块级元素,而链接和图片是行内元素。
1.2.2 块级元素和行内元素
图1-3展示了所谓“文档流”的效果,也就是HTML元素会按照它们各自在标记中出现的先后顺序,依次从页面上方“流向”下方。浏览器的样式表之所以提供这种流动式效果,就是为了让那些简单但却正确标记了HTML的内容,能够以朴素但却可用的方式显示出来。CSS的妙处就在于把这种实用主义的默认显示效果,转换成既有吸引力又直观的页面设计。
几乎所有HTML元素的display
属性值要么为block
,要么为inline
。最明显的一个例外是table
元素,它有自己特殊的display
属性值。块级元素(比如标题和段落)会相互堆叠在一起沿页面向下排列,每个元素分别占一行。而行内元素(比如链接和图片)则会相互并列,只有在空间不足以并列的情况下才会折到下一行显示。
无论你想了解哪个HTML元素,第一个要问的问题都应该是:它是块级元素,还是行内元素?知道了这一点之后,就可以在编写标记的时候,预想到某个元素在初始状态下是如何定位的,这样才能进一步想好将来怎么用CSS重新定位它。
使用块级元素和行内元素构建页面
这里是一个完全由标题和段落组成的页面。为了保证屏幕截图和代码清晰,我故意把段落都弄得非常短。页面的标记如下。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Block and Inline Elements</title>
</head>
<body>
<h1>Types of Guitars</h1>
<p>Guitars come in two main types: electric and acoustic.</p>
<h2>Acoustic Guitars</h2>
<p>Acoustic guitars have a large hollow body that projects the sound of the strings.</p>
<h3>Nylon String Acoustic Guitars</h3>
<p>Descendants of the gut-strung instruments of yore, nylon string guitars have a mellow tone.</p>
<h3>Steel String Acoustic Guitars</h3>
<p>Steel string guitars first appeared in country music and today most acoustic guitars have steel strings.</p>
<h2>Electric Guitars</h2>
<p>Electric guitars have a solid or hollow body with pickups that capture the string vibration so it can be amplified.</p>
<h3>Solid Body Electric Guitars</h3>
<p>Solid body electric guitars are commonly used in rock and country music.</p>
<h3>Hollow Body Electric Guitars</h3>
<p>Hollow body acoustic guitars are commonly used in blues and jazz.</p>
</body>
</html>
整个页面的内容只有标题和段落。为清晰起见,这里省略了本该有的
图1-4展示了以上代码在浏览器中显示的效果。
图1-4 由标题和段落构成的页面
在以上代码和屏幕截图中,可以看到三种级别的标题。浏览器为每一级标题分别应用了不同的字号,从而让页面内容的层次显得非常分明。由于标题和段落都是块级元素,所以每个元素各占一行。
还有,页面四周都添加了一定的边距,所以文本才不会碰到浏览器窗口。而且,段落中的行与行之间也有距离。好了,边距的话题回头我们再仔细聊,还是先给页面添几张图片吧。如图1-5所示,当然你已经知道了,图片是行内元素。
图1-5 为页面添加两个行内元素(吉他图片)
标记中的两个
标签虽然分别位于两行,但这并不影响图片在浏览器中显示时的效果。图片是行内元素,所以它们显示的时候就会并列出现在一行上。而且,标签之间的空白(包括制表、回车和空格)都会被浏览器忽略1。因此,为了让代码的版式布局一目了然,你可以随意在标签之间添加换行和空格。一般推荐的做法都是子标签相对于父标签要有一个缩进。
1 根据CSS标准,默认情况下,多个空白会被浏览器叠加为一个。——译者注
以下是图1-5中展示的那部分页面对应的代码,其中包含两张图片。图片是行内元素,所以两把吉它会并排显示。
<body>
<h1>Types of Guitars</h1>
<p>Guitars come in two main types: electric and acoustic</p>
<h2>Acoustic Guitars</h2>
<img src="images/acoustic_nylon.jpg" alt="nylon string acoustic guitar" />
<img src="images/acoustic_steel.jpg" alt="steel string acoustic guitar" />
<p>Acoustic guitars have a large hollow body that projects the sound of the strings.</p>
</body>
现在,为了进一步加深对块级元素和行内元素的理解,我们在这个页面上搞一次小试验。这次试验要用到我最喜欢的一个开发工具,那就是Web Developer扩展。它是Firefox的一个扩展,安装之后它会生成一个菜单,里面包括很多查看HTML、CSS和JavaScript的工具。
要安装Web Developer,在Firefox工具栏中选择“附加组件”,然后在“附件组件管理器”中搜索“Web Developer”。找到之后,点击“安装”。
图1-6 我在Web Developer工具条中选择了Outline菜单
在图1-6中,可以看到浏览器窗口顶部偏下的Web Developer工具条。这个工具条有很多功能,其中一个就是能让你更清晰地确定每个元素的位置,以及元素之间的嵌套关系。如图所示,我选择了Outline(轮廓)菜单中的Outline Block Level Elements(显示块级元素的轮廓)命令,这个命令可以显示页面中块级元素方盒子的轮廓。
图1-7 选择Outline Block Level Elements命令后,会显示块级元素盒子的实际大小以及相互之间的间距。没有显示行内元素的轮廓
显示块级元素的轮廓之后,通过图1-7就可以发现元素盒子比它们包含的文本要大一些。每个盒子的高度比内容稍微高一点,而宽度跟浏览器窗口一样宽!
块级元素盒子会扩展到与父元素同宽。
在我们这个页面中,所有块级元素的父元素都是body
,而它的宽度默认与浏览器窗口一样宽(当然有少量边距)。因此,所有块级元素就与浏览器窗口一样宽了。说到这,相信你就能理解为什么块级元素始终会占一行了。对了,就是因为它们始终会保持与浏览器窗口同宽。这样一来,一个块级元素旁边也就没有空间容纳另一个块级元素了。
通过Web Developer工具条不能像显示块级元素轮廓那样,同时显示所有行内元素的轮廓。不过,通过Outline菜单中的Outline Custom Elements(显示自定义元素的轮廓)命令可以显示这些元素的轮廓。行内元素盒子的行为与块级元素盒子的行为正好相反。
行内元素盒子会“收缩包裹”其内容,并且会尽可能包紧。
说到这,你就可以理解为什么几个行内元素会并排显示在一行,而每个块级元素都会另起一行了。
1.2.3 嵌套的元素
现在,该看一看在标记中嵌套的HTML元素到了屏幕上是什么效果啦。前面例子中的所有元素都有一个共同的父元素——body
。因此,Web Developer通常不显示它。但通过在Outline菜单中选择Outline Custom Elements命令,可以自定义显示body
,如图1-8所示。
图1-8 选择Outline Custom Elements命令后,在弹出的窗口中可以指定显示哪个元素以及用什么颜色显示
如图1-9所示,父元素body
的盒子(最外面的轮廓),直接嵌套(也就是包裹)着所有子元素盒子(内部的轮廓)。其中,块级子元素扩展到与body
元素同宽,后者默认与浏览器窗口同宽(但有一点外边距)。
在标记中嵌套的是HTML标签,而在屏幕上嵌套的则是一个个的盒子。
图1-9 父元素body
包围着它的子元素
在一个包含很多元素的页面中,盒子套盒子会越套越深,此时合理的HTML布局有助于通过标记看清页面结构,从而保证标签间正确的嵌套关系。我们推荐HTML标签每个层次相对于上一层次都缩进4个空格,如下面代码中的点所示。
在Dreamweaver等HTML编辑器中,每次按Tab键时就会缩进4个空格,从而保证缩进的一致性。
<nav id="toc">
....<ol>
........<li><a href="#">Introduction</a></li>
........<li><a href="#">Chapter 1</a></li>
........<li><a href="#">Chapter 2</a></li>
........<li><a href="#">Chapter 3</a></li>
....</ol>
</nav> <!-- end table of contents -->
两个在标记中嵌套的例子
我们再来看一个嵌套的例子,这一次使用blockquote
元素。顾名思义,blockqoute
元素包含引用内容,而且在页面上看起来是独立的元素。请注意代码中使用的表示弯引号的HTML实体。
<blockquote>“Sometimes you want to give up the guitar, you’ll hate the guitar. But if you stick with it, you're gonna be rewarded.”
<cite>Jimi Hendrix</cite>
//使用cite元素包含作者姓名
</blockquote>
图1-10展示了这段代码在页面中显示的效果,为两个元素都加了轮廓。
图1-10 blockquote
元素默认会缩进
HTML实体
HTML实体常用于生成那些键盘上没有的印刷字符,比如TM、†、©,等等。HTML实体以一个和号(&)开头,一个分号(;)结尾,二者之间是表示实体的字符串。在前面的例子中,两个实体的名字分别是“left-double-quote”(左双引号)和“right-double-quote”(右双引号)的简写。
Peachpit另一位作者Elizabeth Castro(她的书非常赞,在此强烈向大家推荐)在自己的一个网页中列出了常用的HTML实体:http://www.elizabethcastro.com/html/extras/entities.html。
要注意的是,由于和号表示实体开头,所以在要显示和号的时候不能直接写和号,而要在HTML标签包含的文本中使用
&
实体,这样才能显示出&来。比如,写成Johnson & Johnson
,才会显示成:Johnson & Johnson。
显然,
嵌套在blockquote
元素中位于引用文本之后的是cite
元素,它是一个行内元素。因为文本结束后还有空间,所以它就显示在了段落最后一行上。从图1-10中也可以看到,标签的内容默认是斜体。
同样是在这个例子中,还可以看到两个HTML实体,“
和”
,分别用于生成能够正确打印出来的左、右双引号。使用这两个引号的实体,而不是按键盘上的Shift-'(Shift-引号键),能让页面显示更加专业。
第二个嵌套的例子如下,是一个块级元素包含三个行内元素。
<p>It is <strong>absolutely critical</strong> that <em>everyone</em> does this <abbr title=”as soon as possible”>ASAP</abbr>!</p>
图1-11展示了Firefox浏览器中显示的效果。
图1-11 一个段落中嵌套着三个分别表示重要性、强调和简写的标签
图1-12与图1-11一样,只不过显示了元素盒子的轮廓。
图1-12 三个行内元素嵌套在一个块级元素中
这个例子除了能让你感到情况紧急之外,还能让你有如下收获。
- 文本被标记为段落,而其中包含三个行内元素。
标签表示重要,默认以粗体显示。
标签表示强调,默认以斜体显示。
标签表示简写,在Firefox中默认会加上点下划线。
好了,我们已经知道了HTML标记怎么在页面中创建盒子了,也知道了嵌套标记实际上就是嵌套盒子。那么,接下来我们就可以聊一聊文档对象模型(Document Object Model,DOM)了。