css 文字跳跃动画
文字跳动
animation: jump 1s cubic-bezier(0.58, 0.11, 0.63, 1.62) forwards var(–delay);
这条CSS动画属性非常精巧地创建了一个弹性跳跃效果,我来详细解析它的每个部分:
完整语法分解:
animation: jump 1s cubic-bezier(0.58, 0.11, 0.63, 1.62) forwards var(--delay);
1. 动画名称 jump
引用定义好的@keyframes jump
关键帧动画
2. 持续时间 1s
动画完整执行一次需要1秒钟
3. 缓动函数 cubic-bezier(0.58, 0.11, 0.63, 1.62)
这是最精妙的部分,这个三次贝塞尔曲线创造了独特的弹性效果:
- 起点控制点 (0.58, 0.11):使动画开始时快速上升
- 终点控制点 (0.63, 1.62):创造了"过冲"效果(overshoot),让元素会超过终点位置再弹回
- 效果类似弹簧被释放后的弹跳运动
4. 填充模式 forwards
动画结束后保持最后一帧的状态(保留to
关键帧的属性值)
5. 延迟时间 var(--delay)
使用CSS变量控制每个字符的动画延迟时间,实现依次跳跃效果
// 设置每个字符的延迟const spans = title.querySelectorAll('span');spans.forEach((span, spanIndex) => {span.style.setProperty('--delay', `${(titleIndex * 0.3) + (spanIndex * 0.1)}s`);});});
可视化理解这个缓动曲线:
这个特殊的cubic-bezier值会产生这样的运动轨迹:
- 快速向上加速(开始阶段)
- 超过目标位置(约120%的高度)
- 回弹到目标位置
- 轻微震荡后停止
对比标准缓动函数:
- 比
ease-out
更有弹性 - 比
elastic
类动画更简洁 - 比
bounce
效果更平滑
调试建议:
您可以通过Chrome DevTools的"Animation"面板:
- 点击"cubic-bezier"图标
- 拖动曲线控制点实时观察效果变化
- 比较不同参数对动画感觉的影响
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>改进版动画效果</title><style>body {display: flex;justify-content: center;align-items: center;min-height: 100vh;background-color: #f5f5f5;margin: 0;font-family: Arial, sans-serif;}.title-container {text-align: center;}.title {font-size: 42px;text-transform: uppercase;letter-spacing: 2px;transform: rotate(-10deg);display: flex;justify-content: center;margin: 10px 0;}.title span {display: inline-block;text-shadow: 1px 1px #533d4a, 2px 2px #533d4a, 3px 3px #533d4a, 4px 4px #533d4a, 5px 5px #533d4a;transform: skew(-10deg);animation: jump 1s cubic-bezier(0.58, 0.11, 0.63, 1.62) forwards var(--delay);opacity: 0;will-change: transform, opacity;transition: transform 0.2s ease;}.title span:hover {transform: skew(-10deg) translateY(-10px);}@keyframes jump {from {opacity: 0;transform: skew(-10deg) translateY(300%);}to {opacity: 1;transform: skew(-10deg) translateY(0%);}}.title:nth-child(1) {color: #e55643;}.title:nth-child(2) {color: #2b9f5e;}.title:nth-child(3) {color: #f1c83c;}@media (max-width: 768px) {.title {font-size: 32px;letter-spacing: 1px;}}@media (prefers-reduced-motion: reduce) {.title span {animation: none !important;opacity: 1 !important;}}</style>
</head>
<body><div class="title-container"><p class="title">这是一个</p><p class="title">长长的</p><p class="title">标题动画</p></div><script>document.addEventListener('DOMContentLoaded', () => {const titles = document.querySelectorAll('.title');titles.forEach((title, titleIndex) => {// 拆分文字为spantitle.innerHTML = title.textContent.split('').map(char => `<span>${char === ' ' ? ' ' : char}</span>`).join('');// 设置每个字符的延迟const spans = title.querySelectorAll('span');spans.forEach((span, spanIndex) => {span.style.setProperty('--delay', `${(titleIndex * 0.3) + (spanIndex * 0.1)}s`);});});});</script>
</body>
</html>