You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现可访问、不可修改的只读复选框与单选按钮?

可复用只读输入组件的可访问性实现方案推荐

我正在开发支持多种输入类型的可复用输入组件,需要确定可访问且不可修改的只读输入的推荐实现方案,典型场景是用户查看已提交表单内容的情况,核心问题是如何正确渲染这类输入。

核心限制与现有方案问题

  • readonly属性(包括aria-readonly)仅对文本类输入有效,对复选框(checkbox)和单选按钮(radio)完全无效,这类输入需要单独处理。
  • 使用disabled属性的问题:输入会被移出tab切换顺序,且disabled传达的是“输入无关”的状态,和“只读但相关”的需求不符。示例代码:
<label>
  <input type="checkbox" disabled />
  A checkbox
</label>
  • 非编辑模式下移除输入元素:文本输入容易实现,但对单选组这类输入,需要手动向屏幕阅读器传达“属于单选组、已选中”等原生语义,模拟成本高且容易出错。
  • aria-disabled="true"+手动阻止修改:同样无法准确传达“相关但不可编辑”的状态,语义上仍偏向“禁用”,示例代码:
<label>
  <input id="my-checkbox" type="checkbox" aria-disabled="true" />
  A checkbox
</label>
document.getElementById("my-checkbox")?.addEventListener("click", event => {
  event.preventDefault();
})

推荐实现方案

1. 文本类输入(input[type=text/email/url等]、textarea)

直接使用原生readonly属性,这是最优解:

  • 保留输入元素的tab聚焦顺序,用户可通过键盘访问
  • 原生语义明确,屏幕阅读器能正确识别“只读”状态
  • 无需额外JS阻止修改,浏览器原生支持
    示例代码:
<label for="username">用户名</label>
<input type="text" id="username" value="张三" readonly />

2. 复选框与单选按钮

这类输入无法使用readonly,推荐以下组合方案:

  • 保留原生输入元素,确保语义完整性(比如单选组的name属性关联、复选框的选中状态)
  • 添加aria-readonly="true",明确告知屏幕阅读器该输入为只读状态
  • 通过CSS移除交互样式(比如禁用鼠标指针变化)
  • 使用JavaScript阻止所有可能的修改操作(点击、键盘切换等)
  • 可选添加tabindex="0",确保输入可被键盘聚焦(如果需要让用户能通过tab访问到该控件)

示例代码(复选框):

<label>
  <input id="readonly-checkbox" type="checkbox" checked aria-readonly="true" tabindex="0" />
  已同意用户协议
</label>
#readonly-checkbox {
  pointer-events: none; /* 阻止鼠标交互 */
  opacity: 0.8; /* 视觉上区分只读状态 */
}
const checkbox = document.getElementById("readonly-checkbox");
if (checkbox) {
  // 阻止点击修改
  checkbox.addEventListener("click", e => e.preventDefault());
  // 阻止键盘切换(比如空格、回车)
  checkbox.addEventListener("keydown", e => {
    if (e.key === " " || e.key === "Enter") {
      e.preventDefault();
    }
  });
}

示例代码(单选组):

<fieldset>
  <legend>性别</legend>
  <label>
    <input type="radio" name="gender" value="male" checked aria-readonly="true" tabindex="0" />
    男
  </label>
  <label>
    <input type="radio" name="gender" value="female" aria-readonly="true" tabindex="0" />
    女
  </label>
</fieldset>
input[type="radio"][aria-readonly="true"] {
  pointer-events: none;
  opacity: 0.8;
}
const radios = document.querySelectorAll('input[type="radio"][aria-readonly="true"]');
radios.forEach(radio => {
  radio.addEventListener("click", e => e.preventDefault());
  radio.addEventListener("keydown", e => {
    if (["ArrowLeft", "ArrowRight", " ", "Enter"].includes(e.key)) {
      e.preventDefault();
    }
  });
});

方案优势

  • 保留原生输入的语义结构,屏幕阅读器能正确识别控件类型、组关系和选中状态
  • aria-readonly="true"准确传达“只读但相关”的状态,避免disabled的语义偏差
  • 保留tab聚焦能力(可选),符合可访问性要求
  • 视觉上通过CSS区分只读状态,用户能直观感知

内容的提问来源于stack exchange,提问作者Norah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 21:51:17