01好看和可用不是敌人
这个博客全站都是斜切、网点、闪烁、转场。但我给自己立了条硬规矩:所有动效都必须可被关掉,所有颜色都必须能被读懂。
02开工前的五条检查
prefers-reduced-motion必须真的生效,而不是写个空媒体查询- 所有可交互元素都能用 Tab 走到,焦点样式必须显眼(本站是红色虚线框)
- 颜色对比度:正文对背景 ≥ 4.5:1;纯红底上的白字要加描边或黑底衬
- 不靠颜色单独传达信息——标签同时有文字
- 自定义光标必须保留原生行为,键盘用户不受影响
css
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: .001s !important;
transition-duration: .001s !important;
animation-iteration-count: 1 !important;
}
}03自定义光标的坑
cursor: none 会让鼠标消失在所有地方——包括输入框和滚动条。两条必须守住的规矩:
- 只在精确指针设备上启用(触屏设备用系统光标)
- 显示和隐藏必须成对:自定义光标没画出来时,绝不能隐藏系统光标,否则用户会得到一个「不存在的鼠标」
css
@media (pointer: fine) {
body.p5-cursor, body.p5-cursor * { cursor: none !important; }
}js
// 只有确认开始绘制自定义光标,才加上这个 class
function show() {
if (shown) return;
shown = true;
cursor.style.display = 'block';
document.body.classList.add('p5-cursor');
}
function hide() {
if (!shown) return;
shown = false;
cursor.style.display = 'none';
document.body.classList.remove('p5-cursor');
}04测试清单
| 测试 | 方法 | 通过标准 |
|---|---|---|
| 键盘导航 | 只用 Tab / Enter / ↑↓ | 能到达全部功能 |
| 减弱动效 | 系统开启「减少动态效果」 | 无闪烁、无长动画 |
| 缩放 | 浏览器 200% | 不出现横向滚动条 |
| 对比度 | Lighthouse / axe | ≥ 90 分 |
05对比度别靠肉眼判断
红色的 #e60012 上放白字,对比度只有约 4.3:1,不达标。三种修法:
- 加描边或阴影,让文字与直接背景形成高对比
- 换成米白
#f6f4ef并把字重提到 700 - 红底只承载大字号(≥ 24px 且粗体,标准放宽到 3:1)
css
/* 红底白字的安全写法:四向描边 + 阴影 */
.badge {
background: var(--red);
color: #fff;
font-weight: 800;
text-shadow: 0 1px 0 #000, 0 -1px 0 #000, 1px 0 0 #000, -1px 0 0 #000;
}06焦点状态必须能被看见
outline: none 是这个行业最常见的错误之一。焦点框是你自己画的品牌资产,不是浏览器的累赘:
css
:focus-visible {
outline: 3px dashed var(--red);
outline-offset: 3px;
}