Menu

HTML 单选按钮:分组、默认选中与样式

HTML 单选按钮的工作原理:用 name 属性分组,用 checked 设置默认选项,必选的按钮组,在 JavaScript 中读取选中的值,键盘操作,以及把它们设计成自定义圆点或卡片样式。

本页包含可运行的编辑器。编辑、运行,立即查看输出。

如何在 HTML 中创建单选按钮

单选按钮让用户在一组选项中只选一个。每个选项都是一个 <input type="radio">,给它们相同的 name,它们就成了一组。选择一个尺寸,然后点击 Order:

表单只发送一对数据 size=m:组的 name 和选中按钮的 value。各个组成部分:

  • 组内每个按钮都有相同的 name。选中一个,其他的就会取消选中。
  • 每个按钮都有不同的 value。服务器收到的就是这个值。没有 value 的单选按钮会发送 on,服务器从中得不到任何信息。
  • 默认选项上加 checked。
  • 每个按钮外面包一个 <label>,让文字也能点击;再用 <fieldset> 加 <legend>,让屏幕阅读器在读出每个选项时连同问题(“Size”)一起读出。

name 决定分组

name 不同的单选按钮属于不同的组,每组各自有一个选中项。下面的例子有两组,另外还有一组出错的按钮:每个按钮都被误设了不同的 name:

把出错那组的三个按钮都点一遍:它们全部保持选中,而且一个都取消不了,两边的缺点都占了。单选按钮在同一个表单内按 name 分组,所以两个表单可以各有一个 name="size" 的组。

必选组与不设默认值

组内任意一个单选按钮加上 required,就表示提交表单前必须选中其中一个。不写 checked 会让用户主动做出选择,在没有合理默认值时,这样做是对的:

不做选择就点击 Continue,浏览器会阻止提交并显示提示信息。只要选中任意一个选项,整个组就有效了。没有选中且不是必选的组什么都不会发送,和未勾选的复选框一样。

点击可以选中单选按钮,但永远无法取消选中。如果在做出选择之后还需要能“不回答”,就专门加一个对应的选项。

在 JavaScript 中读取选中的值

form.elements.name 返回整个组,它的 .value 就是选中的单选按钮的值(一个都没选中时为空字符串)。change 事件会在变为选中的那个单选按钮上触发:

监听器绑定在表单上,所以表单中任何字段的变化都能捕获到。在表单之外,可以用 document.querySelector('input[name="period"]:checked') 找到选中的单选按钮。

键盘操作

一组单选按钮在 Tab 键顺序中只占一站。按 Tab 进入这一组时,焦点落在选中的按钮上(一个都没选中时落在第一个上),然后用方向键在选项之间切换选中项。再按一次 Tab 就离开这一组。只要使用共享同一个 name 的真正的 radio 输入框,这些行为都是现成的,这也是不要用 <div> 元素重新实现单选按钮的又一个理由。

单选按钮的样式

accent-color 可以改变原生单选按钮的颜色。appearance: none 让你自己画圆点。而且隐藏起来的单选按钮仍然可以通过它的标签选中,所以一组按钮可以看起来像一组卡片,同时保留单选按钮的全部行为:

自定义圆点其实只是选中时变粗的边框。卡片用 opacity: 0 而不是 display: none 来隐藏输入框,这样它仍然可以获得焦点,方向键也照常可用;:has(input:checked) 则为选中的卡片设置样式。当前版本的 Chrome、Firefox 和 Safari 都支持 :has()。

单选按钮、复选框还是下拉列表?

用什么什么时候用
单选按钮从少量选项(大约 2 到 6 个)中选一个,并且所有选项都应该直接可见
复选框可以选任意多个,也可以一个都不选
<select>从一长串选项中选一个,比如国家(参见 HTML select)

常见错误

  • 同一组里用了不同的 name。每个单选按钮都能选中,却一个都取消不了。
  • 没有 value。无论选了什么,服务器收到的都是 on。
  • 在自定义设计中用 display: none 隐藏输入框。它将无法获得焦点,也无法用键盘操作。
  • 没有 <fieldset> 和 <legend>。屏幕阅读器只会读出“Small, radio button”,却没有对应的问题。
  • 用单个单选按钮做“我同意”勾选框。它一旦选中就无法取消;请使用复选框。
  • 同一组的多个单选按钮都加了 checked。最终只有最后一个被选中。

常见问题

如何在 HTML 中创建单选按钮?

每个选项写一个 <input type="radio">,给它们设置相同的 name 和不同的 value,再把每个按钮放进一个 <label>:<label><input type="radio" name="size" value="m"> Medium</label>。相同的 name 让它们成为一组,组内只能选中一个。

为什么我能同时选中多个单选按钮?

因为这些按钮的 name 不同。单选按钮只有在 name 完全相同(并且在同一个表单中)时才会组成一组,每组只能选中一个按钮。

如何在 JavaScript 中获取选中的单选按钮的值?

使用 form.elements.size.value,其中 size 是这一组的 name。它返回选中按钮的值,如果一个都没选中,则返回空字符串。没有表单时可以这样写:document.querySelector('input[name="size"]:checked')?.value。

如何设置默认选中的单选按钮?

给组内的某一个按钮加上 checked:<input type="radio" name="plan" value="free" checked>。如果有多个按钮都带了它,最后一个生效。

单选按钮可以取消选中吗?

点击不行,点击只能选中。你可以提供一个“无”选项、重置表单,或者在 JavaScript 中设置 button.checked = false。如果这个选择是可选的、可以撤销的,复选框或下拉列表可能更合适。

Coddy 编程语言插图

和 Coddy 一起学编程

开始