transition必须写在基础样式中,不能只放:hover里;否则移入有动画、移出无过渡而“啪”地弹回。正确做法是在默认样式中声明transform和transition,并显式设置初始scale值。

transition 必须写在基础样式里,不能只放 :hover 中
鼠标悬停时图标放大正常,一移开就“啪”地弹回原形——这说明 transition 被错误地写进了 :hover 选择器。浏览器只在进入状态时触发动画,离开时直接丢弃规则,根本不会过渡。
正确做法是把 transition 声明在元素默认样式中,确保进、出都受控:
svg.icon, i.icon {
transform: scale(1);
transition: transform 0.25s cubic-bezier(0.25, 0.8, 0.25, 1);
}
svg.icon:hover, i.icon:hover {
transform: scale(1.2);
}
-
transform是唯一推荐用于缩放的属性,不触发重排,天然 GPU 加速 - 别用
width/height或font-size做缩放过渡——前者强制重排,后者在某些字体下渲染不稳定 - 时间设 0.2–0.3s 较合适;太短没感知,太长像卡顿
用 transform: scale() 而不是 width/height
缩放类动效的核心原则:只动 transform 和 opacity。它们走合成层(compositor),不牵扯 layout/paint 流程,帧率稳、功耗低。
常见错误是这样写:
.icon { width: 24px; }
.icon:hover { width: 32px; transition: width 0.3s; }
这会导致每次 hover 都触发重排,尤其在列表中多个图标同时 hover 时,页面明显掉帧。
- 正确缩放路径:
transform: scale(1)→transform: scale(1.25) - 如果需保持点击热区不变,加
transform-origin: center防止位移偏移 - SVG 图标建议显式设置
viewBox和无单位尺寸,避免scale()下描边粗细异常
多个图标独立缩放时,避免父容器 overflow:hidden 截断动画
当一组图标放在 display: flex 或 inline-block 容器中,且设置了 overflow: hidden,悬停放大后图标边缘会被裁切——这不是动画问题,是布局限制。
典型场景:导航栏图标、工具栏按钮组。
- 解决方法:给图标容器加
overflow: visible,或改用position: relative+z-index提升图层 - 若必须保留父容器裁剪(如卡片封面),则改用
transform: scale()配合transform-origin: top left向内缩放,避开边缘 - 注意:
scale(1.2)实际占用空间仍是原始尺寸,视觉放大但不影响文档流——这点常被误认为“没放大”,其实是预期行为
transitionend 事件监听要按 propertyName 过滤
一个图标同时过渡 transform 和 opacity 时,transitionend 会触发两次。不加判断就执行回调,容易重复初始化、重复请求、状态错乱。
例如想在缩放完成时加载图标高亮态资源:
icon.addEventListener('transitionend', (e) => {
if (e.propertyName === 'transform') {
loadHighlightAsset();
}
});
- 永远检查
e.propertyName,不要只监听事件本身 - 避免用
setTimeout模拟完成时机——设备性能差异会导致误差 - 移动端需额外监听
touchstart替代mouseenter,否则首次点击无响应
transform 渲染路径和 transition 作用域的误判。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











