一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

怎样使用CSS prefers-reduced-motion提升可访问性

时间:2026-09-04 20:19:48 编辑:袖梨 来源:一聚教程网

@media (prefers-reduced-motion: reduce) 是唯一可靠入口,因浏览器仅识别 reduce 和 no-preference 两个值,其他写法均失效;iOS Safari 尤其严格,必须全小写带双引号的 "reduce"。

为什么@media (prefers-reduced-motion: reduce) 是唯一可靠入口

浏览器只认 reduceno-preference 两个值,写成 true1reduced 或漏掉引号(如 reduce 不加双引号),整条媒体查询直接失效——DevTools 里对应样式块会变灰,毫无作用。iOS Safari 尤其严格,必须是全小写带双引号的 "reduce"

animation 和 transition 怎么关才不破坏功能

粗暴加 * { animation: none !important; transition: none !important; } 会让下拉菜单突然撑开、模态框闪现、滚动容器失灵——因为结构依赖过渡维持状态。正确做法是分层控制:

  1. 纯视觉动画(loading spinner、背景轮播):用 animation: none 彻底停掉
  2. 结构过渡(菜单展开、折叠面板):保留 transition: max-height 0.01s linearopacity 0.01s,避免布局突变
  3. hover/focus 动效:显式重置 transform,例如 .btn:hover { transform: scale(1); transition: none; }
  4. 关键容器需强制瞬时切换:加 transform: none !important; opacity: 1 !important;,再交由 JS 控制显隐逻辑

JS 动画必须手动响应,CSS 媒体查询管不到它

@media 只影响 CSS 层动画,requestAnimationFramegsap.to()element.animate() 等完全不受控。必须主动监听并降级:

  1. 初始化获取状态:const motionQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
  2. 绑定变更事件:motionQuery.addEventListener("change", handleMotionChange)(Safari 14+ 支持,旧版无需兼容)
  3. 动效启动前判断:if (!motionQuery.matches) { startParallax() },而不是运行中暂停再恢复
  4. 骨架屏、轮播图等场景:直接设终态,例如 el.style.opacity = "1"; el.style.transform = "none";

最容易被忽略的是动画之外的基础可访问性

去掉动画后,文案是否仍可读、布局是否错乱、焦点是否丢失——这说明问题不在动画本身,而在基础语义和视觉层次设计上。动画只是表象,结构是否清晰、对比度是否足够、tab 顺序是否合理,才是根。尤其要注意骨架屏必须带 aria-hidden="true",且不能只写在外层容器;加载完成必须通过 aria-live 主动播报,否则屏幕阅读器用户根本不知道内容已就位。

热门栏目