单选按钮组原生不支持方向键导航,仅支持tab/shift+tab切换焦点和空格键选中;若需方向键支持,应优先改用语义更优、原生支持↑↓导航的元素。

单选按钮组本身不支持方向键导航
原生 <input type="radio"> 没有键盘方向键(↑↓)切换功能。浏览器只对 <select></select> 下拉框、<button></button>、<input type="text"> 等可聚焦控件提供方向键支持,而单选按钮组默认只能用 Tab / Shift+Tab 切换焦点,空格键触发选中 —— 不能用上下箭头在同组内切换选项。
替代方案:用 <select></select> 替代单选按钮组
如果必须支持方向键快速选择,最直接的办法是改用 <select></select> 元素。它天然支持:
- 聚焦后按 ↑ ↓ 键逐项移动选中状态
- 按字母键跳转首字母匹配项(如按 “M” 跳到 “Male”)
- Space/Enter 展开下拉菜单,Esc 收起
- 无需 JS,纯 HTML 就生效
注意:这会改变 UI 形态(从横向按钮变成下拉菜单),但语义和可访问性更优。若设计不允许下拉形态,需 JS 补足。
用 JavaScript 实现方向键切换 radio 组
若坚持用 <input type="radio"> 且必须支持方向键,得手动监听 keydown 事件并控制焦点与选中状态。关键点:
- 确保所有 radio 都能获得焦点:加
tabindex="0"(默认 radio 只有在被 tab 进入时才可聚焦,无法用方向键主动跳转) - 监听父容器(如
<fieldset></fieldset>或<div>)的 <code>keydown,避免给每个 radio 单独绑事件 - 检测
event.key === 'ArrowDown'或'ArrowUp',然后找到当前选中的 radio,再定位下一个/上一个同 name 的兄弟元素 - 调用
nextRadio.focus()并设nextRadio.checked = true - 别忘了处理边界:到第一个时按 ↑ 应跳到最后一个(循环),或保持不动(更常见)
示例片段:
const radios = document.querySelectorAll('input[name="gender"]');
radios.forEach(r => r.tabIndex = 0);
document.querySelector('[name="gender"]').parentElement.addEventListener('keydown', e => {
if (!['ArrowUp', 'ArrowDown'].includes(e.key)) return;
const current = document.querySelector('input[name="gender"]:checked');
const idx = Array.from(radios).indexOf(current);
let nextIdx = e.key === 'ArrowDown' ? (idx + 1) % radios.length : (idx - 1 + radios.length) % radios.length;
radios[nextIdx].focus();
radios[nextIdx].checked = true;
});
为什么没人默认这么做?
方向键操作 radio 组不是无障碍标准要求的行为,WCAG 和浏览器厂商都未将其纳入原生支持范围。主流做法是:
- 用
<fieldset><legend></legend></fieldset>包裹 radio 组,提升语义 - 确保每个 radio 都有
<label></label>关联,支持点击文字选中 - 依赖 Tab 导航 + 空格选中,这是屏幕阅读器和键盘用户的事实标准流
强行加方向键支持反而可能干扰已有交互逻辑,比如打断表单内其他输入框的正常方向键行为。真正需要它的场景极少,优先检查是否误用了 radio 而非 <select></select>。











