最核心的取舍点是用transform: translateY实现悬停上移而非margin/padding,因其走合成层、GPU加速、不触发重排;正确写法为初始transform: translateY(0),hover时transform: translateY(-8px)配transition: transform 0.3s ease-out。

hover时用transform: translateY上移,不是margin或padding
直接改margin-top或padding-top会触发重排(reflow),动画卡顿且影响布局流;而transform: translateY()走合成层,GPU加速,丝滑不抖动。这是最核心的取舍点。
常见错误是写成:margin-top: -10px + transition: margin 0.3s —— 看似简单,但每次变化都强制浏览器重新计算整个文档流,尤其在列表中多个卡片同时悬停时,掉帧明显。
- 正确写法:给卡片加
transform: translateY(0)作为初始状态,hover时改为transform: translateY(-8px) - 必须配
transition: transform 0.3s ease-out,否则只是瞬时跳变 - 如果卡片有阴影,建议同步过渡
box-shadow,否则悬停时阴影突兀出现
transition-duration别超过0.4s,timing-function优先用ease-out
超过0.4秒的升起动画会让人感觉迟滞,低于0.2秒又像“弹”一下,缺乏反馈感。0.25–0.35s是多数交互设计验证过的舒适区间。
ease-out比ease更合适:它让动画起始快、结束缓,模拟真实物体被托起后轻微回弹的物理感;而ease-in开头太慢,用户会误以为没响应。
立即学习“前端免费学习笔记(深入)”;
- 避免用
linear——机械感强,缺乏交互亲和力 - 慎用
cubic-bezier(0.25, 0.46, 0.45, 0.94)这类自定义曲线,除非你真在调交互动效,否则增加维护成本 - 移动端慎设
delay,悬停延迟在触摸设备上不可靠,iOS Safari甚至忽略transition-delay
别忘了transform-origin和z-index细节
默认transform-origin: 50% 50%对translateY没影响,但如果你后续叠加scale或rotate,中心点偏移会导致错位。统一显式声明更稳妥。
z-index容易被忽略:升起后卡片若被相邻元素遮挡,说明父容器没形成新的层叠上下文。常见解法是给卡片父容器加position: relative和z-index: 1,再给卡片本身设z-index: 2。
- 升起幅度建议控制在
translateY(-4px)到translateY(-10px)之间,太大显得浮夸,太小无感知 - 如果卡片含文字链接,升起后点击区域不变,但视觉上“抬高”了,用户心理预期会更强——这点比纯动画更重要
- 不要对
display或visibility做transition,它们不支持中间状态,强行写只会失效
移动端hover无效?得加:active和touch-action兜底
真机上:hover基本不可靠:iOS Safari只在伪悬停(长按)后短暂触发,安卓各厂商行为不一。纯靠:hover做升起效果,等于放弃移动端用户反馈。
必须补充:active样式,配合touch-action: manipulation禁用双击缩放,才能让点击瞬间有“按下-抬起”的升起/回落感。
- 示例:
.card:active { transform: translateY(-6px); }+style="touch-action: manipulation;" - 不要依赖
will-change: transform提前优化——它会常驻图层,多卡片时内存暴涨,Chrome已标记为“谨慎使用” - 如果项目需严格可访问性,升起效果不能是唯一反馈方式,还得配颜色变化或图标旋转等视觉冗余
ease-out的节奏感,而不是像素级位移值。


















