CSS 视觉与可用性(2025-2026 主流最佳实践)
1. 对比度(Contrast)—— 可访问性核心指标
WCAG 2.2 基本要求(2025-2026 仍然是主流标准):
| 级别 |
普通文本 (小文字 < 18px / 14px bold) |
大文字 (≥18px / ≥14px bold) |
图形/组件边界 |
推荐工具 |
| AA |
4.5 : 1 |
3 : 1 |
3 : 1 |
必须达标(绝大多数商业项目) |
| AAA |
7 : 1 |
4.5 : 1 |
4.5 : 1 |
追求极致无障碍 |
现代快速检查与实现方式(2025-2026 常用组合):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| :root { --primary: #6366f1; --primary-text: #ffffff; --primary-900: #312e81; --text: #0f172a; --text-light: #64748b; --bg: #ffffff; }
@media (forced-colors: active) { :root { --primary: CanvasText; --bg: Canvas; } }
.text-primary { color: var(--primary); } .bg-primary { background: var(--primary); color: white; } .text-on-primary { color: white; }
|
推荐工具(日常开发必备):
- WebAIM Contrast Checker
- Stark Figma 插件
- WAVE / axe DevTools
- Color Contrast Analyzer
2. 可见焦点(Visible Focus)—— 永远不要只用 outline: none
2025-2026 推荐写法(符合 WCAG 2.2 Success Criterion 2.4.7 & 9.1.4.11):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| :focus-visible { outline: none; box-shadow: 0 0 0 3px var(--focus-ring); border-radius: var(--radius-sm); }
:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
button:focus-visible, a:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible { box-shadow: 0 0 0 4px var(--primary-200); }
@media (prefers-contrast: more) { :focus-visible { outline: 3px solid currentColor; outline-offset: 3px; } }
|
重要原则:
- 永远不要
outline: none 而不提供替代方案
- 使用
:focus-visible 而不是 :focus(避免鼠标点击时出现焦点框)
- 焦点指示器至少要有 2px 粗细 + 对比度 ≥ 3:1
3. hover / active / focus 状态一致性
现代推荐交互状态顺序与风格统一(2025-2026 主流):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| .interactive { transition: all 0.15s ease; background: var(--bg-neutral); color: var(--text); border: 1px solid var(--border-neutral); }
.interactive:hover { background: var(--bg-neutral-hover); border-color: var(--border-hover); transform: translateY(-1px); box-shadow: 0 4px 12px rgba(0,0,0,0.08); }
.interactive:active { transform: translateY(0); box-shadow: inset 0 2px 4px rgba(0,0,0,0.1); background: var(--bg-neutral-active); }
.interactive:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--primary-200); }
.interactive:disabled, .interactive[aria-disabled="true"] { opacity: 0.55; cursor: not-allowed; box-shadow: none; transform: none; }
|
一致性建议:
- hover → 轻微抬升 + 背景变浅/变深
- active → 按下感(inset shadow 或 scale 微缩)
- focus → 外环(永远用 focus-visible)
- 所有状态保持相同 transition 时间(0.12s~0.2s)
4. 暗色/亮色模式切换(prefers-color-scheme)
2025-2026 主流实现方式(推荐组合):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| :root { --bg: #ffffff; --text: #0f172a; --card: #f8fafc; --border: #e2e8f0; --primary: #6366f1; }
@media (prefers-color-scheme: dark) { :root { --bg: #0f172a; --text: #e2e8f0; --card: #1e293b; --border: #334155; --primary: #818cf8; } }
[data-theme="dark"] { --bg: #0f172a; --text: #e2e8f0; }
[data-theme="light"] { }
html { color-scheme: light dark; }
|
常用技巧:
- 使用
color-scheme: light dark; 自动适配 <select> 等原生控件
- 所有颜色都尽量用 CSS 变量管理
- 测试时使用 DevTools → Rendering → Emulate CSS prefers-color-scheme
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| @media print { nav, footer, .no-print, .sidebar, .ads { display: none !important; }
body { font-size: 12pt; color: black; background: white; }
a { text-decoration: underline; color: black; }
a[href]:after { content: " (" attr(href) ")"; font-size: 0.85em; color: #666; }
h1, h2, h3, table, figure { page-break-inside: avoid; }
* { -webkit-print-color-adjust: exact; print-color-adjust: exact; color: black !important; background: white !important; } }
|
打印无障碍提示:
- 保留重要链接(显示 URL)
- 表格不要隐藏边框
- 字号不要太小(推荐 11pt~14pt 正文)
- 避免背景色(强制白底黑字)
总结:2025-2026 视觉与可用性核心口诀
- 对比度:文本 ≥4.5:1,大文字 ≥3:1
- 焦点:永远 :focus-visible + 3~4px 外环
- 交互:hover抬升 → active按下 → focus外环
- 暗色模式:CSS变量 + prefers-color-scheme + 手动切换
- 打印:隐藏导航/广告 + 显示链接 + 黑白高对比 + 防分页断裂