HTML标签

表单标签

表单(form)是用户输入信息与网页互动的一种形式。大多数情况下,用户提交的信息会发给服务器,比如网站的搜索栏就是表单。

表单由一种或多种的小部件组成,比如输入框、按钮、单选框或复选框。这些小部件称为控件(controls)。

<form>

简介

<form>标签用来定义一个表单,所有表单内容放到这个容器元素之中。

<form>
  <!-- 各种表单控件-->
</form>

上面代码就是表单的基本形式。

下面是一个比较常见的例子。

<form action="https://example.com/api" method="post">
  <label for="POST-name">用户名:</label>
  <input id="POST-name" type="text" name="user">
  <input type="submit" value="提交">
</form>

上面代码就是一个表单,一共包含三个控件:一个<label>标签,一个文本输入框,一个提交按钮。其中,文本输入框的name属性是user,表示将向服务器发送一个键名为user的键值对,键值就是这个控件的value属性,等于用户输入的值。

用户在文本输入框里面,输入用户名,比如foobar,然后点击提交按钮,浏览器就会向服务器https://example.com/api发送一个 POST 请求,发送user=foobar这样一段数据。

<form>有以下属性。

  • accept-charset:服务器接受的字符编码列表,使用空格分隔,默认与网页编码相同。
  • action:服务器接收数据的 URL。
  • autocomplete:如果用户没有填写某个控件,浏览器是否可以自动填写该值。它的可能取值分别为off(不自动填写)和on(自动填写)。
  • method:提交数据的 HTTP 方法,可能的值有post(表单数据作为 HTTP 数据体发送),get(表单数据作为 URL 的查询字符串发送),dialog(表单位于<dialog>内部使用)。
  • enctype:当method属性等于post时,该属性指定提交给服务器的 MIME 类型。可能的值为application/x-www-form-urlencoded(默认值),multipart/form-data(文件上传的情况),text/plain
  • name:表单的名称,应该在网页中是唯一的。注意,如果一个控件没有设置name属性,那么这个控件的值就不会作为键值对,向服务器发送。
  • novalidate:布尔属性,表单提交时是否取消验证。
  • target:在哪个窗口展示服务器返回的数据,可能的值有_self(当前窗口),_blank(新建窗口),_parent(父窗口),_top(顶层窗口),<iframe>标签的name属性(即表单返回结果展示在<iframe>窗口)。

enctype 属性

<form>表单的enctype属性,指定了采用 POST 方法提交数据时,浏览器给出的数据的 MIME 类型。该属性可以取以下值。

(1)application/x-www-form-urlencoded

application/x-www-form-urlencoded是默认类型,控件名和控件值都要转义(空格转为+号,非数字和非字母转为%HH的形式,换行转为CR LF),控件名和控件值之间用=分隔。控件按照出现顺序排列,控件之间用&分隔。

(2)multipart/form-data

multipart/form-data主要用于文件上传。这个类型上传大文件时,会将文件分成多块传送,每一块的 HTTP 头信息都有Content-Disposition属性,值为form-data,以及一个name属性,值为控件名。

Content-Disposition: form-data; name="mycontrol"

下面是上传文件的表单。

<form action="https://example.com/api"
      enctype="multipart/form-data"
      method="post">
  用户名:<input type="text" name="submit-name"><br>
  文件:<input type="file" name="files"><br>
  <input type="submit" value="上传"> <input type="reset" value="清除">
</form>

上面代码中,输入用户名Larry,选中一个file1.txt文件,然后点击“上传”。浏览器发送的实际数据如下。

Content-Type: multipart/form-data; boundary=--AaB03x

--AaB03x
Content-Disposition: form-data; name="submit-name"

Larry
--AaB03x
Content-Disposition: form-data; name="files"; filename="file1.txt"
Content-Type: text/plain

... contents of file1.txt ...
--AaB03x--

上面代码中,浏览器将这个表单发成多个数据块。最上面使用Content-Type字段告诉服务器,数据格式是multipart/form-data(即多个数据块),每个数据块的分隔标志是--AaB03x。每个数据块的第一行是Content-Disposition,其中的name字段表示这个数据块的控件名,数据体则是该控件的数据值,比如第一个数据块的name属性是submit-name控件,数据体是该控件的值Larry。第二个数据块是控件files,由于该控件是上传文件,所以还要用filename属性给出文件名file1.txt,数据体是file1.txt的内容。

<fieldset><legend>

<fieldset>标签是一个块级容器标签,表示控件的集合,用于将一组相关控件组合成一组。

<form>
  <fieldset>
    <p>年龄:<input type="text" name="age"></p>
    <p>性别:<input type="text" name="gender"></p>
  </fieldset>
</form>

上面代码中,两个输入框是一组,它们的外面会显示一个方框。

<fieldset>有以下属性。

  • disabled:布尔属性,一旦设置会使得<fieldset>内部包含的控件都不可用,都变成灰色状态。
  • form:指定控件组所属的<form>,它的值等于<form>id属性。
  • name:该控件组的名称。

<legend>标签用来设置<fieldset>控件组的标题,通常是<fieldset>内部的第一个元素,会嵌入显示在控件组的上边框里面。

<fieldset>
  <legend>学生情况登记</legend>
  <p>年龄:<input type="text" name="age"></p>
  <p>性别:<input type="text" name="gender"></p>
</fieldset>

上面代码中,这个控件组的标题会,嵌入显示在<fieldset>的上边框。

<label>

<label>标签是一个行内元素,提供控件的文字说明,帮助用户理解控件的目的。

<label for="user">用户名:</label>
<input type="text" name="user" id="user">

上面代码中,输入框前面会有文字说明“用户名:”。

<label>的一大优势是增加了控件的可用性。有些控件比较小(比如单选框),不容易点击,那么点击对应的<label>标签,也能选中该控件。点击<label>,就相当于控件本身的click事件。

<label>for属性关联相对应的控件,它的值是对应控件的id属性。所以,控件最好设置id属性。

控件也可以放在<label>之中,这时不需要for属性和id属性。

<label>用户名:
  <input type="text" name="user">
</label>

<label>的属性如下。

  • for:关联控件的id属性。
  • form:关联表单的id属性。设置了该属性后,<label>可以放置在页面的任何位置,否则只能放在<form>内部。

一个控件可以有多个关联的<label>标签。

<label for="username">用户名:</label>
<input type="text" id="username" name="username">
<label for="username"><abbr title="required">*</abbr></label>

上面代码中,<input>有两个关联的<label>

<input>

简介

<input>标签是一个行内元素,用来接收用户的输入。它是一个单独使用的标签,没有结束标志。

它有多种类型,取决于type属性的值,默认值是text,表示一个输入框。

<input>
<!-- 等同于 -->
<input type="text">

上面代码会生成一个单行的输入框,用户可以在里面输入文本。

<input>的属性非常多,有些属性是某个类型专用的,放在下文的“类型”部分介绍。这里介绍一些所有类型的共同属性。

  • autofocus:布尔属性,是否在页面加载时自动获得焦点。
  • disabled:布尔属性,是否禁用该控件。一旦设置,该控件将变灰,用户可以看到,但是无法操作。
  • form:关联表单的id属性。设置了该属性后,控件可以放置在页面的任何位置,否则只能放在<form>内部。
  • list:关联的<datalist>id属性,设置该控件相关的数据列表,详见后文。
  • name:控件的名称,主要用于向服务器提交数据时,控件键值对的键名。注意,只有设置了name属性的控件,才会向服务器提交,不设置就不会提交。
  • readonly:布尔属性,是否为只读。
  • required:布尔属性,是否为必填。
  • type:控件类型,详见下文。
  • value:控件的值。

类型

type属性决定了<input>的形式。该属性可以取以下值。

(1)text

type="text"是普通的文本输入框,用来输入单行文本。如果用户输入换行符,换行符会自动从输入中删除。

<input type="text" id="name" name="name" required
       minlength="4" maxlength="8" size="10">

text输入框有以下配套属性。

  • maxlength:可以输入的最大字符数,值为一个非负整数。
  • minlength:可以输入的最小字符数,值为一个非负整数,且必须小于maxlength
  • pattern:用户输入必须匹配的正则表达式,比如要求用户输入4个~8个英文字符,可以写成pattern="[a-z]{4,8}"。如果用户输入不符合要求,浏览器会弹出提示,不会提交表单。
  • placeholder:输入字段为空时,用于提示的示例值。只要用户没有任何字符,该提示就会出现,否则会消失。
  • readonly:布尔属性,表示该输入框是只读的,用户只能看,不能输入。
  • size:表示输入框的显示长度有多少个字符宽,它的值是一个正整数,默认等于20。超过这个数字的字符,必须移动光标才能看到。
  • spellcheck:是否对用户输入启用拼写检查,可能的值为truefalse

(2)search

type="search"是一个用于搜索的文本输入框,基本等同于type="text"。某些浏览器会在输入的时候,在输入框的尾部显示一个删除按钮,点击就会删除所有输入,让用户从头开始输入。

下面是一个例子。

<form>
  <input type="search" id="mySearch" name="q"
    placeholder="输入搜索词……" required>
  <input type="submit" value="搜索">
</form>

(3)button

type="button"是没有默认行为的按钮,通常脚本指定click事件的监听函数来使用。

<input type="button" value="点击">

建议尽量不使用这个类型,而使用<button>标签代替,一则语义更清晰,二则<button>标签内部可以插入图片或其他 HTML 代码。

(4)submit

type="submit"是表单的提交按钮。用户点击这个按钮,就会把表单提交给服务器。

<input type="submit" value="提交">

如果不指定value属性,浏览器会在提交按钮上显示默认的文字,通常是Submit

该类型有以下配套属性,用来覆盖<form>标签的相应设置。

  • formaction:提交表单数据的服务器 URL。
  • formenctype:表单数据的编码类型。
  • formmethod:提交表单使用的 HTTP 方法(getpost)。
  • formnovalidate:一个布尔值,表示数据提交给服务器之前,是否要忽略表单验证。
  • formtarget:收到服务器返回的数据后,在哪一个窗口显示。

(5)image

type="image"表示将一个图像文件作为提交按钮,行为和用法与type="submit"完全一致。

<input type="image" alt="登陆" src="login-button.png">

上面代码中,图像文件是一个可以点击的按钮,点击后会提交数据到服务器。

该类型有以下配套属性。

  • alt:图像无法加载时显示的替代字符串。
  • src:加载的图像 URL。
  • height:图像的显示高度,单位为像素。
  • width:图像的显示宽度,单位为像素。
  • formaction:提交表单数据的服务器 URL。
  • formenctype:表单数据的编码类型。
  • formmethod:提交表单使用的 HTTP 方法(getpost)。
  • formnovalidate:一个布尔值,表示数据提交给服务器之前,是否要忽略表单验证。
  • formtarget:收到服务器返回的数据后,在哪一个窗口显示。

用户点击图像按钮提交时,会额外提交两个参数xy到服务器,表示鼠标的点击位置,比如x=52&y=55x是横坐标,y是纵坐标,都以图像左上角作为原点(0, 0)。如果图像按钮设置了name属性,比如name="position",那么将以该值作为坐标的前缀,比如position.x=52&position.y=55。这个功能通常用来地图类型的操作,让服务器知道用户点击了地图的哪个部分。

(6)reset

type="reset"是一个重置按钮,用户点击以后,所有表格控件重置为初始值。

<input type="reset" value="重置">

如果不设置value属性,浏览器会在按钮上面加上默认文字,通常是Reset

这个控件用处不大,用户点错了还会使得所有已经输入的值都被重置,建议不要使用。

(7)checkbox

type="checkbox"是复选框,允许选择或取消选择该选项。

<input type="checkbox" id="agreement" name="agreement" checked>
<label for="agreement">是否同意</label>

上面代码会在文字前面,显示一个可以点击的选择框,点击可以选中,再次点击可以取消。上面代码中,checked属性表示默认选中。

value属性的默认值是on。也就是说,如果没有设置value属性,以上例来说,选中复选框时,会提交agreement=on。如果没有选中,提交时不会有该项。

多个相关的复选框,可以放在<fieldset>里面。

<fieldset>
  <legend>你的兴趣</legend>
  <div>
    <input type="checkbox" id="coding" name="interest" value="coding">
    <label for="coding">编码</label>
  </div>
  <div>
    <input type="checkbox" id="music" name="interest" value="music">
    <label for="music">音乐</label>
  </div>
</fieldset>

上面代码中,如果用户同时选中两个复选框,提交的时候就会有两个name属性,比如interest=coding&interest=music

(8)radio

type="radio"是单选框,表示一组选择之中,只能选中一项。单选框通常为一个小圆圈,选中时会被填充或突出显示。

<fieldset>
  <legend>性别</legend>
  <div>
    <input type="radio" id="male" name="gender" value="male">
    <label for="male"></label>
  </div>
  <div>
    <input type="radio" id="female" name="gender" value="female">
    <label for="female"></label>
  </div>
</fieldset>

上面代码中,性别只能在两个选项之中,选择一项。

注意,多个单选框的name属性的值,应该都是一致的。提交到服务器的就是选中的那个值。

该类型的配套属性如下。

  • checked:布尔属性,表示是否默认选中当前项。
  • value:用户选中该项时,提交到服务器的值,默认为on

(9)email

type="email"是一个只能输入电子邮箱的文本输入框。表单提交之前,浏览器会自动验证是否符合电子邮箱的格式,如果不符合就会显示提示,无法提交到服务器。

<input type="email" pattern=".+@foobar.com" size="30" required>

上面代码会生成一个必填的文本框,只能输入后缀为foobar.com的邮箱地址。

该类型有一个multiple的布尔属性,一旦设置,就表示该输入框可以输入多个逗号分隔的电子邮箱。

<input id="emailAddress" type="email" multiple required>

注意,如果同时设置了multiple属性和required属性,零个电子邮箱是允许的,也就是该输入框允许为空。

该类型的配套属性如下。

  • maxlength:可以输入的最大字符数。
  • minlength:可以输入的最少字符数。
  • multiple:布尔属性,是否允许输入多个以逗号分隔的电子邮箱。
  • pattern:输入必须匹配的正则表达式。
  • placeholder:输入为空时的显示文本。
  • readonly:布尔属性,该输入框是否只读。
  • size:一个非负整数,表示输入框的显示长度为多少个字符。
  • spellcheck:是否对输入内容启用拼写检查,可能的值为truefalse

该类型还可以搭配<datalist>标签,提供输入的备选项。

<input type="email" size="40" list="defaultEmails">

<datalist id="defaultEmails">
  <option value="jbond007@mi6.defence.gov.uk">
  <option value="jbourne@unknown.net">
  <option value="nfury@shield.org">
  <option value="tony@starkindustries.com">
  <option value="hulk@grrrrrrrr.arg">
</datalist>

上面代码中,输入焦点进入输入框以后,会显示一个下拉列表,里面有五个参考项,供用户参考。

(10)password

type="password"是一个密码输入框。用户的输入会被遮挡,字符通常显示星号(*)或点(·)。

<input type="password" id="pass" name="password"
           minlength="8" required>

浏览器对该类型输入框的显示,会有所差异。一种常见的处理方法是,用户每输入一个字符,先在输入框里面显示一秒钟,然后再遮挡该字符。

如果用户输入内容包含换行符(U+000A)和回车符(U+000D),浏览器会自动将这两个字符过滤掉。

该类型的配套属性如下。

  • maxlength:可以输入的最大字符数。
  • minlength:可以输入的最少字符数。
  • pattern:输入必须匹配的正则表达式。
  • placeholder:输入为空时的显示文本。
  • readonly:布尔属性,该输入框是否只读。
  • size:一个非负整数,表示输入框的显示长度为多少个字符。
  • autocomplete:是否允许自动填充,可能的值有on(允许自动填充)、off(不允许自动填充)、current-password(填入当前网站保存的密码)、new-password(自动生成一个随机密码)。
  • inputmode:允许用户输入的数据类型,可能的值有none(不使用系统输入法)、text(标准文本输入)、decimal(数字,包含小数)、numeric(数字0-9)等。

(11)file

type="file"是一个文件选择框,允许用户选择一个或多个文件,常用于文件上传功能。

<input type="file"
       id="avatar" name="avatar"
       accept="image/png, image/jpeg">

该类型有以下属性。

  • accept:允许选择的文件类型,使用逗号分隔,可以使用 MIME 类型(比如image/jpeg),也可以使用后缀名(比如.doc),还可以使用audio/*(任何音频文件)、video/*(任何视频文件)、image/*(任何图像文件)等表示法。
  • capture:用于捕获图像或视频数据的源,可能的值有user(面向用户的摄像头或麦克风),environment(外接的摄像头或麦克风)。
  • multiple:布尔属性,是否允许用户选择多个文件。

(12)hidden

type="hidden"是一个不显示在页面的控件,用户无法输入它的值,主要用来向服务器传递一些隐藏信息。比如,CSRF 攻击会伪造表单数据,那么使用这个控件,可以为每个表单生成一个独一无二的隐藏编号,防止伪造表单提交。

<input id="prodId" name="prodId" type="hidden" value="xm234jq">

上面这个控件,页面上是看不见的。用户提交表单的时候,浏览器会将prodId=xm234jq发给服务器。

(13)number

type="number"是一个数字输入框,只能输入数字。浏览器通常会在输入框的最右侧,显示一个可以点击的上下箭头,点击向上箭头,数字会递增,点击向下箭头,数字会递减。

<input type="number" id="tentacles" name="tentacles"
       min="10" max="100">

上面代码指定数字输入框,最小可以输入10,最大可以输入100。

该类型可以接受任何数值,包括小数和整数。可以通过step属性,限定只接受整数。

该类型有以下配套属性。

  • max:允许输入的最大数值。
  • min:允许输入的最小数值。
  • placeholder:用户输入为空时,显示的示例值。
  • readonly:布尔属性,表示该控件是否为只读。
  • step:点击向上和向下箭头时,数值每次递减的步长值。如果用户输入的值,不符合步长值的设定,浏览器会自动四舍五入到最近似的值。默认的步长值是1,如果初始的value属性设为1.5,那么点击向上箭头得到2.5,点击向下箭头得到0.5

(14)range

type="range"是一个滑块,用户拖动滑块,选择给定范围之中的一个数值。因为拖动产生的值是不精确的,如果需要精确数值,不建议使用这个控件。常见的例子是调节音量。

<input type="range" id="start" name="volume"
         min="0" max="11">

上面代码会产生一个最小值为0、最大值为11的滑块区域。用户拖动滑块,选择想要的音量。

该类型的配套属性如下,用法与type="number"一致。

  • max:允许的最大值,默认为100。
  • min:允许的最小值,默认为0。
  • step:步长值,默认为1。

value属性的初始值就是滑块的默认位置。如果没有设置value属性,滑块默认就会停在最大值和最小值中间。如果max属性、min属性、value属性都没有设置,那么value属性为50。

该类型与<datalist>标签配合使用,可以在滑动区域产生刻度。

<input type="range" list="tickmarks">

<datalist id="tickmarks">
  <option value="0" label="0%">
  <option value="10">
  <option value="20">
  <option value="30">
  <option value="40">
  <option value="50" label="50%">
  <option value="60">
  <option value="70">
  <option value="80">
  <option value="90">
  <option value="100" label="100%">
</datalist>

上面代码会在0~100之间产生11个刻度。其中,0%50%100%三个位置会有文字提示,不过浏览器很可能不支持。

注意,浏览器生成的都是水平滑块。如果想要生成垂直滑块,可以使用 CSS 改变滑块区域的方向。

(15)url

type="url"是一个只能输入网址的文本框。提交表单之前,浏览器会自动检查网址格式是否正确,如果不正确,就会无法提交。

<input type="url" name="url" id="url"
       placeholder="https://example.com"
       pattern="https://.*" size="30"
       required>

上面代码的pattern属性指定输入的网址只能使用 HTTPS 协议。

注意,该类型规定,不带有协议的网址是无效的,比如foo.com是无效的,http://foo.com是有效的。

该类型的配套属性如下。

  • maxlength:允许的最大字符数。
  • minlength:允许的最少字符串。
  • pattern:输入内容必须匹配的正则表达式。
  • placeholder:输入为空时显示的示例文本。
  • readonly:布尔属性,表示该控件的内容是否只读。
  • size:一个非负整数,表示该输入框显示宽度为多少个字符。
  • spellcheck:是否启动拼写检查,可能的值为true(启用)和false(不启用)。

该类型与<datalist>标签搭配使用,可以形成下拉列表供用户选择。随着用户不断键入,会缩小显示范围,只显示匹配的备选项。

<input id="myURL" name="myURL" type="url"
       list="defaultURLs">

<datalist id="defaultURLs">
  <option value="https://developer.mozilla.org/" label="MDN Web Docs">
  <option value="http://www.google.com/" label="Google">
  <option value="http://www.microsoft.com/" label="Microsoft">
  <option value="https://www.mozilla.org/" label="Mozilla">
  <option value="http://w3.org/" label="W3C">
</datalist>

上面代码中,<option>label属性表示文本标签,显示在备选下拉框的右侧,网址显示在左侧。

(16)tel

type="tel"是一个只能输入电话号码的输入框。由于全世界的电话号码格式都不相同,因此浏览器没有默认的验证模式,大多数时候需要自定义验证。

<input type="tel" id="phone" name="phone"
       pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}"
       required>

<small>Format: 123-456-7890</small>

上面代码定义了一个只能输入10位电话号码的输入框。

该类型的配套属性如下。

  • maxlength:允许的最大字符数。
  • minlength:允许的最少字符串。
  • pattern:输入内容必须匹配的正则表达式。
  • placeholder:输入为空时显示的示例文本。
  • readonly:布尔属性,表示该控件的内容是否只读。
  • size:一个非负整数,表示该输入框显示宽度为多少个字符。

(17)color

type="color"是一个选择颜色的控件,它的值一律都是#rrggbb格式。

<input type="color" id="background" name="background"
           value="#e66465">

上面代码在 Chrome 浏览器中,会显示一个#e66465的色块。点击色块,就会出现一个拾色器,供用户选择颜色。

如果没有指定value属性的初始值,默认值为#000000(黑色)。

(18)date

type="date"是一个只能输入日期的输入框,用户可以输入年月日,但是不能输入时分秒。输入格式是YYYY-MM-DD

<input type="date" id="start" name="start"
       value="2018-07-22"
       min="2018-01-01" max="2018-12-31">

上面代码会显示一个输入框,默认日期是2018年7月22日。用户点击以后,会日期选择器,供用户选择新的日期。

该类型有以下配套属性。

  • max:可以允许的最晚日期,格式为yyyy-MM-dd
  • min:可以允许的最早日期,格式为yyyy-MM-dd
  • step:步长值,一个数字,以天为单位。

(19)time

type="time"是一个只能输入时间的输入框,可以输入时分秒,不能输入年月日。日期格式是24小时制的hh:mm,如果包括秒数,格式则是hh:mm:ss。日期选择器的形式则随浏览器不同而不同。

<input type="time" id="appt" name="appt"
       min="9:00" max="18:00" required>

<small>营业时间上午9点到下午6点</small>

该类型有以下配套属性。

  • max:允许的最晚时间。
  • min:允许的最早时间。
  • readonly:布尔属性,表示用户是否不可以编辑时间。
  • step:步长值,单位为秒。
<input id="appt" type="time" name="appt" step="2">

上面代码中,调节控件的话,时间每次改变的幅度是2秒钟。

(20)month

type="month"是一个只能输入年份和月份的输入框,格式为YYYY-MM

<input type="month" id="start" name="start"
       min="2018-03" value="2018-05">

该类型有以下配套属性。

  • max:允许的最晚时间,格式为yyyy-MM
  • min:允许的最早时间,格式为yyyy-MM
  • readonly:布尔属性,表示用户是否不可以编辑时间。
  • step:步长值,单位为月。

(21)week

type="week"是一个输入一年中第几周的输入框。格式为yyyy-Www,比如2018-W18表示2018年第18周。

<input type="week" name="week" id="camp-week"
       min="2018-W18" max="2018-W26" required>

该类型有以下配套属性。

  • max:允许的最晚时间,格式为yyyy-Www
  • min:允许的最早时间,格式为yyyy-Www
  • readonly:布尔属性,表示用户是否不可以编辑时间。
  • step:步长值,单位为周。

(22)datetime-local

type="datetime-local"是一个时间输入框,让用户输入年月日和时分,格式为yyyy-MM-ddThh:mm。注意,该控件不支持秒。

<input type="datetime-local" id="meeting-time"
       name="meeting-time" value="2018-06-12T19:30"
       min="2018-06-07T00:00" max="2018-06-14T00:00">

该类型有以下配套属性。

  • max:允许的最晚时间,格式为yyyy-MM-ddThh:mm
  • min:允许的最早时间,格式为yyyy-MM-ddThh:mm
  • step:步长值,单位为秒,默认值是60。

<button>

<button>标签会生成一个可以点击的按钮,没有默认行为,通常需要用type属性或脚本指定按钮的功能。

<button>点击</button>

上面代码会产生一个按钮,上面的文字就是“点击”。

<button>内部不仅放置文字,还可以放置图像,这可以形成图像按钮。

<button name="search" type="submit">
  <img src="search.gif">搜索
</button>

<button>具有以下属性。

  • autofocus:布尔属性,表示网页加载时,焦点就在这个按钮。网页里面只能有一个元素,具有这个属性。
  • disabled:布尔属性,表示按钮不可用,会导致按钮变灰,不可点击。
  • name:按钮的名称(与value属性配合使用),将以name=value的形式,随表单一起提交到服务器。
  • value:按钮的值(与name属性配合使用),将以name=value的形式,随表单一起提交到服务器。
  • type:按钮的类型,可能的值有三种:submit(点击后将数据提交给服务器),reset(将所有控件的值重置为初始值),button(没有默认行为,由脚本指定按钮的行为)。
  • form:指定按钮关联的<form>表单,值为<form>id属性。如果省略该属性,默认关联按钮所在父表单。
  • formaction:数据提交到服务器的目标 URL,会覆盖<form>元素的action属性。
  • formenctype:数据提交到服务器的编码方式,会覆盖<form>元素的enctype属性。可能的值有三种:application/x-www-form-urlencoded(默认值),multipart/form-data(只用于文件上传),text/plain
  • formmethod:数据提交到服务器使用的 HTTP 方法,会覆盖<form>元素的method属性,可能的值为postget
  • formnovalidate:布尔属性,数据提交到服务器时关闭本地验证,会覆盖<form>元素的novalidate属性。
  • formtarget:数据提交到服务器后,展示服务器返回数据的窗口,会覆盖<form>元素的target属性。可能的值有_self(当前窗口),_blank(新的空窗口)、_parent(父窗口)、_top(顶层窗口)。

<select>

<select>标签用于生成一个下拉菜单。

<label for="pet-select">宠物:</label>

<select id="pet-select" name="pet-select">
  <option value="">--请选择一项--</option>
  <option value="dog"></option>
  <option value="cat"></option>
  <option value="others">其他</option>
</select>

上面代码中,<select>生成一个下拉菜单,菜单标题是“–请选择一项–”,最右侧有一个下拉箭头。点击下拉箭头,会显示三个菜单项,供用户点击选择。

下拉菜单的菜单项由<option>标签给出,每个<option>代表可以选择的一个值。选中的<option>value属性,就是<select>控件发送的服务器的值。

<option>有一个布尔属性selected,一旦设置,就表示该项是默认选中的菜单项。

<select name="choice">
  <option value="first">First Value</option>
  <option value="second" selected>Second Value</option>
  <option value="third">Third Value</option>
</select>

上面代码中,第二项Second Value是默认选中的。页面加载的时候,会直接显示在下拉菜单上。

<select>有如下属性。

  • autofocus:布尔属性,页面加载时是否自动获得焦点。
  • disabled:布尔属性,是否禁用当前控件。
  • form:关联表单的id属性。
  • multiple:布尔属性,是否可以选择多个菜单项。默认情况下,只能选择一项。一旦设置,多数浏览器会显示一个滚动列表框。用户可能需要按住Shift或其他功能键,选中多项。
  • name:控件名。
  • required:布尔属性,是否为必填控件。
  • size:设置了multiple属性时,页面显示时一次可见的行数,其他行需要滚动查看。

<option><optgroup>

<option>标签用在<select><optgroup><datalist>里面,表示一个菜单项,参见<select>的示例。

它有如下属性。

  • disabled:布尔属性,是否禁用该项。
  • label:该项的说明。如果省略,则等于该项的文本内容。
  • selected:布尔属性,是否为默认值。显然,一组菜单中,只能有一个菜单项设置该属性。
  • value:该项提交到服务器的值。如果省略,则等于该项的文本内容。

<optgroup>表示菜单项的分组,通常用在<select>内部。

<label>宠物:
  <select name="pets" multiple size="4">
    <optgroup label="四条腿的宠物">
      <option value="dog"></option>
      <option value="cat"></option>
    </optgroup>
    <optgroup label="鸟类">
      <option value="parrot">鹦鹉</option>
      <option value="thrush">画眉</option>
    </optgroup>
  </select>
</label>

上面代码中,<select>是一个下拉菜单,它的内部使用<optgroup>将菜单项分成两组。每组有自己的标题,会加粗显示,但是用户无法选中。

它的属性如下。

  • disabled:布尔设置,是否禁用该组。一旦设置,该组所有的菜单项都不可选。
  • label:菜单项分组的标题。

<datalist>

<datalist>标签是一个容器标签,用于为指定控件提供一组相关数据,通常用于生成输入提示。它的内部使用<option>,生成每个菜单项。

<label for="ice-cream-choice">冰淇淋:</label>
<input type="text" list="ice-cream-flavors" id="ice-cream-choice" name="ice-cream-choice">

<datalist id="ice-cream-flavors">
  <option value="巧克力">
  <option value="椰子">
  <option value="薄荷">
  <option value="草莓">
  <option value="香草">
</datalist>

上面代码中,<input>生成一个文本输入框,用户可以输入文本。<input>list属性指定关联的<datalist>id属性。<datalist>的数据列表用于输入建议,用户点击输入框的时候,会显示一个下拉菜单,里面是建议的输入项。并且还会自动匹配用户已经输入的字符,缩小可选的范围,比如用户输入“香”,则只会显示“香草”这一项。

注意,<option>在这里可以不需要闭合标签。

<option>标签还可以加入label属性,作为说明文字。Chrome 浏览器会将其显示在value的下一行。

<datalist id="ide">
  <option value="Brackets" label="by Adobe">
  <option value="Coda" label="by Panic">
</datalist>

上面代码的渲染结果是,Chrome 浏览器会在下拉列表显示value值(比如Brackets),然后在其下方以小字显示label值(比如by Adobe)。

<textarea>

<textarea>是一个块级元素,用来生成多行的文本框。

<textarea id="story" name="story"
          rows="5" cols="33">
这是一个很长的故事。
</textarea>

上面代码会生成一个长度为5行,宽度为33个字符的文本框。

该标签有如下属性。

  • autofocus:布尔属性,是否自动获得焦点。
  • cols:文本框的宽度,单位为字符,默认值为20。
  • disabled:布尔属性,是否禁用该控件。
  • form:关联表单的id属性。
  • maxlength:允许输入的最大字符数。如果未指定此值,用户可以输入无限数量的字符。
  • minlength:允许输入的最小字符数。
  • name:控件的名称。
  • placeholder:输入为空时显示的提示文本。
  • readonly:布尔属性,控件是否为只读。
  • required:布尔属性,控件是否为必填。
  • rows:文本框的高度,单位为行。
  • spellcheck:是否打开浏览器的拼写检查。可能的值有true(打开),default(由父元素或网页设置决定),false(关闭)。
  • wrap:输入的文本是否自动换行。可能的值有hard(浏览器自动插入换行符CR + LF,使得每行不超过控件的宽度),soft(输入内容超过宽度时自动换行,但不会加入新的换行符,并且浏览器保证所有换行符都是CR + LR,这是默认值),off(关闭自动换行,单行长度超过宽度时,会出现水平滚动条)。

<output>

<output>标签是一个行内元素,用于显示用户操作的结果。

<input type="number" name="a" value="10"> +
<input type="number" name="b" value="10"> =
<output name="result">20</output>

该标签有如下属性。

  • for:关联控件的id属性,表示为该控件的操作结果。
  • form:关联表单的id属性。
  • name:控件的名称。

<progress>

<progress>标签是一个行内元素,表示任务的完成进度。浏览器通常会将显示为进度条。

<progress id="file" max="100" value="70"> 70% </progress>

该标签有如下属性。

  • max:进度条的最大值,应该是一个大于0的浮点数。默认值为1。
  • value:进度条的当前值。它必须是0max属性之间的一个有效浮点数。如果省略了max属性,该值则必须在01之间。如果省略了value属性,则进度条会出现滚动,表明正在进行中,无法知道完成的进度。

<meter>

<meter>标签是一个行内元素,表示指示器,用来显示已知范围内的一个值,很适合用于任务的当前进度、磁盘已用空间、充电量等带有比例性质的场合。浏览器通常会将其显示为一个不会滚动的指示条。

<p>烤箱的当前温度是<meter min="200" max="500"
  value="350"> 350 度</meter></p>

上面代码会显示一个指示条,左侧表示200,右侧表示500,当前位置停留在350

注意,<meter>元素的子元素,正常情况下不会显示。只有在浏览器不支持<meter>时才会显示。

该标签有如下属性。

  • min:范围的下限,必须小于max属性。如果省略,则默认为0
  • max:范围的上限,必须大于min属性。如果省略,则默认为1
  • value:当前值,必须在min属性和max属性之间。如果省略,则默认为0
  • low:表示“低端”的上限门槛值,必须大于min属性,小于high属性和max属性。如果省略,则等于min属性。
  • high:表示“高端”的下限门槛值,必须小于max属性,大于low属性和min属性。如果省略,则等于max属性。
  • optimum:指定最佳值,必须在min属性和max属性之间。它应该与low属性和high属性一起使用,表示最佳范围。如果optimum小于low属性,则表示“低端”是最佳范围;如果大于high属性,则表示“高端”是最佳范围;如果在lowhigh之间,则表示“中间地带”是最佳范围。如果省略,则等于minmax的中间值。
  • form:关联表单的id属性。

Chrome 浏览器使用三种颜色,表示指示条所处的位置。较好情况时,当前位置为绿色;一般情况时,当前位置为黄色;较差情况时,当前位置为红色。

<meter id="fuel" name="fuel"
       min="0" max="100"
       low="33" high="66" optimum="80"
       value="50">
    at 50/100
</meter>

上面代码中,指示条可以分成三段:0 ~ 32,33 ~ 65,66 ~ 100。由于optimum属性是80,因此66 ~ 100是较好情况,33 ~ 65是一般情况,0 ~ 32是较差情况。浏览器因此会根据value属性,将当前位置显示为不同颜色,小于33时显示红色,大于65时显示绿色,两者之间显示黄色。

iframe

<iframe>标签用于在网页里面嵌入其他网页。

基本用法

<iframe>标签生成一个指定区域,在该区域中嵌入其他网页。它是一个容器元素,如果浏览器不支持<iframe>,就会显示内部的子元素。

<iframe src="https://www.example.com"
        width="100%" height="500" frameborder="0"
        allowfullscreen sandbox>
  <p><a href="https://www.example.com">点击打开嵌入页面</a></p>
</iframe>

上面的代码在当前网页嵌入https://www.example.com,显示区域的宽度是100%,高度是500像素。如果当前浏览器不支持<iframe>,则会显示一个链接,让用户点击。

浏览器普遍支持<iframe>,所以内部的子元素可以不写。

<iframe>的属性如下。

  • allowfullscreen:允许嵌入的网页全屏显示,需要全屏 API 的支持,请参考相关的 JavaScript 教程。
  • frameborder:是否绘制边框,0为不绘制,1为绘制(默认值)。建议尽量少用这个属性,而是在 CSS 里面设置样式。
  • src:嵌入的网页的 URL。
  • width:显示区域的宽度。
  • height:显示区域的高度。
  • sandbox:设置嵌入的网页的权限,详见下文。
  • importance:浏览器下载嵌入的网页的优先级,可以设置三个值。high表示高优先级,low表示低优先级,auto表示由浏览器自行决定。
  • name:内嵌窗口的名称,可以用于<a><form><base>target属性。
  • referrerpolicy:请求嵌入网页时,HTTP 请求的Referer字段的设置。参见<a>标签的介绍。

sandbox 属性

嵌入的网页默认具有正常权限,比如执行脚本、提交表单、弹出窗口等。如果嵌入的网页是其他网站的页面,你不了解对方会执行什么操作,因此就存在安全风险。为了限制<iframe>的风险,HTML 提供了sandbox属性,允许设置嵌入的网页的权限,等同于提供了一个隔离层,即“沙箱”。

sandbox可以当作布尔属性使用,表示打开所有限制。

<iframe src="https://www.example.com" sandbox>
</iframe>

sandbox属性可以设置具体的值,表示逐项打开限制。未设置某一项,就表示不具有该权限。

  • allow-forms:允许提交表单。
  • allow-modals:允许提示框,即允许执行window.alert()等会产生弹出提示框的 JavaScript 方法。
  • allow-popups:允许嵌入的网页使用window.open()方法弹出窗口。
  • allow-popups-to-escape-sandbox:允许弹出窗口不受沙箱的限制。
  • allow-orientation-lock:允许嵌入的网页用脚本锁定屏幕的方向,即横屏或竖屏。
  • allow-pointer-lock:允许嵌入的网页使用 Pointer Lock API,锁定鼠标的移动。
  • allow-presentation:允许嵌入的网页使用 Presentation API。
  • allow-same-origin:不打开该项限制,将使得所有加载的网页都视为跨域。
  • allow-scripts:允许嵌入的网页运行脚本(但不创建弹出窗口)。
  • allow-storage-access-by-user-activationsandbox属性同时设置了这个值和allow-same-origin的情况下,允许<iframe>嵌入的第三方网页通过用户发起document.requestStorageAccess()请求,经由 Storage Access API 访问父窗口的 Cookie。
  • allow-top-navigation:允许嵌入的网页对顶级窗口进行导航。
  • allow-top-navigation-by-user-activation:允许嵌入的网页对顶级窗口进行导航,但必须由用户激活。
  • allow-downloads-without-user-activation:允许在没有用户激活的情况下,嵌入的网页启动下载。

注意,不要同时设置allow-scriptsallow-same-origin属性,这将使得嵌入的网页可以改变或删除sandbox属性。

loading 属性

<iframe>指定的网页会立即加载,有时这不是希望的行为。<iframe>滚动进入视口以后再加载,这样会比较节省带宽。

loading属性可以触发<iframe>网页的懒加载。该属性可以取以下三个值。

  • auto:浏览器的默认行为,与不使用loading属性效果相同。
  • lazy<iframe>的懒加载,即将滚动进入视口时开始加载。
  • eager:立即加载资源,无论在页面上的位置如何。
<iframe src="https://example.com" loading="lazy"></iframe>

上面代码会启用<iframe>的懒加载。

有一点需要注意,如果<iframe>是隐藏的,则loading属性无效,将会立即加载。只要满足以下任一个条件,Chrome 浏览器就会认为<iframe>是隐藏的。

  • <iframe>的宽度和高度为4像素或更小。
  • 样式设为display: nonevisibility: hidden
  • 使用定位坐标为负X或负Y,将<iframe>放置在屏幕外。

图像标签

图片是互联网的重要组成部分,让网页变得丰富多彩。本章介绍如何在网页插入图片。

<img>

<img>标签用于插入图片。它是单独使用的,没有闭合标签。

<img src="foo.jpg">

上面代码在网页插入一张图片foo.jpgsrc属性指定图片的网址,上例是相对 URL,表示图片与网页在同一个目录。

<img>默认是一个行内元素,与前后的文字处在同一行。

<p>Hello<img src="foo.jpg">World</p>

上面代码的渲染结果是,文字和图片在同一行显示。

图像默认以原始大小显示。如果图片很大,又与文字处在同一行,那么图片将把当前行的行高撑高,并且图片的底边与文字的底边在同一条水平线上。

<img>可以放在<a>标签内部,使得图片变成一个可以点击的链接。

<a href="example.html">
  <img src="foo.jpg">
</a>

上面代码中,图片可以像链接那样点击,点击后会产生跳转。

(1)alt 属性

alt属性用来设定图片的文字说明。图片不显示时(比如下载失败,或用户关闭图片加载),图片的位置上会显示该文本。

<img src="foo.jpg" alt="示例图片">

上面代码中,alt是图片的说明。图片下载失败时,浏览器会在图片位置,显示文字“示例图片”。

(2)width 属性,height 属性

图片默认以原始大小插入网页,width属性和height属性可以指定图片显示时的宽度和高度,单位是像素或百分比。

<img src="foo.jpg" width="400" height="300">

上面代码中,width属性指定图片显示的宽度为400像素,height属性指定显示高度为300像素。

注意,一旦设置了这两个属性,浏览器会在网页中预先留出这个大小的空间,不管图片有没有加载成功。不过,由于图片的显示大小可以用 CSS 设置,所以不建议使用这两个属性。

一种特殊情况是,width属性和height属性只设置了一个,另一个没有设置。这时,浏览器会根据图片的原始大小,自动设置对应比例的图片宽度或高度。举例来说,图片大小是 800像素 x 800像素,width属性设置成200,那么浏览器会自动将height设成200。

(3)srcset,sizes

详见下文的《响应式图像》部分。

(4)referrerpolicy

<img>导致的图片加载的 HTTP 请求,默认会带有Referer的头信息。referrerpolicy属性对这个行为进行设置。

(5)crossorigin

有时,图片和网页属于不同的网站,网页加载图片就会导致跨域请求,对方服务器可能要求跨域认证。crossorigin属性用来告诉浏览器,是否采用跨域的形式下载图片,默认是不采用。

简单说,只要打开了这个属性,HTTP 请求的头信息里面,就会加入origin字段,给出请求发出的域名,不打开这个属性就不加。

一旦打开该属性,它可以设为两个值。

  • anonymous:跨域请求不带有用户凭证(通常是 Cookie)。
  • use-credentials:跨域请求带有用户凭证。

下面是一个例子。

<img src="foo.jpg" crossorigin="anonymous">

crossorigin属性如果省略值的部分,则等同于anonymous

<img src="foo.jpg" crossorigin>

(6)loading

浏览器的默认行为是,只要解析到<img>标签,就开始加载图片。对于很长的网页,这样做很浪费带宽,因为用户不一定会往下滚动,一直看到网页结束。用户很可能是点开网页,看了一会就关掉了,那些不在视口的图片加载的流量,就都浪费了。

loading属性改变了这个行为,可以指定图片的懒加载,即图片默认不加载,只有即将滚动进入视口,变成用户可见时才会加载,这样就节省了带宽。

loading属性可以取以下三个值。

  • auto:浏览器默认行为,等同于不使用loading属性。
  • lazy:启用懒加载。
  • eager:立即加载资源,无论它在页面上的哪个位置。
<img src="image.png" loading="lazy" alt="" width="200" height="200">

由于行内图片的懒加载,可能会导致页面布局重排,所以使用这个属性的时候,最好指定图片的高和宽。

<figure><figcaption>

<figure>标签可以理解为一个图像区块,将图像和相关信息封装在一起。<figcaption>是它的可选子元素,表示图像的文本描述,通常用于放置标题,可以出现多个。

<figure>  <img src="https://example.com/foo.jpg">  <figcaption>示例图片</figcaption></figure>

除了图像,<figure>还可以封装引言、代码、诗歌等等。它等于是一个将主体内容与附加信息,封装在一起的语义容器。

<figure>  <figcaption>JavaScript 代码示例</figcaption>  <p><code>const foo = 'hello';</code></p></figure>

响应式图像

网页在不同尺寸的设备上,都能产生良好的显示效果,叫做“响应式设计”(responsive web design)。响应式设计的网页图像,就是“响应式图像”(responsive image)。

响应式图像的解决方案有很多,JavaScript 和 CSS 都可以实现。这里只介绍语义性最好的 HTML 方法,浏览器原生支持。

问题的由来

我们知道,<img>标签用于插入网页图像,所有情况默认插入的都是同一张图像。

<img src="foo.jpg">

上面代码在桌面端和手机上,插入的都是图像文件foo.jpg

这种处理方法固然简单,但是有三大弊端。

(1)体积

一般来说,桌面端显示的是大尺寸的图像,文件体积较大。手机的屏幕较小,只需要小尺寸的图像,可以节省带宽,加速网页渲染。

(2)像素密度

桌面显示器一般是单倍像素密度,而手机的显示屏往往是多倍像素密度,即显示时多个像素合成为一个像素,这种屏幕称为 Retina 屏幕。图像文件很可能在桌面端很清晰,放到手机上会有点模糊,因为图像没有那么高的像素密度,浏览器自动把图像的每个像素复制到周围像素,满足像素密度的要求,导致图像的锐利度有所下降。

(3)视觉风格

桌面显示器的面积较大,图像可以容纳更多细节。手机的屏幕较小,许多细节是看不清的,需要突出重点。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ovYCeuS7-1641644186278)(https://www.wangbase.com/blogimg/asset/201906/bg2019061002.jpg)]

上面两张图片,下方的手机图片经过裁剪以后,更突出图像重点,明显效果更好。

srcset属性

为了解决上面这些问题,HTML 语言提供了一套完整的解决方案。首先,<img>标签引入了srcset属性。

srcset属性用来指定多张图像,适应不同像素密度的屏幕。它的值是一个逗号分隔的字符串,每个部分都是一张图像的 URL,后面接一个空格,然后是像素密度的描述符。请看下面的例子。

<img srcset="foo-320w.jpg,             foo-480w.jpg 1.5x,             foo-640w.jpg 2x"     src="foo-640w.jpg">

上面代码中,srcset属性给出了三个图像 URL,适应三种不同的像素密度。

图像 URL 后面的像素密度描述符,格式是像素密度倍数 + 字母x1x表示单倍像素密度,可以省略。浏览器根据当前设备的像素密度,选择需要加载的图像。

如果srcset属性都不满足条件,那么就加载src属性指定的默认图像。

sizes属性

像素密度的适配,只适合显示区域一样大小的图像。如果希望不同尺寸的屏幕,显示不同大小的图像,srcset属性就不够用了,必须搭配sizes属性。

第一步,srcset属性列出所有可用的图像。

<img srcset="foo-160.jpg 160w,             foo-320.jpg 320w,             foo-640.jpg 640w,             foo-1280.jpg 1280w"     src="foo-1280.jpg">

上面代码中,srcset属性列出四张可用的图像,每张图像的 URL 后面是一个空格,再加上宽度描述符。

宽度描述符就是图像原始的宽度,加上字符w。上例的四种图片的原始宽度分别为160像素、320像素、640像素和1280像素。

第二步,sizes属性列出不同设备的图像显示宽度。

sizes属性的值是一个逗号分隔的字符串,除了最后一部分,前面每个部分都是一个放在括号里面的媒体查询表达式,后面是一个空格,再加上图像的显示宽度。

<img srcset="foo-160.jpg 160w,             foo-320.jpg 320w,             foo-640.jpg 640w,             foo-1280.jpg 1280w"     sizes="(max-width: 440px) 100vw,            (max-width: 900px) 33vw,            254px"     src="foo-1280.jpg">

上面代码中,sizes属性给出了三种屏幕条件,以及对应的图像显示宽度。宽度不超过440像素的设备,图像显示宽度为100%;宽度441像素到900像素的设备,图像显示宽度为33%;宽度900像素以上的设备,图像显示宽度为254px

第三步,浏览器根据当前设备的宽度,从sizes属性获得图像的显示宽度,然后从srcset属性找出最接近该宽度的图像,进行加载。

假定当前设备的屏幕宽度是480px,浏览器从sizes属性查询得到,图片的显示宽度是33vw(即33%),等于160pxsrcset属性里面,正好有宽度等于160px的图片,于是加载foo-160.jpg

如果省略sizes属性,那么浏览器将根据实际的图像显示宽度,从srcset属性选择最接近的图片。一旦使用sizes属性,就必须与srcset属性搭配使用,单独使用sizes属性是无效的。

<picture>

响应式用法

<img>标签的srcset属性和sizes属性分别解决了像素密度和屏幕大小的适配,但如果要同时适配不同像素密度、不同大小的屏幕,就要用到<picture>标签。

<picture>是一个容器标签,内部使用<source><img>,指定不同情况下加载的图像。

<picture>  <source media="(max-width: 500px)" srcset="cat-vertical.jpg">  <source media="(min-width: 501px)" srcset="cat-horizontal.jpg">  <img src="cat.jpg" alt="cat"></picture>

上面代码中,<picture>标签内部有两个<source>标签和一个<img>标签。

<picture>内部的<source>标签,主要使用media属性和srcset属性。media属性给出媒体查询表达式,srcset属性就是<img>标签的srcset属性,给出加载的图像文件。sizes属性其实这里也可以用,但由于有了media属性,就没有必要了。

浏览器按照<source>标签出现的顺序,依次判断当前设备是否满足media属性的媒体查询表达式,如果满足就加载srcset属性指定的图片文件,并且不再执行后面的<source>标签和<img>标签。

<img>标签是默认情况下加载的图像,用来满足上面所有<source>都不匹配的情况,或者不支持<picture>的老式浏览器。

上面例子中,设备宽度如果不超过500px,就加载竖屏的图像,否则加载横屏的图像。

下面给出一个例子,同时考虑屏幕尺寸和像素密度的适配。

<picture>  <source srcset="homepage-person@desktop.png,                  homepage-person@desktop-2x.png 2x"          media="(min-width: 990px)">  <source srcset="homepage-person@tablet.png,                  homepage-person@tablet-2x.png 2x"          media="(min-width: 750px)">  <img srcset="homepage-person@mobile.png,               homepage-person@mobile-2x.png 2x"       alt="Shopify Merchant, Corrine Anestopoulos"></picture>

上面代码中,<source>标签的media属性给出屏幕尺寸的适配条件,每个条件都用srcset属性,再给出两种像素密度的图像 URL。

图像格式的选择

除了响应式图像,<picture>标签还可以用来选择不同格式的图像。比如,如果当前浏览器支持 Webp 格式,就加载这种格式的图像,否则加载 PNG 图像。

<picture>  <source type="image/svg+xml" srcset="logo.xml">  <source type="image/webp" srcset="logo.webp">   <img src="logo.png" alt="ACME Corp"></picture>

上面代码中,<source>标签的type属性给出图像的 MIME 类型,srcset是对应的图像 URL。

浏览器按照<source>标签出现的顺序,依次检查是否支持type属性指定的图像格式,如果支持就加载图像,并且不再检查后面的<source>标签了。上面例子中,图像加载优先顺序依次为 svg 格式、webp 格式和 png 格式。

链接标签

链接(hyperlink)是互联网的核心。它允许用户在页面上,从一个网址跳转到另一个网址,从而把所有资源联系在一起。

URL 是链接指向的地址。链接不仅可以指向另一个网页,也可以指向文本、图像、文件等资源。可以这样说,所有互联网上的资源,都可以通过链接访问。

<a>

链接通过<a>标签表示,用户点击后,浏览器会跳转到指定的网址。下面就是一个典型的链接。

<a href="https://wikipedia.org/">维基百科</a>

上面代码就定义了一个超级链接。浏览器显示“维基百科”,文字下面默认会有下划线,表示这是一个链接。用户点击后,浏览器跳转到href属性指定的网址。

<a>标签内部不仅可以放置文字,也可以放置其他元素,比如段落、图像、多媒体等等。

<a href="https://www.example.com/">
  <img src="https://www.example.com/foo.jpg">
</a>

上面代码中,<a>标签内部就是一个图像。用户点击图像,就会跳转到指定网址。

<a>标签有如下属性。

(1)href

href属性给出链接指向的网址。它的值应该是一个 URL 或者锚点。

上文已经给出了完整 URL 的例子,下面是锚点的例子。

<a href="#demo">示例</a>

上面代码中,href属性的值是#加上锚点名称。点击后,浏览器会自动滚动,停在当前页面里面demo锚点所在的位置。

(2)hreflang

hreflang属性给出链接指向的网址所使用的语言,纯粹是提示性的,没有实际功能。

<a
  href="https://www.example.com"
  hreflang="en"
>示例网址</a>

上面代码表明,href属性指向的网址的语言是英语。

该属性的值跟通用属性lang一样,语言代码可以参考《属性》一章的lang属性的介绍。

(3)title

title属性给出链接的说明信息。鼠标悬停在链接上方时,浏览器会将这个属性的值,以提示块的形式显示出来。

<a
  href="https://www.example.com/"
  title="hello"
>示例</a>

上面代码中,用户鼠标停留在链接上面,会出现文字提示hello

(4)target

target属性指定如何展示打开的链接。它可以是在指定的窗口打开,也可以在<iframe>里面打开。

<p><a href="http://foo.com" target="test">foo</a></p>
<p><a href="http://bar.com" target="test">bar</a></p>

上面代码中,两个链接都在名叫test的窗口打开。首先点击链接foo,浏览器发现没有叫做test的窗口,就新建一个窗口,起名为test,在该窗口打开foo.com。然后,用户又点击链接bar,由于已经存在test窗口,浏览器就在该窗口打开bar.com,取代里面已经打开的foo.com

target属性的值也可以是以下四个关键字之一。

  • _self:当前窗口打开,这是默认值。
  • _blank:新窗口打开。
  • _parent:上层窗口打开,这通常用于从父窗口打开的子窗口,或者<iframe>里面的链接。如果当前窗口没有上层窗口,这个值等同于_self
  • _top:顶层窗口打开。如果当前窗口就是顶层窗口,这个值等同于_self
<a
  href="https://www.example.com"
  target="_blank"
>示例链接</a>

上面代码点击后,浏览器会新建一个窗口,在该窗口打开链接,并且新窗口没有名字。

注意,使用target属性的时候,最好跟rel="noreferrer"一起使用,这样可以避免安全风险。

(5)rel

rel属性说明链接与当前页面的关系。

<a href="help.html" rel="help">帮助</a>

上面代码的rel属性,说明链接是当前页面的帮助文档。

下面是一些常见的rel属性的值。

  • alternate:当前文档的另一种形式,比如翻译。
  • author:作者链接。
  • bookmark:用作书签的永久地址。
  • external:当前文档的外部参考文档。
  • help:帮助链接。
  • license:许可证链接。
  • next:系列文档的下一篇。
  • nofollow:告诉搜索引擎忽略该链接,主要用于用户提交的内容,防止有人企图通过添加链接,提高该链接的搜索排名。
  • noreferrer:告诉浏览器打开链接时,不要将当前网址作为 HTTP 头信息的Referer字段发送出去,这样可以隐藏点击的来源。
  • noopener:告诉浏览器打开链接时,不让链接窗口通过 JavaScript 的window.opener属性引用原始窗口,这样就提高了安全性。
  • prev:系列文档的上一篇。
  • search:文档的搜索链接。
  • tag:文档的标签链接。

(6)referrerpolicy

referrerpolicy属性用于精确设定点击链接时,浏览器发送 HTTP 头信息的Referer字段的行为。

该属性可以取下面八个值:no-referrerno-referrer-when-downgradeoriginorigin-when-cross-originunsafe-urlsame-originstrict-originstrict-origin-when-cross-origin

其中,no-referrer表示不发送Referer字段,same-origin表示同源时才发送Referer字段,origin表示只发送源信息(协议+域名+端口)。其他几项的解释,请查阅 HTTP 文档。

(7)ping

ping属性指定一个网址,用户点击的时候,会向该网址发出一个 POST 请求,通常用于跟踪用户的行为。

(8)type

type属性给出链接 URL 的 MIME 类型,比如到底是网页,还是图像或文件。它也是纯粹提示性的属性,没有实际功能。

<a  href="smile.jpg"  type="image/jpeg">示例图片</a>

上面代码中,type属性提示这是一张图片。

(9)download

download属性表明当前链接用于下载,而不是跳转到另一个 URL。

<a href="demo.txt" download>下载</a>

上面代码点击后,会出现下载对话框。

注意,download属性只在链接与网址同源时,才会生效。也就是说,链接应该与网址属于同一个网站。

如果download属性设置了值,那么这个值就是下载的文件名。

<a  href="foo.exe"  download="bar.exe">点击下载</a>

上面代码中,下载文件的原始文件名是foo.exe。点击后,下载对话框提示的文件名是bar.exe

注意,如果链接点击后,服务器的 HTTP 回应的头信息设置了Content-Disposition字段,并且该字段的值与download属性不一致,那么该字段优先,下载时将显示其设置的文件名。

download属性还有一个用途,就是有些地址不是真实网址,而是数据网址,比如data:开头的网址。这时,download属性可以为虚拟网址指定下载的文件名。

<a href="data:,Hello%2C%20World!">点击</a>

上面链接点击后,会打开一个虚拟网页,上面显示Hello World!

<a  href="data:,Hello%2C%20World!"  download="hello.txt">点击</a>

上面链接点击后,下载的hello.txt文件内容就是“Hello, World!”。

邮件链接

链接也可以指向一个邮件地址,使用mailto协议。用户点击后,浏览器会打开本机默认的邮件程序,让用户向指定的地址发送邮件。

<a href="mailto:contact@example.com">联系我们</a>

上面代码中,链接就指向邮件地址。点击后,浏览器会打开一个邮件地址,让你可以向contact@example.com发送邮件。

除了邮箱,邮件协议还允许指定其他几个邮件要素。

  • subject:主题
  • cc:抄送
  • bcc:密送
  • body:邮件内容

使用方法是将这些邮件要素,以查询字符串的方式,附加在邮箱地址后面。

<a  href="mailto:foo@bar.com?cc=test@test.com&subject=The%20subject&body=The%20body">发送邮件</a>

上面代码中,邮件链接里面不仅包含了邮箱地址,还包含了ccsubjectbody等邮件要素。这些要素的值需要经过 URL 转义,比如空格转成%20

不指定邮箱也是允许的,就像下面这样。这时用户自己在邮件程序里面,填写想要发送的邮箱,通常用于邮件分享网页。

<a href="mailto:">告诉朋友</a>

电话链接

如果是手机浏览的页面,还可以使用tel协议,创建电话链接。用户点击该链接,会唤起电话,可以进行拨号。

<a href="tel:13312345678">13312345678</a>

上面代码在手机中,点击链接会唤起拨号界面,可以直接拨打指定号码。

<link>

基本用法

<link>标签主要用于将当前网页与相关的外部资源联系起来,通常放在<head>元素里面。最常见的用途就是加载 CSS 样式表。

<link rel="stylesheet" type="text/css" href="theme.css">

上面代码为网页加载样式表theme.css

除了默认样式表,网页还可以加载替代样式表,即默认不生效、需要用户手动切换的样式表。

<link href="default.css" rel="stylesheet" title="Default Style"><link href="fancy.css" rel="alternate stylesheet" title="Fancy"><link href="basic.css" rel="alternate stylesheet" title="Basic">

上面代码中,default.css是默认样式表,默认就会生效。fancy.cssbasic.css是替换样式表(rel="alternate stylesheet"),默认不生效。title属性在这里是必需的,用来在浏览器菜单里面列出这些样式表的名字,供用户选择,以替代默认样式表。

<link>还可以加载网站的 favicon 图标文件。

<link rel="icon" href="/favicon.ico" type="image/x-icon">

手机访问时,网站通常需要提供不同分辨率的图标文件。

<link rel="apple-touch-icon-precomposed" sizes="114x114" href="favicon114.png"><link rel="apple-touch-icon-precomposed" sizes="72x72" href="favicon72.png">

上面代码指定 iPhone 设备需要的114像素和72像素的图标。

<link>也用于提供文档的相关链接,比如下面是给出文档的 RSS Feed 地址。

<link rel="alternate" type="application/atom+xml" href="/blog/news/atom">

rel 属性

rel属性表示外部资源与当前文档之间的关系,是<link>标签的必需属性。它可以但不限于取以下值。

  • alternate:文档的另一种表现形式的链接,比如打印版。
  • author:文档作者的链接。
  • dns-prefetch:要求浏览器提前执行指定网址的 DNS 查询。
  • help:帮助文档的链接。
  • icon:加载文档的图标文件。
  • license:许可证链接。
  • next:系列文档下一篇的链接。
  • pingback:接收当前文档 pingback 请求的网址。
  • preconnect:要求浏览器提前与给定服务器,建立 HTTP 连接。
  • prefetch:要求浏览器提前下载并缓存指定资源,供下一个页面使用。它的优先级较低,浏览器可以不下载。
  • preload:要求浏览器提前下载并缓存指定资源,当前页面稍后就会用到。它的优先级较高,浏览器必须立即下载。
  • prerender:要求浏览器提前渲染指定链接。这样的话,用户稍后打开该链接,就会立刻显示,感觉非常快。
  • prev:表示当前文档是系列文档的一篇,这里给出上一篇文档的链接。
  • search:提供当前网页的搜索链接。
  • stylesheet:加载一张样式表。

下面是一些示例。

<!-- 作者信息 --><link rel="author" href="humans.txt"><!-- 版权信息 --><link rel="license" href="copyright.html"><!-- 另一个语言的版本 --><link rel="alternate" href="https://es.example.com/" hreflang="es"><!-- 联系方式 --><link rel="me" href="https://google.com/profiles/someone" type="text/html"><link rel="me" href="mailto:name@example.com"><link rel="me" href="sms:+15035550125"><!-- 历史资料 --><link rel="archives" href="http://example.com/archives/"><!-- 目录 --><link rel="index" href="http://example.com/article/"><!-- 导航 --><link rel="first" href="http://example.com/article/"><link rel="last" href="http://example.com/article/?page=42"><link rel="prev" href="http://example.com/article/?page=1"><link rel="next" href="http://example.com/article/?page=3">

资源的预加载

某些情况下,你需要浏览器预加载某些资源,也就是先把资源缓存下来,等到使用的时候,就不用再从网上下载了,立即就能使用。预处理指令可以做到这一点。

预加载主要有下面五种类型。

(1)<link rel="preload">

<link rel="preload">告诉浏览器尽快下载并缓存资源(如脚本或样式表),该指令优先级较高,浏览器肯定会执行。当加载页面几秒钟后需要该资源时,它会很有用。下载后,浏览器不会对资源执行任何操作,脚本未执行,样式表未应用。它只是缓存,当其他东西需要它时,它立即可用。

<link rel="preload" href="image.png" as="image">

rel="preload"除了优先级较高,还有两个优点:一是允许指定预加载资源的类型,二是允许onload事件的回调函数。下面是rel="preload"配合as属性,告诉浏览器预处理资源的类型,以便正确处理。

<link rel="preload" href="style.css" as="style"><link rel="preload" href="main.js" as="script">

上面代码要求浏览器提前下载并缓存style.cssmain.js

as属性指定加载资源的类型,它的值一般有下面几种。

  • “script”
  • “style”
  • “image”
  • “media”
  • “document”

如果不指定as属性,或者它的值是浏览器不认识的,那么浏览器会以较低的优先级下载这个资源。

有时还需要type属性,进一步明确 MIME 类型。

<link rel="preload" href="sintel-short.mp4" as="video" type="video/mp4">

上面代码要求浏览器提前下载视频文件,并且说明这是 MP4 编码。

下面是预下载字体文件的例子。

<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin>

注意,所有预下载的资源,只是下载到浏览器的缓存,并没有执行。如果希望资源预下载后立刻执行,可以参考下面的写法。

<link rel="preload" as="style" href="async_style.css" onload="this.rel='stylesheet'">

上面代码中,onload指定的回调函数会在脚本下载完成后执行,立即插入页面。

(2)<link rel="prefetch">

<link rel="prefetch">的使用场合是,如果后续的页面需要某个资源,并且希望预加载该资源,以便加速页面渲染。该指令不是强制性的,优先级较低,浏览器不一定会执行。这意味着,浏览器可以不下载该资源,比如连接速度很慢时。

<link rel="prefetch" href="https://www.example.com/">

(3)<link rel="preconnect">

<link rel="preconnect">要求浏览器提前与某个域名建立 TCP 连接。当你知道,很快就会请求该域名时,这会很有帮助。

<link rel="preconnect" href="https://www.example.com/">

(4)<link rel="dns-prefetch">

<link rel="dns-prefetch">要求浏览器提前执行某个域名的 DNS 解析。

<link rel="dns-prefetch" href="//example.com/">

(5)<link rel="prerender">

<link rel="prerender">要求浏览器加载某个网页,并且提前渲染它。用户点击指向该网页的链接时,就会立即呈现该页面。如果确定用户下一步会访问该页面,这会很有帮助。

<link rel="prerender" href="http://example.com/">

media 属性

media属性给出外部资源生效的媒介条件。

<link href="print.css" rel="stylesheet" media="print"><link href="mobile.css" rel="stylesheet" media="screen and (max-width: 600px)">

上面代码中,打印时加载print.css,移动设备访问时(设备宽度小于600像素)加载mobile.css

下面是使用media属性实现条件加载的例子。

<link rel="preload" as="image" href="map.png" media="(max-width: 600px)"><link rel="preload" as="script" href="map.js" media="(min-width: 601px)">

上面代码中,如果屏幕宽度在600像素以下,则只加载第一个资源,否则就加载第二个资源。

其他属性

<link>标签的其他属性如下。

  • crossorigin:加载外部资源的跨域设置。
  • href:外部资源的网址。
  • referrerpolicy:加载时Referer头信息字段的处理方法。
  • asrel="preload"rel="prefetch"时,设置外部资源的类型。
  • type:外部资源的 MIME 类型,目前仅用于rel="preload"rel="prefetch"的情况。
  • title:加载样式表时,用来标识样式表的名称。
  • sizes:用来声明图标文件的尺寸,比如加载苹果手机的图标文件。

<script>

<script>用于加载脚本代码,目前主要是加载 JavaScript 代码。

<script>console.log('hello world');</script>

上面代码嵌入网页,会立即执行。

<script>也可以加载外部脚本,src属性给出外部脚本的地址。

<script src="javascript.js"></script>

上面代码会加载javascript.js脚本文件,并执行。

type属性给出脚本的类型,默认是 JavaScript 代码,所以可省略。完整的写法其实是下面这样。

<script type="text/javascript" src="javascript.js"></script>

type属性也可以设成module,表示这是一个 ES6 模块,不是传统脚本。

<script type="module" src="main.js"></script>

对于那些不支持 ES6 模块的浏览器,可以设置nomodule属性。支持 ES6 模块的浏览器,会不加载指定的脚本。这个属性通常与type="module"配合使用,作为老式浏览器的回退方案。

<script type="module" src="main.js"></script><script nomodule src="fallback.js"></script>

<script>还有下面一些其他属性,大部分跟 JavaScript 语言有关,可以参考相关的 JavaScript 教程。

  • async:该属性指定 JavaScript 代码为异步执行,不是造成阻塞效果,JavaScript 代码默认是同步执行。
  • defer:该属性指定 JavaScript 代码不是立即执行,而是页面解析完成后执行。
  • crossorigin:如果采用这个属性,就会采用跨域的方式加载外部脚本,即 HTTP 请求的头信息会加上origin字段。
  • integrity:给出外部脚本的哈希值,防止脚本被篡改。只有哈希值相符的外部脚本,才会执行。
  • nonce:一个密码随机数,由服务器在 HTTP 头信息里面给出,每次加载脚本都不一样。它相当于给出了内嵌脚本的白名单,只有在白名单内的脚本才能执行。
  • referrerpolicy:HTTP 请求的Referer字段的处理方法。

<noscript>

<noscript>标签用于浏览器不支持或关闭 JavaScript 时,所要显示的内容。用户关闭 JavaScript 可能是为了节省带宽,以延长手机电池寿命,或者为了防止追踪,保护隐私。

<noscript>  您的浏览器不能执行 JavaScript 语言,页面无法正常显示。</noscript>

上面这段代码,只有浏览器不能执行 JavaScript 代码时才会显示,否则就不会显示。

列表标签

列表是一系列排列好的项目,主要分成两类:有序列表和无序列表。

有序列表是每个列表项前面有编号,呈现出顺序,就像下面这样。

1. 列表项 A
2. 列表项 B
3. 列表项 C

无序列表则是列表项前面没有编号,只有一个列表符号,默认是一个圆点。

· 列表项 A
· 列表项 B
· 列表项 C

<ol>

<ol>标签是一个有序列表容器(ordered list),会在内部的列表项前面产生数字编号。列表项的顺序有意义时,比如排名,就会采用这个标签。

<ol>
  <li>列表项 A</li>
  <li>列表项 B</li>
  <li>列表项 C</li>
</ol>

上面代码会在列表项 A、B、C 前面,分别产生1、2、3的编号。

<ol>标签内部可以嵌套<ol>标签或<ul>标签,形成多级列表。

<ol>
  <li>列表项 A</li>
  <li>列表项 B
    <ol>
      <li>列表项 B1</li>
      <li>列表项 B2</li>
      <li>列表项 B3</li>
    </ol>
  </li>
  <li>列表项 C</li>
</ol>

上面代码中,一个有序列表内部嵌套了另一个有序列表,渲染结果如下。

1. 列表项 A
2. 列表项 B
  1. 列表项 B1
  2. 列表项 B2
  3. 列表项 B3
3. 列表项 C

该标签有以下属性。

(1)reversed

reversed属性产生倒序的数字列表。

<ol reversed>
  <li>列表项 A</li>
  <li>列表项 B</li>
  <li>列表项 C</li>
</ol>

上面代码中,列表项 A、B、C 前面,产生的编号是3、2、1。

(2)start

start属性的值是一个整数,表示数字列表的起始编号。

<ol start="5">
  <li>列表项 A</li>
  <li>列表项 B</li>
  <li>列表项 C</li>
</ol>

上面代码中,列表项 A、B、C 前面,产生的编号是5、6、7。

(3)type

type属性指定数字编号的样式。目前,浏览器支持以下样式。

  • a:小写字母
  • A:大写字母
  • i:小写罗马数字
  • I:大写罗马数字
  • 1:整数(默认值)
<ol type="a">
  <li>列表项 A</li>
  <li>列表项 B</li>
  <li>列表项 C</li>
</ol>

上面代码中,列表项 A、B、C 前面的编号,分别是英文小写字母a、b、c。

注意,即使编号是字母,start属性也依然使用整数。

<ol type="a" start="3">  <li>列表项 A</li>  <li>列表项 B</li>  <li>列表项 C</li></ol>

上面代码中,type属性指定编号采用小写英文字母,start属性等于3,表示从c开始编号。

<ul>

<ul>标签是一个无序列表容器(unordered list),会在内部的列表项前面产生实心小圆点,作为列表符号。列表项的顺序无意义时,采用这个标签。

<ul>  <li>列表项 A</li>  <li>列表项 B</li>  <li>列表项 C</li></ul>

上面代码的渲染结果是,列表项 A、B、C 前面,分别产生一个实心小圆点,作为列表符号。

<ul>标签内部可以嵌套<ul><ol>,形成多级列表。

<li>

<li>表示列表项,用在<ol><ul>容器之中。

有序列表<ol>之中,<li>有一个value属性,定义当前列表项的编号,后面列表项会从这个值开始编号。

<ol>  <li>列表项 A</li>  <li value="4">列表项 B</li>  <li>列表项 C</li></ol>

上面代码中,value属性指定第二个列表项的编号是4,因此三个列表项的编号,分别为1、4、5。

<dl><dt><dd>

<dl>标签是一个块级元素,表示一组术语的列表(description list)。术语名(description term)由<dt>标签定义,术语解释(description detail)由<dd>标签定义。<dl>常用来定义词汇表。

<dl>  <dt>CPU</dt>  <dd>中央处理器</dd>  <dt>Memory</dt>  <dd>内存</dd>  <dt>Hard Disk</dt>  <dd>硬盘</dd></dl>

<dt><dd>都是块级元素,<dd>默认会在<dt>下方缩进显示。上面代码的默认渲染结果如下。

CPU  中央处理器Memory  内存Hard Disk  硬盘

多个术语(<dt>)对应一个解释(<dd>),或者多个解释(<dd>)对应一个术语(<dt>),都是合法的。

<dl>  <dt>A</dt>  <dt>B</dt>  <dd>C</dd>  <dt>D</dt>  <dd>E</dd>  <dd>F</dd></dl>

上面代码中,AB有共同的解释C,而D有两个解释EF

表格标签

表格(table)以行(row)和列(column)的形式展示数据。

<table><caption>

<table>是一个块级容器标签,所有表格内容都要放在这个标签里面。

<table>
  ... ...
</table>

<caption>总是<table>里面的第一个子元素,表示表格的标题。该元素是可选的。

<table>
  <caption>示例表格</caption>
</table>

<thead><tbody><tfoot>

<thead><tbody><tfoot>都是块级容器元素,且都是<table>的一级子元素,分别表示表头、表体和表尾。

<table>
  <thead>... ...</thead>
  <tbody>... ...</tbody>
  <tfoot>... ...</tfoot>
</table>

这三个元素都是可选的。如果使用了<thead>,那么<tbody><tfoot>一定在<thead>的后面。如果使用了<tbody>,那么<tfoot>一定在<tbody>后面。

大型表格内部可以使用多个<tbody>,表示连续的多个部分。

<colgroup><col>

<colgroup><table>的一级子元素,用来包含一组列的定义。<col><colgroup>的子元素,用来定义表格的一列。

<table>
  <colgroup>
    <col>
    <col>
    <col>
  </colgroup>
</table>

上面代码表明表格有3列。

<col>不仅是一个单独使用的标签,没有结束标志,而且还是一个空元素,没有子元素。它的主要作用,除了申明表格结构,还可以为表格附加样式。

<table>
  <colgroup>
    <col class="c1">
    <col class="c2">
    <col class="c3">
  </colgroup>
  <tr>
    <td>1</td>
    <td>2</td>
    <td>3</td>
  </tr>
</table>

上面代码中,<colgroup>声明表格有三列,每一列有自己的 class,可以使用 CSS 针对每个 class 设定样式,会对整个表格生效。

<col>有一个span属性,值为正整数,默认为1。如果大于1,就表示该列的宽度包含连续的多列。

<table>
  <colgroup>
    <col>
    <col span="2">
    <col>
  </colgroup>
</table>

上面代码中,表格的表头定义了3列,实际数据有4列。表头的第2列会连续跨2列。

<tr>

<tr>标签表示表格的一行(table row)。如果表格有<thead><tbody><tfoot>,那么<tr>就放在这些容器元素之中,否则直接放在<table>的下一级。

<table>
  <tr>...</tr>
  <tr>...</tr>
  <tr>...</tr>
</table>

上面代码表示表格共有3行。

<th><td>

<th><td>都用来定义表格的单元格。其中,<th>是标题单元格,<td>是数据单元格。

<table>
  <tr>
    <th>学号</th><th>姓名</th>
  </tr>
  <tr>
    <td>001</td><td>张三</td>
  </tr>
  <tr>
    <td>002</td><td>李四</td>
  </tr>
</table>

上面代码中,表格一共有三行。第一行是标题行,所以使用<th>;第二行和第三行是数据行,所以使用<td>

(1)colspan属性,rowspan属性

单元格会有跨越多行或多列的情况,这要通过colspan属性和rowspan属性设置,前者表示单元格跨越的栏数,后者表示单元格跨越的行数。它们的值都是一个非负整数,默认为1。

<table>  <tr>    <td colspan="2">A</td><td>B</td>  </tr>  <tr>    <td>A</td><td>B</td><td>C</td>  </tr></table>

上面代码中,第一行的第一个单元格会跨两列。

(2)headers属性

如果表格很大,单元格很多,源码里面会看不清,哪个单元格对应哪个表头,这时就可以使用headers属性。

<table>  <tr>    <th id="no">学号</th><th id="names">姓名</th>  </tr>  <tr>    <td headers="no">001</td><td headers="names">张三</td>  </tr>  <tr>    <td headers="no">002</td><td headers="names">李四</td>  </tr></table>

上面代码中,标题栏的<th>设置了id属性,后面的<td>单元格的headers属性就对应这些id属性的值,因此就能看出来这些单元格对应哪个标题栏。

headers属性的值总是对应<th>标签的id属性的值。由于一个单元格可以对应多个标题栏(跨行的情况),所以headers属性可以是一个空格分隔的字符串,对应多个id属性的值。

(3)scope属性

scope属性只有<th>标签支持,一般不在<td>标签使用,表示该<th>单元格到底是栏的标题,还是列的标题。

<table>  <tr>    <th scope="col">姓名</th>    <th scope="col">学号</th>    <th scope="col">性别</th>  </tr>  <tr>    <th scope="row">张三</th>    <td>001</td>    <td></td>  </tr>  <tr>    <th scope="row">李四</th>    <td>002</td>    <td></td>  </tr></table>

上面代码中,第一行的标题栏都是列标题,所以<th>scope属性为col,第二行和第三行的第一列是行标题,所以<th>标签的scope属性为row

scope属性可以取下面这些值。

  • row:该行的所有单元格,都与该标题单元格相关。
  • col:该列的所有单元格,都与该标题单元格相关。
  • rowgroup:多行组成的一个行组的所有单元格,都与该标题单元格相关,可以与rowspan属性配合使用。
  • colgroup:多列组成的一个列组的所有单元格,都与该标题单元格相关,可以与colspan属性配合使用。
  • auto:默认值,表示由浏览器自行决定。

下面是一个colgroup属性和rowgroup属性的例子。

<table>  <thead>    <tr>      <th scope="col">海报名称</th>      <th scope="col">颜色</th>      <th colspan="3" scope="colgroup">尺寸</th>    </tr>  </thead>  <tbody>    <tr>      <th rowspan="3" scope="rowgroup">Zodiac</th>      <th scope="row">Full color</th>      <td>A2</td>      <td>A3</td>      <td>A4</td>    </tr>    <tr>      <th scope="row">Black and white</th>      <td>A1</td>      <td>A2</td>      <td>A3</td>    </tr>    <tr>      <th scope="row">Sepia</th>      <td>A3</td>      <td>A4</td>      <td>A5</td>    </tr>  </tbody></table>

上面的例子中,列标题“尺寸”的scope属性为colgroup,表示这个标题单元格对应多列(本例为3列);行标题的scope属性为rowgroup,表示这个标题单元格对应多行(本例为3行)。

渲染结果就是下面的样子。

海报名称颜色尺寸
ZodiacFull colorA2A3A4
Black and whiteA1A2A3
SepiaA3A4A5

文本标签

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

<div>

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

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

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

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

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

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

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

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

<p>

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

<p>hello world</p>

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

<span>

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

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

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

<br><wbr>

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

hello<br>world

浏览器渲染上面代码时,会分成两行,helloworld各占一行。

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

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

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

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

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

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

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

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

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

<hr>

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

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

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

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

<pre>

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

<pre>hello   world</pre>

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

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

<pre><strong>hello world</strong></pre>

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

<strong><b>

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

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

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

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

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

<em><i>

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

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

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

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

<p>我心想,这件事是<i>真的</i>吗?</p>

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

<sub><sup><var>

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

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

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

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

<u><s>

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

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

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

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

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

<p>今天特价商品:<s>三文鱼</s>(售完)</p>

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

<blockquote><cite><q>

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

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

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

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

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

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

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

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

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

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

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

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

<code>

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

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

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

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

<kbd><samp>

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

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

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

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

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

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

<mark>

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

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

<mark>很适合在引用的内容(<q><blockquote>)中,标记出需要关注的句子。

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

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

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

<small>

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

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

<time><data>

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

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

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

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

  • 有效年份:2011
  • 有效月份:2011-11
  • 有效日期:2011-11-18
  • 无年份的日期:11-18
  • 年度的第几周:2011-W47
  • 有效时间:14:5414:54:3914:54:39.929
  • 日期和时间:2011-11-18T14:54:39.929
<p>音乐会在<time datetime="20:00">晚上八点</time>开始。</p>

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

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

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

<address>

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

<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>里面,下面是一个例子。

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

<abbr>

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

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

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

<ins><del>

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

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

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

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

  • cite:该属性的值是一个 URL,表示该网址可以解释本次删改。
  • datetime:表示删改发生的时间。
<ins cite="./why.html" datetime="2018-05">  <p>项目比原定时间提前两周结束。</p></ins>

<dfn>

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

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

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

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

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

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

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

<ruby>

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

<ruby><rp>(</rp><rt>han</rt><rp>)</rp><rp>(</rp><rt>zi</rt><rp>)</rp></ruby>

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

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

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

(1)<rp>

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

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

<ruby><rp>(</rp><rt>han</rt><rp>)</rp><rp>(</rp><rt>zi</rt><rp>)</rp></ruby>

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

(2)<rt>

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

(3)<rb>

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

<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>对应。

<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>标签是一个行内元素,表示文字方向与网页主体内容的方向不一致。

<p>床前明月光,<bdo dir="rtl">霜上地是疑</bdo></p>

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

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

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

<p><bdi>床前明月光,疑是地上霜。</bdi></p>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值