transition必须写在元素默认样式中,且opacity需显式声明为0–1的数字;推荐搭配transform使用,并添加touch-action: manipulation适配移动端hover。
很多人写transition: opacity 0.3s却没效果,不是语法错,而是把transition放错了地方——它得写在元素的默认样式里,而不是:hover或.active这类状态规则中。浏览器需要知道“从什么时候开始过渡”,如果只在悬停时声明,第一次触发就没有过渡过程。
.box规则里写transition: opacity 0.25s ease-in-out
.box:hover里写transition
opacity值本身也必须显式声明,默认值1不能省略(哪怕和浏览器默认一致)opacity不接受百分比、关键词或inherit这类值。写成opacity: 50%或opacity: transparent都会让过渡失效,甚至导致回退到未定义行为。
opacity: 0、opacity: 0.7、opacity: 1
opacity: 50%、opacity: transparent、opacity: inherit
el.style.opacity = 0.4,别传字符串"0.4"(虽部分浏览器会转,但不可靠)单独用opacity过渡通常没问题,但如果还想动位置、缩放等,直接改top/left会触发布局重排。用transform配合opacity能走GPU合成层,性能更好,且两者可共用一个transition声明。
transition: opacity 0.3s ease, transform 0.3s ease
opacity: 0; transform: translateY(10px) → opacity: 1; transform: translateY(0)
all简写:transition: all 0.3s可能意外触发其他属性动画,尤其当元素有margin或width变化时在iOS Safari或安卓Chrome上,纯:hover经常不响应点击——这不是bug,是浏览器为避免误触延迟了伪类触发。解决办法很简单,但容易被忽略。
touch-action: manipulation到目标元素上pointer-events: none,否则:hover根本不会进入display: none替代opacity: 0:前者会移出文档流、丢失事件监听;后者保留占位和交互能力opacity声明和touch-action适配——这两个点一缺,效果就断在第一步。