# 文本标签

历史上，网页的主要功能是文本展示。所以，HTML 提供了大量的文本处理标签。

## `<div>`

`<div>`是一个通用标签，表示一个区块（division）。它没有语义，如果网页需要一个块级元素容器，又没有其他合适的标签，就可以使用这个标签。

它的最常见用途就是提供 CSS 的钩子，用来指定各种样式。所以在早期，下面层层包裹的`<div>`就很常见。

```html
<div class="main">
  <div class="article">
    <div class="title">
      <h1>文章标题</h1>
    </div>
  </div>
</div>
```

上面代码读起来很费力，因为不带有语义。后来，HTML 5 就提出了语义标签，改进了上面的代码。

```html
<main>
  <article>
    <header>
      <h1>文章标题</h1>
    </header>
  </article>
</main>
```

`<div>`是无语义的块级元素。下面的例子使用`<div>`，将图像和文字组合在一起，构成一个警告区块。

```html
<div>
  <img src="warning.jpg" alt="警告">
  <p>小心</p>
</div>
```

只要样式上需要多个块级元素组合在一起，就可以使用`<div>`。但是，这应该是最后的措施，带有语义的块级标签（比如`<article>`、`<section>`、`<aside>`、`<nav>`等）始终应该优先使用，当且仅当没有其他语义元素合适时，才可以使用`<div>`。

## `<p>`

`<p>`标签是一个块级元素，代表文章的一个段落（paragraph）。不仅是文本，任何想以段落显示的内容，比如图片和表单项，都可以放进`<p>`元素。

```html
<p>hello world</p>
```

上面代码就是一个简单的段落。

## `<span>`

`<span>`是一个通用目的的行内标签（即不会产生换行），不带有任何语义。它通常用作 CSS 样式的钩子，如果需要对某些行内内容指定样式，就可以把它们放置在`<span>`。

```html
<p>这是一句<span>重要</span>的句子。</p>
```

上面代码中，句子里面需要强调的部分，就可以放在`<span>`。

## `<br>`，`<wbr>`

`<br>`让网页产生一个换行效果。该标签是单独使用的，没有闭合标签。

```html
hello<br>world
```

浏览器渲染上面代码时，会分成两行，`hello`和`world`各占一行。

`<br>`对于诗歌和地址的换行非常有用。

```html
<p>
  床前明月光，<br>
  疑是地上霜。<br>
  举头望明月，<br>
  低头思故乡。
</p>
```

上面的代码如果不用`<br>`，会显示成一行。

注意，块级元素的间隔，不要使用`<br>`来产生，而要使用 CSS 指定。

```html
<p>第一段</p>
<br>
<br>
<p>第二段</p>
```

上面的代码希望段落之间有两个换行，这时不应该使用`<br>`，而应该使用 CSS。

`<wbr>`标签跟`<br>`很相似，表示一个可选的断行。如果一行的宽度足够，则不断行；如果宽度不够，需要断行，就在`<wbr>`的位置的断行。它是为了防止浏览器在一个很长的单词中间，不正确地断行或者不断行，所以事先标明可以断行的位置，主要用于欧洲一些单词很长的语言或者 URL 的断行。

```html
<p>
Fernstraßen<wbr>bau<wbr>privat<wbr>finanzierungs<wbr>gesetz
</p>
```

上面代码是一个很长的德语单词，为了防止不正确断行，事先用`<wbr>`告诉浏览器，可以选择在哪里断行。

## `<hr>`

`<hr>`用来在一篇文章中分隔两个不同的主题，浏览器会将其渲染为一根水平线。该标签是单独使用的，没有闭合标签。

```html
<p>第一个主题</p>
<hr>
<p>第二个主题</p>
```

上面代码的渲染结果是，两段之间会出现一根水平线。

该标签是历史遗留下来的，建议尽量避免使用。主题之间的分隔可以使用`<section>`，如果想要水平线的效果，可以使用 CSS。

## `<pre>`

`<pre>`是一个块级元素，表示保留原来的格式（preformatted），即浏览器会保留该标签内部原始的换行和空格。浏览器默认以等宽字体显示标签内容。

```html
<pre>hello

   world</pre>
```

上面代码中，换行和连续空格都会由于`<pre>`标签，而被保留下来，浏览器按照原样输出。

注意，HTML 标签在`<pre>`里面还是起作用的。`<pre>`只保留空格和换行，不会保留 HTML 标签。

```html
<pre><strong>hello world</strong></pre>
```

上面代码中，`<pre>`标签的内容会加粗显示。

## `<strong>`，`<b>`

`<strong>`是一个行内元素，表示它包含的内容具有很强的重要性，需要引起注意。浏览器会以粗体显示内容。

```html
<p>开会时间是<strong>下午两点</strong>。</p>
```

`<b>`与`<strong>`很相似，也表示它包含的内容需要引起注意，浏览器会加粗显示。它是 Boldface 的缩写。

```html
<p>开会时间是<b>下午两点</b>。</p>
```

它与`<strong>`的区别在于，由于历史原因，它没有语义，是一个纯样式的标签，违反了语义与样式分离的原则，因此不建议使用，应该优先使用`<strong>`标签。

## `<em>`，`<i>`

`<em>`是一个行内标签，表示强调（emphasize），浏览器会以斜体显示它包含的内容。

```html
<p>我们<em>已经</em>讨论过这件事情了。</p>
```

虽然浏览器通常会以斜体显示`<em>`，但无法保证一定如此，所以最好还是用 CSS 指定一下这个标签的样式。

`<i>`标签与`<em>`相似，也表示与其他地方有所区别，浏览器会以斜体显示。它是 Italic 的缩写。

```html
<p>我心想，这件事是<i>真的</i>吗？</p>
```

`<i>`标签的语义不强，更接近是一个纯样式的标签，建议优先使用`<em>`标签代替它。

## `<sub>`，`<sup>`，`<var>`

`<sub>`标签将内容变为下标，`<sup>`标签将内容变为上标。它们都是行内元素，主要用于数学公式、分子式等。

```html
<p>水分子是 H<sub>2</sub>O。</p>
```

`<var>`标签表示代码或数学公式的变量。

```html
<p>勾股定理是
  <var>a</var><sup>2</sup> + <var>b</var><sup>2</sup> = <var>c</var><sup>2</sup>
。</p>
```

## `<u>`，`<s>`

`<u>`标签是一个行内元素，表示对内容提供某种注释，提醒用户这里可能有问题，基本上只用来表示拼写错误。浏览器默认以下划线渲染内容。

```html
<p>
一个容易写错的成语是把<em>安分守己</em>写成<u>安份守己</u>。
</p>
```

上面代码中，`<u>`提示用户这是一个拼写错误，“安份守己”的下方会有一个下划线。

注意，`<u>`会产生下划线，由于链接也默认带有下划线，所以必须非常小心使用`<u>`标签，避免用户误以为可以点击。万一确有必要使用，最好使用 CSS 改变`<u>`的默认样式。

`<s>`标签是一个行内元素，为内容加上删除线。

```html
<p>今天特价商品：<s>三文鱼</s>（售完）</p>
```

上面代码中，“三文鱼”会有一根删除线。

## `<blockquote>`，`<cite>`，`<q>`

`<blockquote>`是一个块级标签，表示引用他人的话。浏览器会在样式上，与正常文本区别显示。

```html
<blockquote cite="https://quote.example.com">
  <p>天才就是 1% 的天赋和99%的汗水。</p>
</blockquote>
```

`<blockquote>`标签有一个`cite`属性，它的值是一个网址，表示引言来源，不会显示在网页上。

`<cite>`标签表示引言出处或者作者，浏览器默认使用斜体显示这部分内容。

```html
<blockquote cite="https://quote.example.com">
  <p>天才就是 1% 的天赋和99%的汗水。</p>
</blockquote>
<cite>-- 爱迪生</cite>
```

`<cite>`不一定跟`<blockquote>`一起使用。如果文章中提到资料来源，也可以单独使用。

```html
<p>更多资料请看<cite>维基百科</cite>。</p>
```

`<q>`是一个行内标签，也表示引用。它与`<blockquote>`的区别，就是它不会产生换行。

```html
<p>
  莎士比亚的《哈姆雷特》有一句著名的台词：
  <q cite="https://quote.example.com">活着还是死亡，这是一个问题。</q>
</p>
```

上面例子中，引言部分跟前面的说明部分是在同一行里面。

另外，跟`<blockquote>`一样，`<q>`也有`cite`属性，表示引言的来源网址。

注意，浏览器默认会斜体显示`<q>`的内容，并且会自动添加半角的双引号。所以，引用中文内容时要小心。

## `<code>`

`<code>`标签是一个行内元素，表示标签内容是计算机代码，浏览器默认会以等宽字体显示。

```html
<code>alert()</code>的作用是让网页弹出一个提示框。
```

如果要表示多行代码，`<code>`标签必须放在`<pre>`内部。`<code>`本身仅表示一行代码。

```html
<pre>
<code>
  let a = 1;
  console.log(a);
</code>
</pre>
```

## `<kbd>`，`<samp>`

`<kbd>`标签是一个行内元素，原意是用户从键盘输入的内容，现在扩展到各种输入，包括语音输入。浏览器默认以等宽字体显示标签内容。

```html
<p>Windows 可以按下 <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>Del</kbd> 重启。</p>
```

`<kbd>`可以嵌套，方便指定样式。

```html
<p>Windows 可以按下
<kbd> <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>Del</kbd> </kbd>
重启。</p>
```

`<samp>`标签是一个行内元素，表示计算机程序输出内容的一个例子。浏览器默认以等宽字体显示。

```html
<p>如果使用没有定义的变量，浏览器会报错：
<samp>Uncaught ReferenceError: foo is not defined</samp>。
</p>
```

## `<mark>`

`<mark>`是一个行内标签，表示突出显示的内容。Chrome 浏览器默认会以亮黄色背景，显示该标签的内容。

```html
<p>我们讨论以后决定，<mark>运行会在下周三举办</mark>。</p>
```

`<mark>`很适合在引用的内容（`<q>`或`<blockquote>`）中，标记出需要关注的句子。

```html
<blockquote>
床前明月光，疑是地上霜。<mark>举头望明月，低头思故乡。</mark>
</blockquote>
```

除了标记感兴趣的文本，`<mark>`还可以用于在搜索结果中，标记出匹配的关键词。

注意，不要只为了高亮的效果，而使用这个标签，因为不能保证浏览器的处理方式。如果要保证高亮，还是要使用 CSS 样式。

## `<small>`

`<small>`是一个行内标签，浏览器会将它包含的内容，以小一号的字号显示，不需要使用 CSS 样式。它通常用于文章附带的版权信息或法律信息。

```html
<p>文章正文</p>
<p><small>以上内容使用创意共享许可证。</small></p>
```

## `<time>`，`<data>`

`<time>`是一个行内标签，为跟时间相关的内容提供机器可读的格式。

```html
<p>运动会预定<time datetime="2015-06-10">下周三</time>举行。</p>
```

上面代码中，`<time>`表示下周三的具体日期。这方便搜索引擎抓取，或者下一步的其他处理。

`<time>`的`datetime`属性，用来指定机器可读的日期，可以有多种格式。

- 有效年份：`2011`
- 有效月份：`2011-11`
- 有效日期：`2011-11-18`
- 无年份的日期：`11-18`
- 年度的第几周：`2011-W47`
- 有效时间：`14:54`、`14:54:39`、`14:54:39.929`
- 日期和时间：`2011-11-18T14:54:39.929`

```html
<p>音乐会在<time datetime="20:00">晚上八点</time>开始。</p>
```

`<data>`标签与`<time>`类似，也是提供机器可读的内容，但是用于非时间的场合。

```html
<p>本次马拉松比赛第一名是<data value="39">张三</data></p>。
```

上面代码中，选手的机读数据就放在`<data>`标签的`value`属性。

## `<address>`

`<address>`标签是一个块级元素，表示某人或某个组织的联系方式。

```html
<p>作者的联系方式：</p>

<address>
  <p><a href="mailto:foo@example.com">foo@example.com</a></p>
  <p><a href="tel:+555-34762301">+555-34762301</a></p>
</address>
```

该标签有几个注意点。

（1）如果是文章里提到的地址（比如提到搬家前的地址），而不是联系信息，不要使用`<address>`标签。

（2）`<address>`的内容不得有非联系信息，比如发布日期。

（3）`<address>`不能嵌套，并且内部不能有标题标签（`<h1>`~`<h6>`），也不能有`<article>`、`<aside>`、`<section>`、`<nav>`、`<header>`、`<footer>`等标签。

（4）通常，`<address>`会放在`<footer>`里面，下面是一个例子。

```html
<footer>
  <address>
    文章的相关问题请联系<a href="mailto:zhangsan@example.com">张三
    McClure</a>。
  </address>
</footer>
```

## `<abbr>`

`<abbr>`标签是一个行内元素，表示标签内容是一个缩写。它的`title`属性给出缩写的完整形式，或者缩写的描述。鼠标悬停在该元素上方时，`title`属性值作为提示，会完整显示出来。

```html
<abbr title="HyperText Markup Language">HTML</abbr>
```

注意，某些浏览器可能对该标签提供圆点下划线。

## `<ins>`，`<del>`

`<ins>`标签是一个行内元素，表示原始文档添加（insert）的内容。`<del>`与之类似，表示删除（delete）的内容。它们通常用于展示文档的删改。

```html
<del><p>会议定于5月8日举行。</p></del>
<ins><p>会议定于5月9日举行。</p></ins>
```

浏览器默认为`<del>`标签的内容加上删除线，为`<ins>`标签的内容加上下划线。

这两个标签都有以下属性。

- `cite`：该属性的值是一个 URL，表示该网址可以解释本次删改。
- `datetime`：表示删改发生的时间。

```html
<ins cite="./why.html" datetime="2018-05">
  <p>项目比原定时间提前两周结束。</p>
</ins>
```

## `<dfn>`

`<dfn>`是一个行内元素，表示标签内容是一个术语（definition），本段或本句包含它的定义。

```html
<p>
通过 TCP/IP 协议连接的全球性计算机网络，叫做 <dfn>Internet</dfn>。
</p>
```

为了脚本操作的方便，可以把术语的定义写入`<dfn>`标签的`title`属性。

```html
<p>
通过 TCP/IP 协议连接的全球性计算机网络，叫做
<dfn title="全球性计算机网络">Internet</dfn>。
</p>
```

上面代码中，`title`属性的一个作用是，鼠标悬浮的时候，术语的解释会以提示的形式显示出来。

某些时候，术语本身是一个缩写，这时`<dfn>`和`<abbr>`可以结合使用。

```html
<p>
<dfn><abbr title="acquired immune deficiency syndrome">AIDS</abbr></dfn>
的全称是获得性免疫缺陷综合征。
</p>
```

## `<ruby>`

`<ruby>`标签表示文字的语音注释，主要用于东亚文字，比如汉语拼音和日语的片假名。它默认将语音注释，以小字体显示在文字的上方。

```html
<ruby>
汉<rp>(</rp><rt>han</rt><rp>)</rp>
字<rp>(</rp><rt>zi</rt><rp>)</rp>
</ruby>
```

上面代码的渲染结果是，`汉字`上方有小字体的拼音`han zi`。

`<ruby>`标签是一个行内元素，也是一个容器标签。如果要使用语音注释，就必须把文字和注释都放在这个标签里面。

`<ruby>`的内部还有许多配套的标签。

**（1）`<rp>`**

`<rp>`标签的用处，是为不支持语音注释的浏览器，提供一个兼容方案。对于那些支持语音注释的浏览器，该标签的内容不显示。

`<rp>`标签一般用于放置圆括号，如果遇到不支持的浏览器，就会将语音注释显示在括号里面。

```html
<ruby>
汉<rp>(</rp><rt>han</rt><rp>)</rp>
字<rp>(</rp><rt>zi</rt><rp>)</rp>
</ruby>
```

上面代码在不支持语音注释的浏览器中，渲染结果为`汉(han)字(zi)`。遇到支持语音注释的浏览器，就不会显示圆括号。

**（2）`<rt>`**

`<rt>`标签用于放置语音注释。

**（3）`<rb>`**

`<rb>`标签用于划分文字单位，与语音注释一一对应。

```html
<ruby>
  <rb>汉</rb><rb>字</rb>
  <rp>(</rp>
  <rt>han</rt>
  <rt>zi</rt>
  <rp>)</rp>
</ruby>
```

上面例子中，`汉字`这两个字是写在一起的，`<rb>`标签用于每个字划分出来，跟`<rt>`标签一一对应。

注意，Chrome 浏览器目前不支持这个标签。

**（4）`<rbc>`，`<rtc>`**

`<rbc>`标签表示一组文字，通常包含多个`<rb>`元素。`<rtc>`标签表示一组语音注释，跟`<rbc>`对应。

```html
<ruby style="ruby-position: under;">
  <rbc>
    <rb>汉</rb><rp>(</rp><rt>han</rt><rp>)</rp>
    <rb>字</rb><rp>(</rp><rt>zi</rt><rp>)</rp>
  </rbc>
  <rtc style="ruby-position: over;">
    <rp>(</rp><rt>Chinese</rt><rp>)</rp>
  </rtc>
</ruby>
```

上面例子中，`汉字`这两个字有两组语音注释，分别是汉语拼音与英语。一组语音注释放在`<rbc>`标签中，另一组语音注释放在`<rtc>`，用来对应`<rbc>`。同时，分别使用`style`属性，指定汉语拼音显示在文字下方，英语显示在文字上方。

注意，Chrome 浏览器目前不支持这两个标签。

## `<bdo>`，`<bdi>`

大部分文字的阅读方向是从左到右，但是有些文字的方向是从右到左，比如阿拉伯语、希伯来语等。`<bdo>`标签是一个行内元素，表示文字方向与网页主体内容的方向不一致。

```html
<p>床前明月光，<bdo dir="rtl">霜上地是疑</bdo>。</p>
```

上面代码中，`<bdo>`标签里面的文字，会以相反的方向渲染，结果就是“床前明月光，疑是地上霜”。

`<bdo>`的`dir`属性，指定具体的文字方向。它有两个值，`ltr`表示从左到右，`rtl`表示从右到左。

`<bdi>`标签用于不确定文字方向的情况。比如，网页有一个部分是用户输入的内容，但是不知道输入内容的文字方向。这种情况就可以使用`<bdi>`标签，告诉浏览器，不确定文字的方向，由浏览器自己决定。

```html
<p><bdi>床前明月光，疑是地上霜。</bdi></p>
```