是,prefers-reduced-motion 不会自动覆盖 transition-duration,需主动用 @media (prefers-reduced-motion: reduce), print 规则将 transition-duration 和 animation-duration 设为 0.01s 以兼顾无障碍与兼容性。

prefers-reduced-motion 会覆盖 transition-duration 吗
会,但不是直接“禁用”,而是需要你主动响应。浏览器不会自动把 transition-duration: 0.3s 变成 0s;它只提供一个媒体查询信号,你得用 CSS 规则去拦截并重置。不写对应规则时,动画照常运行,对开启“减少动画”的用户造成不适甚至眩晕风险。
怎么写才真正尊重用户偏好
核心是两条规则叠加:系统设置 + 打印场景。Aniate.css 和主流设计系统都采用这个模式:
- 用
@media (prefers-reduced-motion: reduce), print包裹重置规则,不能只写reduce - 把
transition-duration设为0.01s或1ms,而非0s—— 避免触发浏览器某些过渡取消逻辑(比如 Safari 对0s的处理不一致) - 同时重置
animation-duration,因为很多过渡效果实际靠@keyframes驱动
示例:
@media (prefers-reduced-motion: reduce), print {
* {
transition-duration: 0.01s !important;
animation-duration: 0.01s !important;
}
}transition-duration 设太小会导致什么问题
设成 0s 看似最彻底,但容易出意外:
立即学习“前端免费学习笔记(深入)”;
-
0s在部分浏览器中可能让transitionend事件不触发,影响 JS 依赖该事件的逻辑(比如动画完成后的 DOM 清理) - 某些 CSS 框架(如 Tailwind)的
duration-0类本质是transition-duration: 0s,和prefers-reduced-motion规则冲突时优先级难控 -
0.01s或1ms能绕过这些边界情况,视觉上等效于无动画,又保留过渡机制完整性
要不要给所有 transition 都加无障碍适配
不需要一刀切。优先处理以下三类:
- 非交互触发的自动动画(比如轮播、通知弹出)
- 影响布局的过渡(
height、max-height、opacity+visibility组合) - 表单反馈类动效(校验成功/失败图标淡入、边框颜色变化)
像 :hover 下的 background-color 这种纯视觉微调,用户主动悬停才触发,通常无需干预 —— 除非它伴随大幅位移或旋转。
真正容易被忽略的点是:很多人只在全局样式里加了 prefers-reduced-motion 重置,却没检查组件库内部是否自带过渡规则。比如某个 UI 库的 .modal-open 类写了 transition: all 0.25s,你的重置规则若没用 !important 或足够高的选择器权重,就会失效。


















