css 过渡是否会影响可访问性_通过减少动态幅度提升可用性

应默认尊重系统“减少运动”偏好,用prefers-reduced-motion媒体查询强制降级动画时长与迭代次数,并避免依赖transitionend事件;关键交互需解耦状态变更与视觉反馈,且优先质疑动画必要性。

过渡动画会触发用户的前庭敏感或视觉疲劳

对部分用户来说,CSS transitionanimation 不只是“看起来更顺滑”,它们可能直接引发头晕、恶心或注意力涣散——尤其是涉及位移(transform: translate())、缩放(scale())或不规则旋转的动画。WCAG 2.2 明确将这类运动归为“可关闭、可暂停、可减少”的需求项。

prefers-reduced-motion 媒体查询主动降级动画

这不是“加个开关让用户自己关”,而是默认尊重系统级偏好。macOS、Windows 和 iOS 都提供“减少运动”全局开关,浏览器会通过 @media (prefers-reduced-motion) 暴露该状态。

@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

注意:0s 在某些旧版 Safari 中会被忽略,用 0.01ms 更可靠;!important 是必要的,否则组件内联样式或高优先级 CSS 可能覆盖它。

避免在关键交互路径中依赖过渡完成状态

比如用 transitionend 事件来触发下一步 DOM 操作(如删除元素、切换表单步骤),一旦用户启用了“减少运动”,这个事件可能永不触发——因为过渡被强制跳过,transitionend 不会派发。

  • 改用 setTimeout + 固定延时(需与 CSS 中的 transition-duration 同步维护)
  • 或改用 getComputedStyle(el).transitionDuration 动态读取,再做延时
  • 更稳妥的方式:把“状态变更”和“视觉反馈”解耦,用 class 切换控制状态,用 JS 控制是否启用过渡

“减少幅度”不等于“去掉动画”,而是控制变量范围

例如导航下划线从左到右滑动,原方案用 width: 0 → 100% + left: 0 → 100%,幅度大且含位移。可改为仅改变 width,并限制最大宽度为容器的 30%,同时将缓动函数换成更平缓的 cubic-bezier(0.33, 1, 0.68, 1)

.nav-underline {

width: 0; transition: width 0.3s cubic-bezier(0.33, 1, 0.68, 1); } @media (prefers-reduced-motion: reduce) { .nav-underline { transition: none; } }

真正容易被忽略的是:过渡的“起始/结束值”本身是否必要。很多所谓“动效优化”,其实第一步该问——这个变化,非得动吗?