前言

本章介绍一些浏览器与服务器中最常见的传输文档语言——超文本标记语言(Hypertext Markup Language, HTML),我们主要学习HTML语言系列中最为严格的分支——XHTML(可扩展超文本标记语言),XHTML 具有与 HTML 相同的基本语法和元素,但在规则上更为严格。同时也将介绍一些简单的XML语言。

特别参考:W3School菜鸟教程MDN


HTML简介与编辑器

HTML 是一种标记语言,这意味着它用来标记(指示)文档中的各个部分,以指定文档在打印件或者显示器上的显示方式。HTML因为早起开发时各个厂商的规范与标准不同,W3C(万维网联盟)在1999发布了规范HTML4.01。但HTML4.01 存在两个根本性的问题。首先,它的语法规则不够严谨。所以HTML 文档可能存在各种各样的形式,不同的浏览器会以不同方式解释它们。这导致HTML 文档的编写十分随意。

于是,W3C在2000 年早期制定的XHTML 1.0 标准重新定义了HTML4.01,并遵循XML语法规则。

XHTML文档旨在格式良好,这意味着它们符合特定的结构和语法规则。这确保了XHTML文档可以被Web浏览器和其他软件以一致的方式解析和解释。

使用XHTML的好处之一是可以更容易地为残障人士创建无障碍网站。通过遵循严格的语法规则,开发人员可以更轻松地创建符合无障碍指南的网页。

直到2010 年,许多Web 开发人员使用XHTML来编写文档,以便利用更严格的语法规则、标准的格式和验证工具,但是文档仍然使用text/html, 并且浏览器仍然使用HTML解析器。然而,自HTML5推出以来,XHTML在Web开发中变得不太流行,因为HTML5提供了许多相同的优点,同时更加灵活且能够容忍语法错误。


说了这么多,我们主要注意一些XHTML的规范,它主要的限制规范:

  1. 所有标签必须小写
  2. 所有标签必须正确嵌套,即每个开始标签必须有一个相应的结束标签,并且它们不能重叠。
  3. 所有标签必须关闭。即使某些标签在HTML中可以省略结束标签,但在XHTML中不行。
  4. 所有属性必须用引号括起来,单引号或双引号均可。属性名称和属性值都必须符合XML命名规范。
  5. 所有非空元素必须包含一个结束标签,或者采取自闭合形式。
  6. 所有空元素必须采取自闭合形式,即在标签末尾添加斜杠。
  7. 所有注释必须采用HTML的注释格式。
  8. 所有实体引用必须以“&”开头,以“;”结尾。

而学习XHTML其实和学习HTML基本无异,我们只是在HTML基础上使用XHTML标准。学习编写HTML的时候,我们应该多试多练

本篇中的编辑器使用在线编辑器进行演示,中国大陆可以使用W3CSchool提供的编辑器:https://www.w3cschool.cn/tryrun/runcode?lang=html 

国际地区可以使用Programiz提供的:https://www.programiz.com/html/online-compiler/

其他建议搜索引擎查找。本地编辑器这里推荐使用vscode、sublime、notepad--之类的。

同时推荐一些VSCode前端方面的拓展,可以让你的VSCode更好用:

  • Open-In-Browser:在快捷菜单中添加了在默认浏览器中打开的选项。
  • HTML Boilerplate:生成干净的文档结构。
  • Auto Rename Tag:自动重命名配对的 HTML 标记。
  • Auto Close Tag:自动闭合 HTML/XML 标签。
  • Code Spell Checker:自动检查代码语法。
  • CSS Peek:可以追踪至样式表中 CSS 类和 ids 定义的地方。

基本HTML

HTML元素

在HTML中我们一般会把形如下列情况的HTML代码称为HTML标签(tag)

  • HTML 标签是由尖括号包围的关键词,比如 <html>
  • HTML 标签通常成对出现的,比如 <b> 和 </b>
  • 标签对中的第一个标签是开始标签,第二个标签是结束标签
  • 开始和结束标签也被称为开放标签闭合标签

而一个HTML元素(Element)是包含了HTML开始标签、结束标签(结束标签可能没有)与内容。即如图:

嵌套元素

当然,我们在使用时可以把元素放到其他元素之中——这被称作嵌套

例如:

<p>My cat is <strong>very</strong> grumpy.</p>

你需要确保元素被正确的嵌套:在上面的例子中我们先打开 p 元素,然后才打开 strong 元素,因此必须先将 strong 元素关闭,然后再去关闭 p 元素。

块级元素和内联元素

在 HTML 中有两种你需要知道的重要元素类别,块级元素和内联元素。

  • 块级元素在页面中以块的形式展现。一个块级元素出现在它前面的内容之后的新行上。任何跟在块级元素后面的内容也会出现在新的行上。块级元素通常是页面上的结构元素。例如,一个块级元素可能代表标题、段落、列表、导航菜单或页脚。一个块级元素不会嵌套在一个内联元素里面,但它可能嵌套在另一个块级元素里面。
  • 内联元素通常出现在块级元素中并环绕文档内容的一小部分,而不是一整个段落或者一组内容。内联元素不会导致文本换行。它通常与文本一起使用,例如,<a> 元素创建一个超链接,<em> 和 <strong> 等元素创建强调。
  • 块级元素与内联元素最基本的区别就是块级元素自带结尾换行,而内联元素不自带换行。

空元素

不是所有元素都拥有开始标签、内容和结束标签。一些元素只有一个标签,通常用来在此元素所在位置插入/嵌入一些东西。这些元素被称为空元素。例如:

<img src="avatar.png" />

我们插入了一张图片,<img>元素为空元素,它不需要结束标签。在HTML标准中,无需在一个空元素的标签末尾添加 /,但在XHTML中应该使用这种形式。


属性

属性是 HTML 元素提供的附加信息。属性包含元素的额外信息,这些信息不会出现在实际的内容中。

属性一般描述于开始标签,且总是以属性名="属性值"的形式出现,比如:name="value"。

必须存在一个空格在属性和元素名称之间。如果一个元素具有多个属性,则每个属性之间必须由空格分隔。

属性和属性值对大小写不敏感,但XHTML中必须使用小写。例如:

<a href="https://www.example.com">Example</a>

我们一般使用双引号包裹属性值,当然单引号也可以,看个人喜欢。但应该注意单引号和双引号不能在一个属性值里面混用

布尔属性

有时你会看到没有值的属性,用于标识一些内容,这也是完全可以接受的,这些属性被称为布尔属性。布尔属性只能有一个值,这个值一般与属性名称相同。例如:

<input type="text" disabled="disabled" />

我们为了简便,一般写成:

<input type="text" disabled />

基本HTML语法

一般来说,一个HTML应该包含下面四个部分:

  • 文档声明:<!DOCTYPE html>
  • html标签对:<html></html>
  • head标签对:<head></head>
  • body标签对:<body></body>

接下来我们来看一个简单的HTML代码作为示例。

 

<!DOCTYPE html 
    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head> 
    <meta charset="utf-8" />
    <title>HelloWorld</title> 
</head> 
<body> 
    <p>Hello World!</p> 
</body> 
</html>

文档声明

DOCTYPE标签是一种标准通用标记语言的文档类型声明,它的目的是要告诉标准通用标记语言解析器,它应该使用什么样的文档类型定义(DTD)来解析文档。文档类型是一个历史遗留问题,需要包含它才能使其他东西正常工作。

通常情况下,下列代码是最短的有效文档声明就可以了:

<!DOCTYPE html>

而采用了严格的XHTML格式的文档应该写成这样:

<!DOCTYPE html 
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

HTML元素

HTML标签元素表示一个 HTML 文档的根(顶级元素),所以它也被称为根元素。所有其他元素必须是此元素的后代。

在HTML中我们一般不需要任何属性,而在XHTML中我们必须加上xmlns属性以指派文档的 XML 命名空间。

<html xmlns="http://www.w3.org/1999/xhtml">

Head元素

<head> 元素用于表示头部内容,页面在浏览器加载后它的内容不会在浏览器中显示,它的作用是保存页面的一些元数据。我们有一些元素可以包含在里面:

可用于<head>元素内的元素有:<title><base><link><style><meta><script><noscript>

<meta> 元素表示那些不能由其他 HTML 元相关(meta-related)元素表示的元数据信息,通常有name属性和charset属性。name属性表示文档级别元数据,而charset属性是一个字符集声明,告诉文档使用哪种字符编码。

<title>元素设置了页面的标题,也就是出现在该页面加载的浏览器标签中的内容。当页面被加入书签时,页面标题也被用来描述该页面。

Body元素

包含了你访问页面时所有显示在页面上的内容,包含文本、图片、视频、游戏、可播放音频轨道等等。内部其他的基本元素在之后会涉及。


HTML特殊语义

空白

无论你在 HTML 元素的内容中使用多少空格(包括一个或多个空白字符或换行),当渲染这些代码的时候,HTML 解释器会将连续出现的空白字符减少只剩下一个单独的空格符。例如:

<p>你 好 呀 。</p>
<p>你    好
         呀      。</p>

上述语句在HTML中都是一样的,即第一句表现的形式,因为多个空格被消减为一个空格符。

如果我们不想让HTML忽略这些空格符,我们应该把它们包裹在<pre>标签中。

<pre>元素表示预定义格式文本。在该元素中的文本通常按照原文件中的编排,以等宽字体的形式展现出来,文本中的空白符(比如空格和换行符)都会显示出来。(紧跟在 <pre> 开始标签后的换行符也会被省略),例如:

注释

HTML 拥有在代码中写注释的机制。浏览器会忽略注释,有效地使注释对用户来说不可见。

为了将一段 HTML 中的内容置为注释,你需要将其用特殊的记号 <!-- 和 --> 包裹起来,比如:

<!-- <p>我在注释内!</p> -->

实体引用

在 HTML 中,字符 <>"' 和 & 是特殊字符,因为它们是 HTML 语法自身的一部分。我们必须使用字符实体引用——表示字符的特殊编码,它们可以在需要转义特殊符号的情况下使用。

每个字符引用以符号 & 开始,以分号(;)结束。常见的有:

显示结果 描述 实体名称 实体编号
不间断空格 &nbsp; &#160;
< 小于号 &lt; &#60;
> 大于号 &gt; &#62;
& 和号 &amp; &#38;
" 双引号 &quot; &#34;
' 单引号 &apos; &#39;
× 乘号 &times; &#215;
÷ 除号 &divide; &#247;

虽然HTML不区分大小写,但实体字符对大小写敏感

补充一些原型:

  • lt : less than
  • gt : greater than
  • amp : ampersand
  • quot : quotation

基本HTML元素

基本文本处理——标题与段落

大部分结构化文本由标题和段落组成。在 HTML 中,每个段落是通过 <p> 元素标签进行定义的,例如:

<p>我是一个段落。</p>

每个标题(Heading)都必须被包裹在一个标题元素中:

<h1>我是文章的标题</h1>

一共有六种标题元素标签——h1、h2、h3、h4、h5 和 h6。每个元素代表文档中不同级别的内容:<h1> 表示主标题,<h2> 表示二级子标题,<h3> 表示三级子标题等等,它们的区别也挺明显,如下代码及其展示:

<!DOCTYPE html>
<html>
  <head>
    <title>Headings</title>
  </head>
<body>
  <h1>Heading 1</h1>
  <h2>Heading 2</h2>
  <h3>Heading 3</h3>
  <h4>Heading 4</h4>
  <h5>Heading 5</h5>
  <h6>Heading 6</h6>
  <p>The default paragraph text.</p>
</body>
</html>

于是我们就有了一个简单的结构——标题-段落的结构。所涉及的元素具体代表什么,完全取决于作者编辑的内容,只要层次结构是合理的。于是我们写一篇文章可以写成这样,例如:

<h1>三国演义</h1>
<p>罗贯中</p>
<h2>第一回 宴桃园豪杰三结义 斩黄巾英雄首立功</h2>
<p>话说天下大势,分久必合,合久必分。周末七国分争,并入于秦。及秦灭之后,楚、汉分争,又并入于汉……</p>

为了保证其美观,建议:

  • 最好只对每个页面使用一次 <h1>——这是顶级标题,所有其他标题位于层次结构中的下方。
  • 请确保在层次结构中以正确的顺序使用标题。
  • 减少标题层次的层数。

格式化文本——强调与样式

在表达中,我们有时会强调某些字,有可能是加粗也有斜体。我们一般使用内联元素<em>元素表示斜体,用<strong>元素表示粗体。例如:

<p>你好,我是<strong>田所浩二</strong>,24岁,是<em>学生</em>。</p>

除了上述外,之前还定义有<b><i> 和 <u>分别表示粗体、斜体和下划线。

因为HTML会自动将空格减少到1个,当我们在<p>元素中换行时也许只显示一个空格甚至不显示。当我们需要手动空行的时候,我们需要使用<br>元素。例如:

<p>话说天下大势,分久必合,合久必分。<br>周末七国分争,并入于秦。</p>

当然,因为<p>元素是块元素,我们也可以通过多个<p>元素实现换行:

我们可以发现,使用两个<p>元素的换行间距会比<br>元素换行间距大,我们在使用中一般分为:<p>标签是分段<br>标签是换行。而在XHTML中,我们需要闭合所有的标签,应该写成:<br />

当我们在使用日期、化学方程式、和数学方程式时会偶尔使用上标和下标,我们可以使用<sup> 和 <sub> 元素可以解决这样的问题。例如:

<p>
  咖啡因的化学方程式是
  C<sub>8</sub>H<sub>10</sub>N<sub>4</sub>O<sub>2</sub>。
</p>
<p>如果 x<sup>2</sup> 的值为 9,那么 x 的值必为 3 或 -3。</p>

当然现在有一些富文本编辑语言(例如Markdown)支持渲染LaTeX数学公式,这里不做展示。

HTML 还支持将时间和日期标记为可供机器识别的格式的 <time> 元素,因为世界上有许多种书写日期的格式,不同地区格式不同。例如:

<time datetime="2016-01-20">20 January 2016</time>

超文本格式

超链接使我们能够将我们的文档链接到任何其他文档(或其他资源),也可以链接到文档的指定部分,我们可以在一个简单的网址上提供应用程序。几乎任何网络内容都可以转换为链接,点击(或激活)超链接将使网络浏览器转到另一个网址(URL)。

我们一般通过将文本或其他内容包裹在 <a> 元素内,并给它一个包含网址的 href 属性(也称为超文本引用目标,它将包含一个网址)来创建一个基本链接。例如:

<a href="https://hoyue.fun">hoyue</a>

<a>元素是块元素,可以包含其他元素,例如我们把顶级标题放在<a>元素之内,有:

你可能要添加到你的链接的另一个属性是 title。这旨在包含关于链接的补充信息,例如页面包含什么样的信息或需要注意的事情。当我们把光标放上去的时候,会显示补充信息,例如:

<a href="https://hoyue.fun" title="View Hoyue Blog">hoyue</a>

此时我们在href属性引用的目标为URL,通常是一个网络上的地址。当我们加载本地地址时,经常使用相对路径与绝对路径

绝对 URL指向由其在 Web 上的绝对位置定义的位置,包括协议域名。例如:如果 index.html 页面上传到了 projects 这一个目录。并且 projects 目录位于 web 服务站点的根目录,web 站点的域名为 https://www.example.com,那么这个页面就可以通过 https://www.example.com/projects/index.html 访问(或者通过 https://www.example.com/projects/ 来访问,因为在没有指定特定的 URL 的情况下,大多数 web 服务器会默认访问加载 index.html 这类页面)

不管绝对 URL 在哪里使用,它总是指向确定的相同位置。即https://www.example.com/projects/index.html

相对 URL:指向与你链接的文件相关的位置。如上例子中,如果我们在projects中上传一个文件comment.html,若我们在index.html文件中引用它,它此时的目录就是comment.html

  • 指向当前目录你只需要指定想要链接到的文件名,因为它与当前文件是在同一个目录的。如上例。
  • 指向子目录:如果你想在 index.html (顶层 index.html)中包含一个指向 projects/index.html 的超链接,你需要先进入 projects 项目目录,然后通过指定目录的名称,然后是正斜杠,然后是文件的名称指明要链接到的文件 index.html。因此你要使用的 URL 是 projects/index.html。当然我们还可以使用./projects/index.html的方式表示。
  • 指向上级目录:如果你想在 projects/index.html 中包含一个指向 pdfs/project-brief.pdf 的超链接,你必须先返回上级目录,然后再回到 pdfs 目录。“返回上一个目录级”使用两个英文点号表示..),因此你应该使用的 URL 是 ../pdfs/project-brief.pdf

我们通过一个例子来巩固这些知识,例如我们的根目录为D:\WEB

在目录HTML下有:

D:\WEB\HTML\CSS下有一个style.cssD:\WEB\Homework下还有一个图像avatar.jpg

  1. 我们在D:\WEB\HTML\hello.html中添加一个链接跳转到D:\WEB\HTML\HelloWorld.html,我们应该写成:
    <a href="HelloWorld.html">Click here to jump.</a>

    此时是相对URL,且在同目录,直接写文件名即可。当然,它和绝对地址写法等价:

    <a href="D:\WEB\HTML\HelloWorld.html">Click here to jump.</a>
  2. 如果我们要添加一个CSS(D:\WEB\HTML\CSS\style.css)到D:\WEB\HTML\hello.html中,相对URL我们可以写成:
    <link rel="stylesheet" href="CSS/style.css" />

    同时,我们还可以写成下面的形式,它们都是等价的:

    <link rel="stylesheet" href="./CSS/style.css" />
  3. 如果我们要添加一个图片(D:\WEB\Homework\avatar.jpg)到D:\WEB\HTML\hello.html中,相对URL我们可以写成:
    <img src="../Homework/avatar.jpg" />

如果我们要链接的目标是位于文档内部的目标,此时我们需要给跳转目标位置增加一个id属性,在链接中使用#id的格式链接。例如:

<a href="#goto1">111</a>
<h1 id="goto1">Heading1</h1>

当我们点下111时,我们的页面就会跳转到Heading1的位置。

除了链接以外,<a>元素还有其他一些常用的属性。

对于邮箱,当点击一个链接或按钮时,可能会开启新的邮件的发送而不是连接到一个资源或页面。这种场景可以使用 <a> 元素和 mailto: URL 协议实现。

<a href="mailto:[email protected]">向 hoyue 发邮件</a>

当你链接到要下载的资源而不是在浏览器中打开时,你可以使用 download 属性来提供一个默认的保存文件名。

<a href="https://download.mozilla.org/?product=firefox-latest-ssl&os=win64&lang=zh-CN"
   download="firefox-latest-64bit-installer.exe">
  下载最新的 Firefox 中文版 - Windows(64 位)
</a>

多媒体处理

我们可以用<img> 元素来把图片放到网页上。它是一个空元素(它不需要包含文本内容或闭合标签),最少只需要一个 src (一般读作其全称 *source)*来使其生效。src 属性包含了指向我们想要引入的图片的路径,可以是相对路径或绝对 URL,就像 <a> 元素的 href 属性一样。

例如前文例子中:

如果我们要添加一个图片(D:\WEB\Homework\avatar.jpg)到D:\WEB\HTML\hello.html中,可以写成:

<img src="../Homework/avatar.jpg" />

我们就嵌入了一张图片,它的路径为D:\WEB\Homework\avatar.jpg

<img>元素还有一个alt属性,它的值应该是对图片的文字描述,用于在图片无法显示或不能被看到的情况。注意:不代表鼠标停留时显示的文本。

例如:

<img src="../Homework/avatar.jpg" alt="错误的时候才能看到我" />

你还可以用widthheight属性来指定你的图片的高度和宽度,但不建议使用 HTML 属性来改变图片的大小。因为如果你没有保持正确的宽高比,图片可能看起来会扭曲。例如:

<img src="../Homework/avatar.jpg" alt="错误的时候才能看到我" width="400" height="400" />

它们的单位均为像素(PX),也可以使用百分比描述,为宽度或高度的百分比数

类似于超链接,你可以给图片增加title属性来提供需要更进一步的支持信息。这就是鼠标停留时出现的信息了,例如:

<img src="images/dinosaur.jpg"
     alt="一只恐龙头部和躯干的骨架,它有一个巨大的头,长着锋利的牙齿。"
     width="400"
     height="341"
     title="A T-Rex on display in the Manchester University Museum">

对于多张图片的处理,HTML5中引入了<figure> 和 <figcaption> 元素,具体请看文档介绍。

表处理——列表

当我们要展示列的时候,HTML提供了列表来处理,我们有三种不同的类型需要注意。

无序列表(unordered lists)是一个项目的列表,此列项目使用粗体圆点(典型的小黑圆圈)进行标记。无序列表使用<ul>元素定义,项目由<li>元素(list items)包裹例如:

<ul>
  <li>豆浆</li>
  <li>油条</li>
  <li>馒头</li>
  <li>包子</li>
</ul>

它的展示效果为:

同样,有序列表(ordered lists)也是一列项目,列表项目使用数字进行标记。这个标记的结构和无序列表一样,除了需要用 <ol> 元素将所有项目包裹,而不是 <ul>。例如:

<ol>
<li>豆浆</li>
<li>油条</li>
<li>馒头</li>
<li>包子</li>
</ol>

我们还有一种自定义列表,不仅仅是一列项目,而是项目及其注释的组合。

自定义列表(definition lists)以 <dl> 标签开始。每个自定义列表项(definition term)以 <dt> 开始。每个自定义列表项的描述(definition description)以 <dd> 开始。例如:

<dl>
<dt>豆浆</dt>
<dd>我早餐喜欢喝</dd>
<dt>油条</dt>
<dd>适合和豆浆一起吃</dd>
</dl>

请注意,描述一般与列表项有缩进关系

表处理——表格

表格是由行和列组成的结构化数据集(表格数据),它让你快速简单地查找某个表示不同类型数据之间的某种关系的值。建立一个表格有这些步骤:

  • 每一个表格的内容都包含在这两个标签中:<table></table>
  • 在表格中,最小的内容容器是单元格,是通过 <td> 元素创建的(table data),它是横向向右创建的。
  • 当需要表格换行时,需要使用 <tr> 元素(其中“tr”代表“table row”)。

通过这样的方法我们就成功创建了一个表格,表格中框线默认为无,框线样式可以通过CSS进行调整。在这里使用的border属性已经被弃用,为了显示而使用。

<table border=1>
  <tr>
    <td>Hi, I'm your first cell.</td>
    <td>I'm your second cell.</td>
    <td>I'm your third cell.</td>
    <td>I'm your fourth cell.</td>
  </tr>
  <tr>
    <td>Hi, I'm your first cell.</td>
    <td>I'm your second cell.</td>
    <td>I'm your third cell.</td>
    <td>I'm your fourth cell.</td>
  </tr>
</table>

我们还可以给表格添加模式(标题),表格中的标题是特殊的单元格,通常在行或列的开始处,定义行或列包含的数据类型。例如:

<table border="1">
  <tr>
    <th>Header 1</th>
    <th>Header 2</th>
  </tr>
  <tr>
    <td>row 1, cell 1</td>
    <td>row 1, cell 2</td>
  </tr>
  <tr>
    <td>row 2, cell 1</td>
    <td>row 2, cell 2</td>
  </tr>
</table>

我们处理标题时同样可以把它当成普通单元格对待,只是用不同的标签表示了。

在表格中,我们的数据默认左对齐我们可以把大部分元素放入表格中让其保持对齐的状态。例如:

<table>
  <tr>
    <td><label for="shipping-name">Name:</label></td>
    <td><input type="text" id="shipping-name"></td>
  </tr>
  <tr>
    <td><label for="shipping-street">Street:</label></td>
    <td><input type="text" id="shipping-street"></td>
  </tr>
  <tr>
    <td><label for="shipping-city">City:</label></td>
    <td><input type="text" id="shipping-city"></td>
  </tr>
  <tr>
    <td><label for="shipping-state">State:</label></td>
    <td><input type="text" id="shipping-state"></td>
  </tr>
  <tr>
    <td><label for="shipping-zip">Zip Code:</label></td>
    <td><input type="text" id="shipping-zip"></td>
  </tr>
</table>

在这个示例中,我们把<lable>元素和<input>元素放在表格里让它们左侧对其。其中<label>元素(标签)表示用户界面中某个元素的说明。<input> 元素用于为基于 Web 的表单创建交互式控件,以便接受来自用户的数据。

如果我们需要合并单元格,则需要使用表格中的标题和单元格的 colspan 和 rowspan 属性。这两个属性接受一个没有单位的数字值,数字决定了它们的宽度或高度是几个单元格。例如:

<table border="1"> 
  <tr> 
    <th colspan="2">Header</th> 
  </tr> 
  <tr> 
    <td rowspan="2">row 1/2, cell 1</td> 
    <td>row 1, cell 2</td> 
  </tr> 
  <tr> 
    <td>row 2, cell 2</td> 
  </tr> 
</table>

此时我们对一个标题使用了colspan="2",让其宽度为2个单元格。接着对一个单元格使用了rowspan="2"让它高度为2个单元格。效果如图:

除了我们前文知道的表格模式(表标题)外,HTML还定义了一个大标题,通过 <caption> 元素实现。形如:

<table>
  <caption>BIG TITLE</caption>
  ...
</table>

表处理——表单

HTML 表单用于收集用户的输入信息。表示文档中的一个区域,此区域包含交互控件,将用户收集到的信息发送到 Web 服务器。

所有表单都以一个 <form> 元素开始,它一般有两个属性:

  • action 属性定义了在提交表单时,应该把所收集的数据送给谁(URL)去处理。即用户提交表单时将数据使用什么method发送到这个actionURL上。
  • method 属性定义了发送数据的 HTTP 方法(通常是 get 或 post)。

而还有target 属性规定提交表单后在何处显示响应。

_blank 响应显示在新窗口或选项卡中。
_self 响应显示在当前窗口中。
_parent 响应显示在父框架中。
_top 响应显示在窗口的整个 body 中。
framename 响应显示在命名的 iframe 中。

表单中一般有<label><input><textarea> 和 <buttom>元素构成,即标签、单行编辑框和多行输入框。

<label> 元素(标签)表示用户界面中某个元素的说明。通常作为<input>的说明语句使用。

<input> 元素用于为基于 Web 的表单创建交互式控件,以便接受来自用户的数据。取决于设备和用户代理不同,表单可以使用各种类型的输入数据和控件。<input> 元素是一个空元素,不需要结束标签。

将一个 <label> 和一个 <input> 元素匹配在一起,你需要给 <input> 一个 id 属性而 <label> 需要一个 for 属性,其值和 <input> 的 id 一样。例如:

<label for="cheese">Do you like cheese?</label>
<input type="checkbox" name="cheese" id="cheese">

另外,也可以将 <input> 直接放在 <label> 里,此时则不需要 for 和 id 属性,因为关联已隐含存在:

<label>Do you like peas?
<input type="checkbox" name="peas">
</label>

<input>元素的工作方式相当程度上取决于 type 属性的值,而type 属性的值非常的多。下面是一些常用的:

  1. text 定义供文本输入的单行输入字段。
  2. password单行的密码文本区域,其值会被*遮盖。
  3. submit定义提交表单数据至表单处理程序的按钮
  4. reset是个按钮,将表单的所有内容重置为默认值。
  5. radio定义单选按钮。
  6. checkbox定义复选框。
  7. button定义按钮。
  8. ......

演示如下:

<form action="" method="post">
  <label for="name">Name:</label>
  <input type="text" id="name" name="user_name"><br>

  <label for="password">Password:</label>
  <input type="password" id="password" name="password"><br>

  <label for="radio">Radio:</label>
  <input type="radio" id="radio" name="radio"><br>

  <label for="checkbox">Checkbox:</label>
  <input type="checkbox" id="checkbox" name="checkbox"><br> 

  <label for="submit">Submit:</label>
  <input type="submit" id="submit" name="submit" value="submit"><br>

  <label for="reset">Reset:</label>
  <input type="reset" id="reset" name="reset" value="reset"><br>

  <label for="button">Button:</label>
  <input type="button" id="button" name="button" value="button">
</form>

<input>元素除了type属性决定了输入元素的类型外,我们还常用一些属性如下:

  • value 属性规定输入字段的初始值;
  • name属性是表单的控件名称,作为键值对的一部分与表单一同提交;
  • readonly 属性规定输入字段为只读(不能修改);
  • disabled 属性规定输入字段是禁用的。被禁用的元素是不可用和不可点击的;
  • size属性规定输入字段的尺寸(以字符计);
  • maxlength 属性规定输入字段允许的最大长度。
  • required属性规定在提交表单之前必须填写输入字段。

除了<input>元素外,我们还有<textarea> 元素定义多行输入字段,当你希望用户输入一段相当长的、不限格式的文本,例如评论或反馈表单中的一段意见时,这很有用。

  • 和<input>一样,id 属性用于将 <textarea>与一个<lable>关联。
  • name 属性,用于设置随表单一同提交到服务器的相关数据的名字。
  • rows 和 cols 属性,用于声明 <textarea> 的精确尺寸。这对于一致性非常有帮助,因为不同浏览器的默认值常常不一样。
  • <textarea> 元素不是空元素,需要结束标签。<textarea> 不支持 value 属性,需要默认值直接在开始与结束标签之间添加即可。

示例:

<form action="" method="post">
  <label for="story">Tell us your story:</label><br>
  <textarea id="story" name="story" rows="10" cols="50">It was a dark and stormy night...</textarea>
</form>

除了上述以外,我们还有<button>元素,它有一个属性type,具体情况与<input>中对应type相同。

  • 单击 type 属性定义为 submit 值(也是默认值)的按钮会发送表单的数据到 <form> 元素的 action 属性所定义的网页。
  • 单击 type 属性定义为 reset 值的按钮 将所有表单小部件重新设置为它们的默认值。
  • 单击 type 属性定义为 button 值的按钮。

<button> 元素的主要优点是,<input> 元素只允许纯文本作为其标签,而 <button> 元素允许完整的 HTML 内容,允许更复杂、更有创意的按钮内容。

我们有些时候还可能用到菜单功能,HTML 有两种下拉内容:一种是选择框、另外一种是自动补全框

一个简单的选择框是由 <select> 元素及一个或多个 <option> 子元素构成的,每个子元素指定了选择框的可能取值。例如:

<form action="" method="post">
  <select id="simple" name="simple">
    <option>Banana</option>
    <option selected>Cherry</option>
    <option>Lemon</option>
  </select>
</form>

选择框的默认值可以由要指定默认值的 <option> 元素中的 selected 属性设置,这样在页面加载后,该选项可以预先选中。

如果一个 <option> 元素明确设置了 value 属性,当表单提交时也会提交那个选项对应的值。当然这是可选的。

分组

<fieldset>元素用于对表单中的控制元素进行分组。<fieldset> 元素将一个 HTML 表单的一部分组成一组,内置了一个 <legend> 元素作为 fieldset 的标题。例如:

<form>
  <fieldset>
    <legend>health information</legend>
    height: <input type="text" />
    weight: <input type="text" />
  </fieldset>

  <fieldset>
    <legend>Choose your favorite monster</legend>
    <input type="radio" id="kraken" name="monster" value="K">
    <label for="kraken">Kraken</label><br>

    <input type="radio" id="sasquatch" name="monster" value="S">
    <label for="sasquatch">Sasquatch</label><br>

    <input type="radio" id="mothman" name="monster" value="M" />
    <label for="mothman">Mothman</label>
  </fieldset>
</form>

<fieldset> 元素有一个form属性,其可以包含同一页面的 <form> 元素的 id,以使 <fieldset> 成为这个 <form> 的一部分,即使 <fieldset> 不在其内。

网站基础构架

对于一个网站,我们一般有一种基本构架:

  • 页眉(标题):通常横跨于整个页面顶部有一个大标题 和/或 一个标志。这是网站的主要一般信息,通常存在于所有网页。
  • 导航栏(可选):指向网站各个主要区段的超链接。通常用菜单按钮、链接或标签页表示。类似于标题栏,导航栏通常应在所有网页之间保持一致,否则会让用户感到疑惑,甚至无所适从。
  • 主内容:中心的大部分区域是当前网页大多数的独有内容,例如视频、文章、地图、新闻等。这些内容是网站的一部分,且会因页面而异。
  • 侧边栏(可选):一些外围信息、链接、引用、广告等。通常与主内容相关(例如一个新闻页面上,侧边栏可能包含作者信息或相关文章链接),还可能存在其他的重复元素,如辅助导航系统。
  • 页脚(可选):横跨页面底部的狭长区域。和标题一样,页脚是放置公共信息(比如版权声明或联系方式)的,一般使用较小字体,且通常为次要内容。

通过合适的 CSS,你可以使用相当多种的任意页面元素来环绕在不同的页面区域来做成你想要的样子。有时你会发现,对于一些要组织的项目或要包装的内容,现有的语义元素均不能很好对应。有时候你可能只想将一组元素作为一个单独的实体来修饰来响应单一的用 CSS 或 JavaScript。

为了应对这种情况,HTML 提供了 <div> 和 <span> 元素。应配合使用 class 属性提供一些标签,使这些元素能易于查询。

  • <span> 是一个内联的(inline)无语义元素,最好只用于无法找到更好的语义元素来包含内容时,或者不想增加特定的含义时。
  • <div> 是一个块级无语义元素,应仅用于找不到更好的块级元素时,或者不想增加特定的意义时。

它们的使用在学习CSS 与 JavaScript中会提及,这里只是介绍。

对于主文本和侧边栏的存在,在基础的HTML中我们一般使用表格中<td>元素的 width属性来处理。但在实际情况中我们更希望使用CSS解决。下面是使用width属性实现的侧边栏的例子。

<table>
  <tr>
    <td style="vertical-align:top" width="70%">
      <h2>Title</h2>
      <p>Context</p><br>
    </td>
    <td style="vertical-align:top" width="30%">
      <h2>Sidebar</h2>
      <ul>
      <li><b>Name:</b></li>
      <li><b>Age:</b></li>
      <li><b>Birth Place:</b></li>
      <li><b>Residence Place:</b></li>
      <li><b>Occupation:</b></li>
      </ul>
    </td>
  </tr>
</table>


基本XML

XML语法与语义

XML 指可扩展标记语言(EXtensible Markup Language),XML 被设计为传输和存储数据,其焦点是数据的内容。HTML 被设计用来显示数据,其焦点是数据的外观。

XML 仅仅是纯文本而已,并不能做任何事情。有能力处理纯文本的软件都可以处理 XML。不过,能够读懂 XML 的应用程序可以有针对性地处理 XML 的标签。标签的功能性意义依赖于应用程序的特性。

例如下面是 John 写给 George 的便签,存储为 XML:

<note>
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>

上面的这条便签具有自我描述性。它拥有标题以及留言,同时包含了发送者和接受者的信息。

上例中的标签没有在任何 XML 标准中定义过(比如 <to> 和 <from>)。这些标签是由文档的创作者发明的。

这是因为 XML 没有预定义的标签在 HTML 中使用的标签(以及 HTML 的结构)是预定义的。HTML 文档只使用在 HTML 标准中定义过的标签(比如 <p> 、<h1> 等等)。

XML 的语法规则很简单,且很有逻辑。这些规则很容易学习,也很容易使用。

闭合与大小写要求

在 XML 中,省略关闭标签是非法的。所有元素都必须有关闭标签。下面例子中第一句是非法的

<p>This is a paragraph <p>This is a paragraph</p>

XML 标签对大小写敏感。在 XML 中,标签 <Letter> 与标签 <letter> 是不同的。必须使用相同的大小写来编写打开标签和关闭标签:

<Message>这是错误的。</message>
<message>这是正确的。</message>

嵌套

在 XML 中,所有元素都必须彼此正确地嵌套,例如:

<b><i>This text is bold and italic</i></b>

由于 <i> 元素是在 <b> 元素内打开的,那么它必须在 <b> 元素内关闭。

引号

与 HTML 类似,XML 也可拥有属性(名称/值的对)。在 XML 中,XML 的属性值须加引号。

例如:

<note date="16/03/2023">

注释

在 XML 中编写注释的语法与 HTML 的语法很相似:

<!-- This is a comment -->

空格保留

HTML 会把多个连续的空格字符裁减(合并)为一个,而在 XML 中,文档中的空格不会被删减

<p>Hello           my name is David.</p> Output: Hello           my name is David.

实体引用

和HTML一样,在 XML 中,一些字符拥有特殊的意义。

在 XML 中,有 5 个预定义的实体引用:

&lt; < 小于
&gt; > 大于
&amp; & 和号
&apos; ' 单引号
&quot; " 引号

其实为了迎合HTML,虽然在 XML 中,只有字符 "<" 和 "&" 确实是非法的。但是用实体引用来代替其它是一个好习惯。 


文档类型定义(DTD)

文档类型定义(DTD)可定义合法的XML文档构建模块。它使用一系列合法的元素来定义文档的结构。我们通过DTD,可以得到关于XML文件元素与属性的自己描述。

元素声明

在一个 DTD 中,元素通过ELEMENT来进行声明。其基本格式为:

<!ELEMENT 元素名称 类别>
  • 如果我们声明的这个元素为空元素时,就应该使用类别EMPTY
  • 如果我们声明元素可以带任何元素,则使用类别ANY

例如:

<!ELEMENT br EMPTY>    #声明<br /> <!ELEMENT note ANY>    #声明<note></note>里面可以有任意其他元素

如果我们声明元素可以带有一个或多个子元素的元素,此时用圆括号子元素名的方式表示。

例如:

<!ELEMENT note (to,from,heading,body)>

当子元素按照由逗号分隔开的序列进行声明时,这些子元素必须按照相同的顺序出现在文档中。如上例子,note元素必须包含to,from,heading,body,且按照这个顺序出现。

我们使用|号分割开的序列声明时,它们必须恰好出现其中之一

例如:

<!ELEMENT select (opegroup|option)>

如上例子,opegroup、option元素必须出现其中之一,且不能同时出现

当然,我们元素中可以接任意字符数据,称为PCDATA——被解析的字符数据(parsed character data)。

例如:

<!ELEMENT to  (#PCDATA)>

表明to元素可以接任意字符数据。

除此之外,我们还有三个符号用来表达元素或序列出现的次数。

  • +:我们可以声明最少出现一次的元素,在元素/实体后加上一个+号表示。
  • ?:声明出现零次或一次的元素
  • *声明重复出现任意次(随意)。

例如,混合型元素声明:

<!ELEMENT note (#PCDATA|to|from|header|message)*>

表明,"note" 元素可包含出现任意次数的 PCDATA、"to"、"from"、"header" 或者 "message"。

还有一个例子:

<!ELEMENT note (to,from,header,(message|body))>

表明,"note" 元素必须包含 "to" 元素、"from" 元素、"header" 元素,以及非 "message" 元素既 "body" 元素。

属性声明

在 DTD 中,属性通过 ATTLIST 声明来进行声明。

<!ATTLIST 元素名称 属性名称 属性类型 默认值>

其中属性类型包括:

类型 描述
CDATA 值为字符数据 (character data)
(en1|en2|..) 此值是枚举列表中的一个值
ID 值为唯一的 id
IDREF 值为另外一个元素的 id
IDREFS 值为其他 id 的列表
NMTOKEN 值为合法的 XML 名称
NMTOKENS 值为合法的 XML 名称的列表
ENTITY 值是一个实体
ENTITIES 值是一个实体列表
NOTATION 此值是符号的名称
xml: 值是一个预定义的 XML 值

其中默认值我们可以写成:

解释
属性的默认值
#REQUIRED 属性值是必需的
#IMPLIED 属性不是必需的
#FIXED value 属性值是固定的

例如:

<!ATTLIST contact fax CDATA #IMPLIED> <!ATTLIST person number CDATA #REQUIRED> <!ATTLIST sender company CDATA #FIXED "Microsoft"> <!ATTLIST payment type (check|cash) "cash">

其中根据这些定义,下面语句的是合法的:

<contact fax="555-667788" /> <person number="5677" /> <sender company="Microsoft" /> <payment type="check" /> <payment type="cash" />

实体声明

实体是用于定义引用普通文本或特殊字符的快捷方式的变量。

我们引用内部实体时,写作:

<!ENTITY 实体名称 "实体的值">

例如:

<!ENTITY writer "Hoyue">

我们在XML中,一个实体由三部分构成: 一个和号 (&), 一个实体名称, 以及一个分号 (;)。如上例子,应该在XML中写为:&writer;

在XML中,参数实体是一种特殊类型的实体,用于在DTD中定义可重复使用的文本或值。与普通实体不同,参数实体被定义为DTD中的一个单独部分,并且可以作为DTD中其他实体或属性的值来引用。

参数实体由百分号符号(%)和名称组成,在声明中写为:

<!ENTITY % entity_name "entity_value">

其中,"entity_name"是参数实体的名称,而"entity_value"是该实体的值。我们可以在定义元素或属性时部分位置用% entity_name的形式代替。


后记

本章介绍了HTML中最严格的分支——XHTML的基本使用,以及XML语言的基本内容,便于我们编写文档。

这里的一切都有始有终,却能容纳所有的不期而遇和久别重逢。
最后更新于 2023-03-17