最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
怎样使用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) 是唯一可靠入口
浏览器只认 reduce 和 no-preference 两个值,写成 true、1、reduced 或漏掉引号(如 reduce 不加双引号),整条媒体查询直接失效——DevTools 里对应样式块会变灰,毫无作用。iOS Safari 尤其严格,必须是全小写带双引号的 "reduce"。
animation 和 transition 怎么关才不破坏功能
粗暴加 * { animation: none !important; transition: none !important; } 会让下拉菜单突然撑开、模态框闪现、滚动容器失灵——因为结构依赖过渡维持状态。正确做法是分层控制:
- 纯视觉动画(loading spinner、背景轮播):用
animation: none彻底停掉 - 结构过渡(菜单展开、折叠面板):保留
transition: max-height 0.01s linear或opacity 0.01s,避免布局突变 - hover/focus 动效:显式重置
transform,例如.btn:hover { transform: scale(1); transition: none; } - 关键容器需强制瞬时切换:加
transform: none !important; opacity: 1 !important;,再交由 JS 控制显隐逻辑
JS 动画必须手动响应,CSS 媒体查询管不到它
@media 只影响 CSS 层动画,requestAnimationFrame、gsap.to()、element.animate() 等完全不受控。必须主动监听并降级:
- 初始化获取状态:
const motionQuery = window.matchMedia('(prefers-reduced-motion: reduce)'); - 绑定变更事件:
motionQuery.addEventListener("change", handleMotionChange)(Safari 14+ 支持,旧版无需兼容) - 动效启动前判断:
if (!motionQuery.matches) { startParallax() },而不是运行中暂停再恢复 - 骨架屏、轮播图等场景:直接设终态,例如
el.style.opacity = "1"; el.style.transform = "none";
最容易被忽略的是动画之外的基础可访问性
去掉动画后,文案是否仍可读、布局是否错乱、焦点是否丢失——这说明问题不在动画本身,而在基础语义和视觉层次设计上。动画只是表象,结构是否清晰、对比度是否足够、tab 顺序是否合理,才是根。尤其要注意骨架屏必须带 aria-hidden="true",且不能只写在外层容器;加载完成必须通过 aria-live 主动播报,否则屏幕阅读器用户根本不知道内容已就位。