组件无障碍 a11y
学习目标
- 掌握语义化标签优先于 ARIA 的原则
- 理解
aria-*属性的典型用法 - 掌握自定义组件的键盘交互与焦点管理
语义化优先
能用原生元素就别用 div 模拟: <button> 自带键盘可聚焦与回车/空格触发,远胜 <div onClick>。读屏软件依赖语义角色(role)与名称(accessible name)来播报。
jsx
// ❌ 读屏无法识别这是可点击的
<div onClick={onClick}>删除</div>
// ✅ 自带 role=button、可聚焦、键盘触发
<button onClick={onClick}>删除</button>ARIA 何时用
当原生语义不够时再用 aria-*:
aria-label/aria-labelledby:给无文本控件提供可访问名称;aria-expanded:标记折叠状态;aria-live="polite":动态内容变化时通知读屏(如提示文案);role="dialog"+aria-modal:对话框。
jsx
<span aria-live="polite">{message}</span>键盘交互与焦点
自定义组件(如下拉、模态)必须实现键盘行为:
- 模态打开时把焦点移入、关闭时归还触发元素(
useRef+useEffect); Escape关闭模态;- 列表类组件实现方向键 /
Home/End导航(roving tabindex); - 用
onKeyDown而非onClick处理键盘(同时保留点击)。
jsx
function Modal({ onClose, children }) {
const ref = useRef(null);
useEffect(() => { ref.current?.focus(); return () => triggerRef.current?.focus(); }, []);
return <div role="dialog" aria-modal="true" ref={ref} onKeyDown={e => e.key === 'Escape' && onClose()}>{children}</div>;
}与表单的结合
错误提示用 aria-describedby 关联到输入框,读屏会在聚焦时朗读错误:
jsx
<input aria-describedby="err" aria-invalid={!!err} />
<span id="err">{err}</span>总结
a11y 的核心是「语义优先、ARIA 补位、键盘可达、焦点可控」。它应作为组件验收标准,而非事后补救——这与 33-错误边界实践进阶 同属「生产级组件」的必备素养。
继续阅读
- 上一篇:33-错误边界实践进阶
- 下一篇:00-表单验证