基本的原生表单控件

上一篇文章中,我们标记了一个功能性的 Web 表单示例,介绍了表单控件和常见的结构元素,并重点关注了可访问性最佳实践。接下来,我们将详细研究不同表单控件(或称小部件)的功能,探讨可用于收集不同类型数据的所有不同选项。在本文中,我们将重点介绍自 Web 早期以来所有浏览器都支持的原始表单控件集。

预备知识 HTML 的基本理解
目标 详细了解浏览器中可用于收集数据的原始原生表单小部件集,以及如何使用 HTML 实现它们。

您已经了解了一些表单元素,包括 <form><fieldset><legend><textarea><label><button><input>。本文涵盖:

注意: 我们将在接下来的两篇文章中介绍其他功能更强大的表单控件。如果您需要更高级的参考资料,请查阅我们的 HTML 表单元素参考,特别是我们详尽的 <input> 类型参考。

文本输入字段

文本 <input> 字段是最基本的表单小部件。它们是让用户输入任何类型数据的便捷方式,我们已经看到了一些简单的示例。

注意: HTML 表单文本字段是简单的纯文本输入控件。这意味着您不能使用它们来执行富文本编辑(粗体、斜体等)。您会遇到的所有富文本编辑器都是使用 HTML、CSS 和 JavaScript 创建的自定义小部件。

所有基本文本控件都具有一些共同的行为:

  • 它们可以标记为 readonly(用户不能修改输入值,但它仍与表单的其余数据一起发送)或 disabled(输入值不能修改,也从不与表单的其余数据一起发送)。
  • 它们可以有一个 placeholder;这是出现在文本输入框内的文本,用于简要描述该框的用途。
  • 它们可以在 size(框的物理大小)和 maxlength(可以输入到框中的最大字符数)上受到限制。
  • 它们可以受益于拼写检查(使用 spellcheck 属性)。

注意: <input> 元素在 HTML 元素中是独一无二的,因为它可以根据其 type 属性值采用多种形式。它用于创建大多数类型的表单小部件,包括单行文本字段、时间日期控件、不带文本输入的控件(如复选框、单选按钮和颜色选择器),以及按钮。

单行文本字段

单行文本字段是使用 <input> 元素创建的,其 type 属性值设置为 text,或者完全省略 type 属性(text 是默认值)。如果浏览器不识别您为 type 属性指定的值(例如,如果您指定 type="color" 但浏览器不支持原生的颜色选择器),则 text 值也是该属性的备用值。

注意: 您可以在 GitHub 上找到所有单行文本字段类型的示例,网址为 single-line-text-fields.html也可在线查看)。

这是一个基本的单行文本字段示例:

html
<input type="text" id="comment" name="comment" value="I'm a text field" />

单行文本字段只有一个真正的限制:如果您输入带有换行符的文本,浏览器会在将数据发送到服务器之前删除这些换行符。

下面的截图显示了文本输入框在默认、聚焦和禁用状态下的样子。大多数浏览器使用控件周围的聚焦环来指示聚焦状态,并使用灰色文本或褪色/半透明控件来指示禁用状态。

Screenshot of the default, focused and disabled states text input in Chrome on macOS

本文档中使用的屏幕截图是在 macOS 上的 Chrome 浏览器中拍摄的。这些字段/按钮在不同浏览器之间可能存在细微差异,但基本的高亮显示技术保持相似。

注意: 我们将在下一篇文章 HTML5 输入类型中讨论用于强制执行特定验证约束的 type 属性值,包括颜色、电子邮件和 URL 输入类型。

密码字段

最初的输入类型之一是 password 文本字段类型:

html
<input type="password" id="pwd" name="pwd" />

下面的截图显示了密码输入字段,其中每个输入字符都显示为圆点。

Password field in chrome 115 on macOS

password 值不会对输入的文本添加任何特殊限制,但它会模糊输入字段中的值(例如,用点或星号),以便其他人无法轻易读取。

请记住,这只是一个用户界面功能;除非您安全地提交表单,否则它将以纯文本形式发送,这对安全性不利——恶意方可能会截取您的数据并窃取密码、信用卡详细信息或您提交的任何其他信息。保护用户免受此影响的最佳方法是通过安全连接(即,位于 https:// 地址)托管涉及表单的任何页面,这样数据在发送之前就会加密。

浏览器认识到通过不安全连接发送表单数据的安全隐患,并发出警告以阻止用户使用不安全的表单。有关 Firefox 实施的更多信息,请参阅 不安全密码

隐藏内容

另一个原始文本控件是 hidden 输入类型。它用于创建一个对用户不可见的表单控件,但在提交后仍与表单的其余数据一起发送到服务器——例如,您可能希望向服务器提交一个时间戳,说明订单何时下达。由于它是隐藏的,用户无法看到也无法有意编辑其值,它永远不会获得焦点,屏幕阅读器也不会注意到它。

html
<input type="hidden" id="timestamp" name="timestamp" value="1286705410" />

如果您创建此类元素,则需要设置其 namevalue 属性。该值可以通过 JavaScript 动态设置。hidden 输入类型不应具有关联的标签。

其他文本输入类型,如搜索URL电话,将在下一教程HTML5 输入类型中介绍。

可选择项:复选框和单选按钮

可选择项是您可以通过单击它们或其相关标签来更改状态的控件。可选择项有两种:复选框和单选按钮。两者都使用 checked 属性来指示小部件是否默认选中。

值得注意的是,这些小部件的行为并非完全与其他表单小部件相同。对于大多数表单小部件,一旦提交表单,所有带有 name 属性的小部件都会发送,即使没有填写值。在可选择项的情况下,它们的值仅在被选中时才发送。如果未选中,则不发送任何内容,甚至不发送它们的名称。如果选中但没有值,则名称会与一个值为 on 的值一起发送。

注意: 您可以在 GitHub 上找到本节的示例,网址为 checkable-items.html也可在线查看)。

为了最大化可用性/可访问性,建议您将每个相关的项目列表放在一个 <fieldset> 中,并使用 <legend> 提供列表的整体描述。每个单独的 <label>/<input> 元素对都应包含在其自己的列表项(或类似结构)中。关联的 <label> 通常放置在单选按钮或复选框之前或之后,而单选按钮或复选框组的说明通常是 <legend> 的内容。请参阅上面链接的示例以获取结构示例。

复选框

复选框是使用 <input> 元素创建的,其 type 属性设置为 checkbox 值。

html
<input type="checkbox" id="questionOne" name="subscribe" value="yes" checked />

相关的复选框项目应使用相同的 name 属性。包含 checked 属性会使复选框在页面加载时自动选中。单击复选框或其关联的标签会切换复选框的开/关状态。

html
<fieldset>
  <legend>Choose all the vegetables you like to eat</legend>
  <ul>
    <li>
      <label for="carrots">Carrots</label>
      <input
        type="checkbox"
        id="carrots"
        name="vegetable"
        value="carrots"
        checked />
    </li>
    <li>
      <label for="peas">Peas</label>
      <input type="checkbox" id="peas" name="vegetable" value="peas" />
    </li>
    <li>
      <label for="cabbage">Cabbage</label>
      <input type="checkbox" id="cabbage" name="vegetable" value="cabbage" />
    </li>
  </ul>
</fieldset>

以下截图显示了复选框在默认、聚焦和禁用状态下的样子。默认和禁用状态下的复选框显示为选中,而聚焦状态下的复选框未选中,其周围有一个聚焦环。

Default, focused and disabled Checkboxes in chrome 115 on macOS

注意: 任何在加载时带有 checked 属性的复选框和单选按钮都匹配 :default 伪类,即使它们不再被选中。任何当前被选中的都匹配 :checked 伪类。

由于复选框的开-关特性,复选框被认为是切换按钮,许多开发人员和设计师在默认复选框样式的基础上进行扩展,创建了看起来像切换开关的按钮。您可以在此处查看一个实际示例(另请参阅源代码)。

单选按钮

单选按钮是使用 <input> 元素创建的,其 type 属性设置为 radio 值。

html
<input type="radio" id="soup" name="meal" value="soup" checked />

多个单选按钮可以绑定在一起。如果它们共享相同的 name 属性值,则它们将被视为同一组按钮。在一个给定组中,一次只能选中一个按钮;这意味着当其中一个被选中时,所有其他按钮都会自动取消选中。当表单发送时,只发送被选中的单选按钮的值。如果没有一个被选中,则整个单选按钮池被视为处于未知状态,不发送任何值。一旦同一组中有一个单选按钮被选中,用户将无法在不重置表单的情况下取消选中所有按钮。

html
<fieldset>
  <legend>What is your favorite meal?</legend>
  <ul>
    <li>
      <label for="soup">Soup</label>
      <input type="radio" id="soup" name="meal" value="soup" checked />
    </li>
    <li>
      <label for="curry">Curry</label>
      <input type="radio" id="curry" name="meal" value="curry" />
    </li>
    <li>
      <label for="pizza">Pizza</label>
      <input type="radio" id="pizza" name="meal" value="pizza" />
    </li>
  </ul>
</fieldset>

以下截图显示了处于选中状态的默认和禁用单选按钮,以及处于未选中状态的聚焦单选按钮。

Default, focused and disabled Radio buttons in chrome 115 on macOS

实际按钮

单选按钮实际上并不是一个按钮,尽管它的名字如此;让我们继续看看实际的按钮!有三种输入类型会产生按钮:

submit

将表单数据发送到服务器。对于 <button> 元素,省略 type 属性(或 type 的无效值)将导致一个提交按钮。

reset

将所有表单小部件重置为其默认值。

button

没有自动效果但可以使用 JavaScript 代码自定义的按钮。

然后我们还有 <button> 元素本身。它可以接受 type 属性值 submitresetbutton,以模仿上述三种 <input> 类型的行为。两者之间的主要区别在于,实际的 <button> 元素更容易设置样式。

html
<p>Using &lt;input></p>
<p>
  <input type="submit" value="Submit this form" />
  <input type="reset" value="Reset this form" />
  <input type="button" value="Do Nothing without JavaScript" />
</p>
<p>Using &lt;button></p>
<p>
  <button type="submit">Submit this form</button>
  <button type="reset">Reset this form</button>
  <button type="button">Do Nothing without JavaScript</button>
</p>

注意: image 输入类型也呈现为按钮。我们稍后也会介绍。

注意: 您可以在 GitHub 上找到本节的示例,网址为 button-examples.html也可在线查看)。

下面您可以找到每种按钮 <input> 类型的示例,以及等效的 <button> 类型。

submit

html
<button type="submit">This is a <strong>submit button</strong></button>

<input type="submit" value="This is a submit button" />

reset

html
<button type="reset">This is a <strong>reset button</strong></button>

<input type="reset" value="This is a reset button" />

anonymous

html
<button type="button">This is an <strong>anonymous button</strong></button>

<input type="button" value="This is an anonymous button" />

无论您使用 <button> 元素还是 <input> 元素,按钮的行为都始终相同。但是,从示例中可以看出,<button> 元素允许您在其内容中使用 HTML,这些内容插入在开头和结尾的 <button> 标签之间。另一方面,<input> 元素是空元素;它们显示的内容插入在 value 属性内,因此只接受纯文本作为内容。

以下截图显示了按钮在默认、聚焦和禁用状态下的样子。在聚焦状态下,按钮周围有一个聚焦环,而在禁用状态下,按钮显示为灰色。

Default, focus, and disabled button states in chrome 115 on macOS

图像按钮

图像按钮控件的渲染方式与 <img> 元素完全相同,但当用户点击它时,它的行为类似于提交按钮。

图像按钮是使用 <input> 元素创建的,其 type 属性设置为 image 值。此元素支持与 <img> 元素完全相同的属性集,以及其他表单按钮支持的所有属性。

html
<input type="image" alt="Click me!" src="my-img.png" width="80" height="30" />

如果图像按钮用于提交表单,此控件不提交其值——相反,它会提交点击图像的 X 和 Y 坐标(坐标是相对于图像的,这意味着图像的左上角代表坐标 (0, 0))。坐标以两个键/值对的形式发送:

  • X 值键是 name 属性的值后跟字符串 ".x"。
  • Y 值键是 name 属性的值后跟字符串 ".y"。

例如,当您在坐标 (123, 456) 处点击图像并使用 get 方法提交时,您会看到这些值附加到 URL 中,如下所示:

url
http://foo.com?pos.x=123&pos.y=456

这是一种非常方便的构建“热图”的方法。这些值如何发送和检索在发送表单数据文章中详细介绍。

文件选择器

还有一种早期的 HTML <input> 类型:文件输入类型。表单能够将文件发送到服务器(此特定操作也在发送表单数据一文中详细介绍)。文件选择器小部件可用于选择一个或多个要发送的文件。

要创建文件选择器小部件,您可以使用 <input> 元素,其 type 属性设置为 file。接受的文件类型可以使用 accept 属性进行限制。此外,如果您想让用户选择多个文件,可以通过添加 multiple 属性来实现。

示例

在此示例中,创建了一个文件选择器,请求图形图像文件。在这种情况下,允许用户选择多个文件。

html
<input type="file" name="file" id="file" accept="image/*" multiple />

在某些移动设备上,文件选择器可以通过在 accept 属性中添加捕获信息来直接访问设备相机和麦克风捕获的照片、视频和音频,如下所示:

html
<input type="file" accept="image/*;capture=camera" />
<input type="file" accept="video/*;capture=camcorder" />
<input type="file" accept="audio/*;capture=microphone" />

下面的截图显示了文件选择器小部件在未选择文件时的默认、聚焦和禁用状态。

File picker widget in default, focus, and disabled states in chrome 115 on macOS

通用属性

许多用于定义表单控件的元素都有一些自己的特定属性。然而,有一组属性是所有表单元素通用的。您已经遇到过其中一些,但下面列出了这些通用属性,供您参考:

属性名称 默认值 描述
autofocus false 这个布尔属性允许你指定页面加载时元素是否应该自动获得输入焦点。文档中只有一个与表单关联的元素可以指定此属性。
disabled false 此布尔属性表示用户无法与该元素交互。如果未指定此属性,则该元素会从包含元素(例如 <fieldset>)继承其设置;如果没有包含设置了 disabled 属性的元素,则该元素被启用。
form 小部件关联的 <form> 元素,如果它未嵌套在该表单中则使用此属性。属性的值必须是同一文档中 <form> 元素的 id 属性。这允许您将表单控件与它外部的表单关联起来,即使它位于不同的表单元素中。
name 元素的名称;这与表单数据一起提交。
value 元素的初始值。

总结

本文介绍了较旧的输入类型——HTML 早期引入的原始集合,所有浏览器都很好地支持它们。在下一节中,我们将介绍 type 属性的更现代的值。