focus:ring 必须配 focus:ring-offset-2 且父容器设 focus:ring-offset-white,否则聚焦环会溢出或发灰;禁用按钮必须用 disabled 属性而非仅样式;文字对比度须≥4.5:1,小按钮需确保 hover 与 focus 样式明显区分。

focus:ring 必须配 focus:ring-offset-2,且父容器要设 focus:ring-offset-white
键盘用户 tab 到按钮时,若只加 focus:ring-2 focus:ring-blue-500,蓝色环会贴着边框“溢出”,视觉上像偏移或断裂。根本原因是 ring 默认以元素自身为锚点绘制,没预留内边距空间。正确做法是:按钮加 focus:ring-offset-2,同时确保其最近的、有背景色的父容器(比如 div 或 nav)带 focus:ring-offset-white(或对应背景色)。否则在深色背景上 ring 会显黑边,白底上则可能看不见 offset 效果。
常见错误现象:
- 聚焦时蓝色环一半被裁切,或颜色发灰不清晰
- 用
focus:outline-none却没补 ring,导致键盘用户完全看不到焦点 - 父容器没设
focus:ring-offset-*,ring 渲染位置飘忽
禁用按钮必须用 disabled 属性,不能只靠 opacity-50 + cursor-not-allowed
disabled 是语义必需,仅靠样式无法让屏幕阅读器识别状态,也无法阻止键盘 Enter 或 Space 触发。若用 opacity-50 cursor-not-allowed 但没加 disabled,AT(辅助技术)仍会把它当可操作项朗读,用户可能反复尝试点击。
正确写法示例:
立即学习“前端免费学习笔记(深入)”;
<button class="bg-gray-400 text-white py-2 px-4 rounded opacity-50 cursor-not-allowed" disabled>提交</button>
注意:opacity-50 不是必须——有些设计规范要求禁用态保持 100% 不透明度(仅改颜色和 cursor),所以更稳妥的是用 bg-gray-300 text-gray-500 配合 cursor-not-allowed disabled。
文字对比度低于 4.5:1 会直接失败 WCAG AA 级
Tailwind 的 text-white 搭 bg-blue-500 是安全的(对比度约 4.9),但 text-gray-500 搭 bg-white 就只有约 3.2 —— 这在小字号文本中属于可访问性缺陷。别依赖“看起来还行”,要用工具验证。
实操建议:
- 用浏览器插件(如 axe DevTools)一键扫描对比度
- 深色背景慎用
text-gray-300,优先选text-gray-100或text-white - 按钮文字最小用
text-sm(14px),text-xs在非图标按钮中基本不可读 - 避免用
text-blue-400这类浅蓝配白底——它和白底对比度常低于 3.0
hover 和 focus 样式不能完全一致,否则键盘用户失去反馈差异
如果 hover:bg-blue-600 和 focus:bg-blue-600 完全一样,键盘用户 tab 进来时就看不出自己聚焦在哪。WCAG 要求焦点指示必须与悬停状态有明显区别(颜色、边框、阴影等任一维度)。
推荐组合:
- 悬停:加深背景
hover:bg-blue-600 - 聚焦:保留原背景 + 加环
focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 - 绝对不要写
hover:bg-blue-600 focus:bg-blue-600—— 这等于主动放弃键盘可访问性
真正难的不是写对类名,而是记住:每个 hover: 都得有个对应的、不冲突的 focus: 方案。按钮越小,这个区分越关键——因为小按钮上 ring 的视觉权重更高。


















