前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
首页程序员面试题库prefers-reduced-motion 优化滚动与 JS 动画
CSS动画与视觉

除了 CSS 动画,prefers-reduced-motion 还能用在滚动行为和 JS 动画上吗?

prefers-reduced-motion 是媒体查询,CSS 和 JavaScript 都能读到。CSS 里可以把 scroll-behavior: smooth 降级成 auto,JavaScript 里用 matchMedia 检测后跳过 requestAnimationFrame 动画或缩短动画库的时长。

前端进阶之旅 · 一题精讲更新于 2026.09.29
CSS#动画与视觉#动画
先看核心答案读代码示例
理解线索

三个需要处理的动效来源

  1. CSS 过渡和动画在媒体查询里覆盖 transition 和 animation 声明
  2. 滚动行为scroll-behavior: smooth 要降级,锚点跳转也算动效
  3. JavaScript 动画matchMedia 检测后跳过或缩短 requestAnimationFrame 循环

很多人只处理了 CSS,忘了页面里还有 JavaScript 驱动的动画和平滑滚动。面试时能把三个来源都说到,回答就比较完整。

核心回答

先记住这个答案

prefers-reduced-motion 是一个系统级媒体查询,不只影响 transition 和 animation。CSS 里的 scroll-behavior: smooth 也算动效,应该在 reduce 模式下降级为瞬间跳转。JavaScript 动画需要用 window.matchMedia 主动检测,然后决定是跳过动画还是缩短时长。把这三个来源都处理好,才算真正响应了用户的偏好。

  • 减弱动效时可关闭平滑滚动
  • matchMedia 可监听偏好变化
  • 第三方动画库通常有全局配置项可以统一缩短时长
  • 用 CSS 自定义属性存时长值,一处改全局生效

用自定义属性统一管理动效时长

项目里动画散落在几十个组件里,逐条覆盖太麻烦。更好的做法是把时长提取成 CSS 自定义属性,在根节点定义默认值,媒体查询里统一改成接近零。

一处定义,全局生效CSS
:root {
  --duration: 300ms;
  --ease: ease;
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --duration: 0.01s; /* 几乎瞬间,但 transitionend 照常触发 */
    --ease: linear;
  }
}

.card {
  transition: transform var(--duration) var(--ease);
}

所有引用 --duration 的组件自动生效,不用写几十条媒体查询覆盖。新增组件时也只要引用同一个变量,减弱动效就自动带上了。

平滑滚动的降级

scroll-behavior: smooth 会让锚点跳转和 scrollIntoView 产生平滑滚动动画。对前庭障碍患者来说,整页的滚动运动和大幅位移动画一样容易引起不适。

在 reduce 模式下应该把它改回默认的 auto,跳转瞬间完成。如果你用 JavaScript 的 scrollIntoView({ behavior: 'smooth' }) 来滚动,也要根据检测结果把 behavior 改成 'auto'。

JavaScript 里检测并控制滚动JavaScript
const prefersReduced = window.matchMedia(
  '(prefers-reduced-motion: reduce)'
)

function scrollToSection(el) {
  el.scrollIntoView({
    behavior: prefersReduced.matches ? 'auto' : 'smooth'
  })
}

// 用户在系统设置里切换时实时响应
prefersReduced.addEventListener('change', () => {
  // 更新全局配置或重新渲染
})

matchMedia 返回的对象可以监听 change 事件,用户在系统偏好里切换时不用刷新页面就能生效。

JavaScript 动画库的处理

用 requestAnimationFrame 手写的动画、Framer Motion、GSAP 这类库不走 CSS 渲染管线,媒体查询写在样式表里对它们没用。需要在 JavaScript 里主动读取 prefersReduced.matches,为 true 时把动画时长设成 0 或直接跳到终态。

Framer Motion 可以在全局的 MotionConfig 上设置 reducedMotion="user",它会自动读取系统偏好。GSAP 没有内置支持,但可以在初始化时根据检测结果设 gsap.defaults({ duration: 0 })。

回答前,多想一步

容易答错的地方

以为 CSS 媒体查询能管住所有动画
CSS 媒体查询只作用于样式表里的声明。JavaScript 用 requestAnimationFrame 或 element.animate() 做的动画完全不受影响,必须在 JavaScript 里单独检测。
忘了 scroll-behavior
很多人答这道题只提到 transition 和 animation,忘了 scroll-behavior: smooth 也是动效。面试时能提到滚动降级,回答会更完整。
试着用自己的话回答

面试官还会怎么问?

matchMedia 的 change 事件在所有浏览器都支持吗?

现代浏览器都支持 addEventListener('change', ...)。旧的写法是 addListener,已经废弃但仍然能用。如果要兼容 IE,就轮询 matches 属性,不过 IE 本身也不支持 prefers-reduced-motion。

prefers-reduced-motion 和 prefers-reduced-transparency 有什么关系?

两者都是用户偏好媒体查询。prefers-reduced-motion 管动效,prefers-reduced-transparency 管半透明效果。后者浏览器支持较少,目前只有 Safari 实现了。它们互相独立,用户可以只开其中一个。

怎么在开发时测试减弱动效模式?

Chrome DevTools 的 Rendering 面板里可以模拟 prefers-reduced-motion: reduce,不用去系统设置里改。macOS 的路径是「系统设置 - 辅助功能 - 显示 - 减少动态效果」。

从一道题,走向一组知识

把知识连起来

动画与视觉

用 CSS 做打字机效果时,steps() 和线性过渡有什么区别?

steps() 打字机动画也需要考虑减弱动效,可以用同样的自定义属性方案统一管理。

动画与视觉

perspective 和 perspective-origin 怎么影响 CSS 3D 变换的视觉效果?

3D 变换的旋转和透视变化是最容易引起眩晕的动效类型,和本题的减弱策略直接相关。

参考资料

  • CSS:动画与视觉参考资料

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 用自定义属性统一管理动效时长
  3. 平滑滚动的降级
  4. JavaScript 动画库的处理
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑