必须用@media (prefers-reduced-motion: reduce)全局重置动画属性,因该媒体查询仅支持reduce和no-preference两个标准值,写true、大小写错误或漏引号均导致规则被静默忽略;须用!important设animation:none、transition:none等关键属性以确保生效。

必须用 @media (prefers-reduced-motion: reduce) 全局重置动画属性,否则用户开启系统“减少动画”后,你的淡入、轮播、滚动视差仍会照常播放——这不是体验问题,是可访问性失效。
为什么 @media (prefers-reduced-motion: true) 完全不生效
这个媒体查询只接受两个标准化值:reduce 和 no-preference,没有布尔类型。写成 true、1、Reduce(大小写错误)或漏掉引号(如 reduce 不加引号),整条规则都会被浏览器静默忽略。DevTools 里该媒体查询块变灰,就是它没生效的明确信号。
怎么写才能真正禁掉动画,而不是“看起来停了”
常见错误是只加个空媒体查询,或只设 animation-duration: 0s。这会导致:某些浏览器跳过过渡、transform/opacity 状态残留、第三方组件动效未拦截。必须用 !important 覆盖关键属性:
-
animation设为none(不是none 0s,后者仍有解析开销) -
transition设为none(避免all 0.3s这类隐式声明在低端机上触发计算) - 通配符起步:
* { animation: none !important; transition: none !important; },再按需白名单放开(如加载 spinner 可保留) - 若需保留极简反馈,可用
opacity: 0.1s替代完整动效,但必须显式声明,不能依赖继承
移动端特别容易漏掉的三个 JS 动画场景
CSS 媒体查询拦不住 JS 控制的动画,而移动端这三处最容易出问题:
立即学习“前端免费学习笔记(深入)”;
- 页面内锚点跳转默认带滚动动画,应检测
window.matchMedia('(prefers-reduced-motion: reduce)').matches后强制设behavior: auto - 第三方库的动效(如 React Spring 默认配置、Bootstrap collapse)需手动覆写,或检查其是否支持
reduced-motion类名注入 -
requestAnimationFrame驱动的自定义动画(如视差滚动、手势拖拽反馈)必须主动判断匹配状态,跳过帧循环,否则照样触发晕动症
开发阶段必须真机+模拟双测
Chrome 和 Safari 开发者工具都支持强制启用 prefers-reduced-motion(Chrome:Rendering 面板 → Emulate CSS media feature;Safari:Develop → Rendering → Reduce Motion),但仅模拟不够。iOS 的“降低动态效果”和 Android 的“移除动画”开关路径不同,且部分安卓 WebView(如旧版微信)对 matchMedia 支持不全。真机测试时重点看:首屏加载是否闪动、滚动是否卡顿、第三方组件是否仍有微动——这些往往是 CSS 未覆盖到或 JS 监听延迟导致的。


















