必须将transition写在基础选择器中,否则@media (prefers-reduced-motion: reduce)无法生效;因浏览器仅在起始与结束态均存在transition声明时才启用插值,若仅在:hover等状态类中定义,移出时无声明可回退,导致跳变。

必须把 transition 写在基础选择器里,再用 @media (prefers-reduced-motion: reduce) 统一设为 none,否则悬停或 class 切换时动画照常执行——这不是浏览器 bug,是 CSS 插值机制决定的。
为什么只加媒体查询却关不掉 transition
很多人把 transition 放在 :hover 或 .is-open 这类状态类里,以为加了 @media (prefers-reduced-motion: reduce) 就能覆盖。结果鼠标移出时直接跳变,悬停时仍有延迟位移。
根本原因是:浏览器只在起始态和结束态都声明了同一组 transition 时,才启用插值;如果基础规则没写 transition,那移入时靠 :hover 声明,移出时无声明可回退,就只能硬切——@media 根本没机会生效。
-
transition必须出现在元素默认状态(如.card)中,不能只藏在伪类或动态类里 - 媒体查询里的
transition: none是“覆盖”,不是“拦截”;覆盖的前提是原声明存在且可被匹配 - 第三方组件库(如 Ant Design、MUI)若把
transition写在.ant-collapse-content-active里,同样会失效
哪些属性必须一并禁用
prefers-reduced-motion: reduce 不是开关,而是提示你主动切断所有可能引发视觉运动的路径。光清 animation 不够,以下属性只要参与 transition,就得进黑名单:
-
transform:平移/缩放/旋转,最常用也最容易被忽略 -
opacity:渐隐渐显虽轻量,但快速切换仍可能诱发眩晕 -
width/height:触发布局重排,reduce 模式下抖动更明显 -
margin/padding:同上,布局变化比颜色更干扰 -
box-shadow和filter(如blur()、drop-shadow()):阴影扩散也算运动类动效
稳妥做法是统一写 transition: none,别尝试 transition-property: none——部分旧 Safari 对后者不识别。
transition: none 还是 transition-duration: 0.01ms
两者适用场景不同,选错会导致布局突变或兼容性问题:
- 用
transition: none:适合纯视觉反馈类动效(loading spinner、背景淡入),确保完全静止 - 用
transition-duration: 0.01ms:适合结构过渡类(下拉菜单、折叠面板),避免display: none → block导致的闪跳或高度坍塌 - 必须加
!important:否则容易被组件库内联样式或高权重选择器覆盖 - 别用
0s:某些旧版 Safari 对0s仍有微弱插值,0.01ms是最小非零安全值
示例:
@media (prefers-reduced-motion: reduce) {
.dropdown-menu, .accordion-panel {
transition-duration: 0.01ms !important;
}
.loading-spinner {
transition: none !important;
}
}
JS 动态插入元素怎么办
CSS 媒体查询对运行时插入的节点无效,比如 document.createElement('div') 后 append,它的 transition 依然会执行。
必须配合 JS 主动监听并打标:
- 用
window.matchMedia('(prefers-reduced-motion: reduce)')监听变化 - 回调中给
添加类名(如reduced-motion),而非直接改样式 - 后续所有动态元素的 CSS 规则都带上
html.reduced-motion前缀,例如:html.reduced-motion .card { transition: none; } - SSR 场景下,服务端无法读取该偏好,首次 hydrate 后需立即补一次判断
真正难的不是写出那行 @media,而是确认每个 transition 声明是否都被基础规则覆盖、是否被 JS 新增节点绕过、是否被第三方库的 scoped 样式或 CSS-in-JS 隐式注入漏掉。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











