本文详解如何在按钮点击后动态替换为可聚焦输入框时,确保键盘导航、屏幕阅读器提示和 aria 语义均符合 wcag 2.1 可访问性标准,涵盖 tabindex、aria-live、aria-expanded 等关键实践。
本文详解如何在按钮点击后动态替换为可聚焦输入框时,确保键盘导航、屏幕阅读器提示和 aria 语义均符合 wcag 2.1 可访问性标准,涵盖 tabindex、aria-live、aria-expanded 等关键实践。
实现一个“点击按钮 → 替换为输入框”的交互看似简单,但若忽视可访问性细节,将导致屏幕阅读器用户无法感知状态变化、键盘用户无法顺利操作,甚至违反 WCAG 2.1 成功准则(如 2.1.1 键盘、4.1.2 名称-角色-值、3.2.2 一致的识别)。以下是经过验证的专业实现方案:
<div role="group" aria-labelledby="edit-label"> <button id="edit-label" type="button" aria-expanded={isOpen} aria-controls="editable-input" onClick={() => setIsOpen(true)} > {isOpen ? 'Save changes' : 'Edit'} </button> {isOpen && ( <input id="editable-input" type="text" defaultValue={value} autoFocus onBlur={() => setIsOpen(false)} aria-label="Edit the content" // 必须声明 role="textbox" 以明确语义(尤其当父元素非 form) role="textbox" tabIndex={0} /> )}</div>
强制键盘可访问性
主动通知屏幕阅读器状态变更
仅靠 autoFocus 不足以保证播报。需结合 aria-live 区域提供上下文反馈:
// 在组件顶部或页面公共区域添加(不可隐藏!)<div aria-live="polite" aria-atomic="true" className="sr-only"> {isOpen ? 'Editing enabled. Type to modify, press Enter or Escape to confirm.' : ''}</div>
⚠️ 注意:aria-live="polite" 确保不打断当前语音;aria-atomic="true" 保证整句播报而非增量更新;.sr-only 是辅助技术可见但视觉隐藏的 CSS 类(position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;)。
遵循以上模式,不仅能通过 WCAG AA 级审计,更能为所有用户——无论是否依赖辅助技术——提供一致、可预测、可掌控的交互体验。