transition 必须加在常态元素上,配合 transform 实现平滑位移;避免使用 top/margin 等触发重排的属性;选用合适缓动函数;并兼顾触屏设备的交互兼容性。

transition 要加在哪个元素上才生效
必须加在「常态元素」(非 :hover 状态)上,而不是只写在 :hover 里。如果只在 :hover 中写 transition,鼠标移入时动画可能触发,但移出时会立刻跳回原位——因为常态下没有过渡定义,浏览器直接硬切。
正确写法是:先给元素本体设好 transition,再在 :hover 中改 transform 值:
.box {
transform: translateX(0);
transition: transform 0.3s ease;
}
.box:hover {
transform: translateX(20px);
}
-
transition属性必须包含要过渡的属性名(如transform),不能只写transition: all 0.3s—— 这会导致意外性能问题,且部分浏览器对all的过渡行为不一致 - 不要给
position(如top/left)加transition来实现移动,它会触发重排(layout),而transform只触发重绘(paint)甚至合成(composite),更流畅
为什么用 transform 而不是 margin 或 top
用 margin、top、left 等布局属性做位移,每次变化都会导致浏览器重新计算元素位置和周围流式布局(即触发 layout),开销大,尤其在中低端设备或复杂页面中容易卡顿。
transform 是合成层操作,只要不改变文档流,GPU 就能高效处理平移、缩放、旋转等变换。
立即学习“前端免费学习笔记(深入)”;
- 确保目标元素没被其他样式强制降级(比如设置了
will-change: auto或有遮罩/滤镜干扰合成) - 如果元素本身用了
position: absolute且父容器未设transform: none,有时会意外创建新层叠上下文,影响动画层级——此时可加transform: translateZ(0)强制提升为合成层(但别滥用)
如何让 hover 动画真正「平滑」而非生硬
关键不在时长,而在缓动函数(timing function)的选择。默认的 ease 在起始和结束处减速明显,适合按钮反馈;但纯位移常需更线性或更柔和的节奏。
- 小位移(如图标微移 5–10px)推荐
cubic-bezier(0.25, 0.46, 0.45, 0.94)(类似ease-out,起始快、收尾柔) - 避免用
linear,它全程匀速,人眼感知反而像“滑出去”,缺乏自然感 - 如果需要悬停后保持偏移态,且鼠标离开时不反向动,就别依赖
:hover,改用 JS 切换 class +transition控制更稳妥
移动端 hover 不触发?得考虑触摸场景
CSS :hover 在多数触摸设备上不可靠:iOS Safari 只在点击后短暂模拟一次 hover;Android Chrome 表现也不一致。单纯靠 :hover + transform 无法覆盖真实用户操作路径。
- 若需兼容触屏,把交互逻辑下沉到 JS:监听
touchstart/pointerdown触发位移,touchend/pointerup恢复,同时保留:hover供桌面端使用(CSS 里写两个规则即可) - 别忘了加
@media (hover: hover)媒体查询来隔离桌面专属 hover 样式,防止触屏设备误加载 - 测试时真机连上 DevTools,禁用 hover 模拟,看实际表现——模拟器经常骗人


















