| name | animation-library |
| description | CSS animation patterns library. Use when searching for keyframes, timing functions, or animation recipes for common UI patterns. |
Animation Library - Complete CSS Animation Patterns Reference
A comprehensive library of pre-built CSS animations, timing functions, and animation recipes for common UI patterns. This library includes 50+ animation patterns ready to use in your projects.
Table of Contents
- Fade Animations
- Slide Animations
- Scale Animations
- Rotate Animations
- Bounce Animations
- Flip Animations
- Shake & Wobble Animations
- Blur & Focus Animations
- Glow & Pulse Animations
- Swing & Pendulum Animations
- Timing Functions Reference
- Common UI Animation Recipes
- Scroll-Driven Animation Patterns
- Performance Patterns
- Accessibility Considerations
- Browser Compatibility Notes
- Troubleshooting Guide
Fade Animations
1. Fade In
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.fade-in {
animation: fadeIn 0.3s ease-in;
}
2. Fade Out
@keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
.fade-out {
animation: fadeOut 0.3s ease-out;
animation-fill-mode: forwards;
}
3. Fade In Up
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.fade-in-up {
animation: fadeInUp 0.5s ease-out;
}
4. Fade In Down
@keyframes fadeInDown {
from {
opacity: 0;
transform: translateY(-20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.fade-in-down {
animation: fadeInDown 0.5s ease-out;
}
5. Fade In Left
@keyframes fadeInLeft {
from {
opacity: 0;
transform: translateX(-20px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
.fade-in-left {
animation: fadeInLeft 0.5s ease-out;
}
6. Fade In Right
@keyframes fadeInRight {
from {
opacity: 0;
transform: translateX(20px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
.fade-in-right {
animation: fadeInRight 0.5s ease-out;
}
Slide Animations
7. Slide In Left
@keyframes slideInLeft {
from {
transform: translateX(-100%);
}
to {
transform: translateX(0);
}
}
.slide-in-left {
animation: slideInLeft 0.3s ease-out;
}
8. Slide In Right
@keyframes slideInRight {
from {
transform: translateX(100%);
}
to {
transform: translateX(0);
}
}
.slide-in-right {
animation: slideInRight 0.3s ease-out;
}
9. Slide In Up
@keyframes slideInUp {
from {
transform: translateY(100%);
}
to {
transform: translateY(0);
}
}
.slide-in-up {
animation: slideInUp 0.3s ease-out;
}
10. Slide In Down
@keyframes slideInDown {
from {
transform: translateY(-100%);
}
to {
transform: translateY(0);
}
}
.slide-in-down {
animation: slideInDown 0.3s ease-out;
}
11. Slide Out Left
@keyframes slideOutLeft {
from {
transform: translateX(0);
}
to {
transform: translateX(-100%);
}
}
.slide-out-left {
animation: slideOutLeft 0.3s ease-in;
animation-fill-mode: forwards;
}
Scale Animations
12. Scale In
@keyframes scaleIn {
from {
opacity: 0;
transform: scale(0.8);
}
to {
opacity: 1;
transform: scale(1);
}
}
.scale-in {
animation: scaleIn 0.3s ease-out;
}
13. Scale Out
@keyframes scaleOut {
from {
opacity: 1;
transform: scale(1);
}
to {
opacity: 0;
transform: scale(0.8);
}
}
.scale-out {
animation: scaleOut 0.3s ease-in;
animation-fill-mode: forwards;
}
14. Scale Up
@keyframes scaleUp {
from {
transform: scale(1);
}
to {
transform: scale(1.1);
}
}
.scale-up {
animation: scaleUp 0.2s ease-out;
animation-fill-mode: forwards;
}
15. Scale Down
@keyframes scaleDown {
from {
transform: scale(1);
}
to {
transform: scale(0.95);
}
}
.scale-down {
animation: scaleDown 0.2s ease-out;
animation-fill-mode: forwards;
}
16. Scale Bounce
@keyframes scaleBounce {
0% {
transform: scale(0);
}
50% {
transform: scale(1.15);
}
70% {
transform: scale(0.9);
}
100% {
transform: scale(1);
}
}
.scale-bounce {
animation: scaleBounce 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
}
Rotate Animations
17. Rotate In
@keyframes rotateIn {
from {
opacity: 0;
transform: rotate(-180deg);
}
to {
opacity: 1;
transform: rotate(0deg);
}
}
.rotate-in {
animation: rotateIn 0.5s ease-out;
}
18. Rotate 360
@keyframes rotate360 {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.rotate-360 {
animation: rotate360 1s linear infinite;
}
19. Rotate Scale In
@keyframes rotateScaleIn {
from {
opacity: 0;
transform: rotate(-180deg) scale(0);
}
to {
opacity: 1;
transform: rotate(0deg) scale(1);
}
}
.rotate-scale-in {
animation: rotateScaleIn 0.5s ease-out;
}
20. Rotate Y (3D Flip)
@keyframes rotateY {
from {
transform: perspective(1000px) rotateY(0deg);
}
to {
transform: perspective(1000px) rotateY(360deg);
}
}
.rotate-y {
animation: rotateY 0.8s ease-in-out;
}
21. Rotate X (3D Flip)
@keyframes rotateX {
from {
transform: perspective(1000px) rotateX(0deg);
}
to {
transform: perspective(1000px) rotateX(360deg);
}
}
.rotate-x {
animation: rotateX 0.8s ease-in-out;
}
Bounce Animations
22. Bounce In
@keyframes bounceIn {
0% {
opacity: 0;
transform: scale(0.3);
}
50% {
opacity: 1;
transform: scale(1.05);
}
70% {
transform: scale(0.9);
}
100% {
transform: scale(1);
}
}
.bounce-in {
animation: bounceIn 0.6s cubic-bezier(0.68, -0.55, 0.265, 1.55);
}
23. Bounce
@keyframes bounce {
0%, 20%, 50%, 80%, 100% {
transform: translateY(0);
}
40% {
transform: translateY(-20px);
}
60% {
transform: translateY(-10px);
}
}
.bounce {
animation: bounce 2s infinite;
}
24. Bounce In Up
@keyframes bounceInUp {
0% {
opacity: 0;
transform: translateY(100px);
}
60% {
opacity: 1;
transform: translateY(-10px);
}
80% {
transform: translateY(5px);
}
100% {
transform: translateY(0);
}
}
.bounce-in-up {
animation: bounceInUp 0.8s ease-out;
}
25. Bounce In Down
@keyframes bounceInDown {
0% {
opacity: 0;
transform: translateY(-100px);
}
60% {
opacity: 1;
transform: translateY(10px);
}
80% {
transform: translateY(-5px);
}
100% {
transform: translateY(0);
}
}
.bounce-in-down {
animation: bounceInDown 0.8s ease-out;
}
Flip Animations
26. Flip In X
@keyframes flipInX {
from {
transform: perspective(400px) rotateX(90deg);
opacity: 0;
}
40% {
transform: perspective(400px) rotateX(-10deg);
}
70% {
transform: perspective(400px) rotateX(10deg);
}
100% {
transform: perspective(400px) rotateX(0deg);
opacity: 1;
}
}
.flip-in-x {
animation: flipInX 0.75s ease-out;
backface-visibility: visible;
}
27. Flip In Y
@keyframes flipInY {
from {
transform: perspective(400px) rotateY(90deg);
opacity: 0;
}
40% {
transform: perspective(400px) rotateY(-10deg);
}
70% {
transform: perspective(400px) rotateY(10deg);
}
100% {
transform: perspective(400px) rotateY(0deg);
opacity: 1;
}
}
.flip-in-y {
animation: flipInY 0.75s ease-out;
backface-visibility: visible;
}
28. Flip
@keyframes flip {
from {
transform: perspective(400px) rotateY(0);
}
to {
transform: perspective(400px) rotateY(180deg);
}
}
.flip {
animation: flip 0.6s ease-in-out;
}
Shake & Wobble Animations
29. Shake
@keyframes shake {
0%, 100% {
transform: translateX(0);
}
10%, 30%, 50%, 70%, 90% {
transform: translateX(-10px);
}
20%, 40%, 60%, 80% {
transform: translateX(10px);
}
}
.shake {
animation: shake 0.6s ease-in-out;
}
30. Shake Vertical
@keyframes shakeVertical {
0%, 100% {
transform: translateY(0);
}
10%, 30%, 50%, 70%, 90% {
transform: translateY(-8px);
}
20%, 40%, 60%, 80% {
transform: translateY(8px);
}
}
.shake-vertical {
animation: shakeVertical 0.6s ease-in-out;
}
31. Wobble
@keyframes wobble {
0% {
transform: translateX(0) rotate(0deg);
}
15% {
transform: translateX(-25%) rotate(-5deg);
}
30% {
transform: translateX(20%) rotate(3deg);
}
45% {
transform: translateX(-15%) rotate(-3deg);
}
60% {
transform: translateX(10%) rotate(2deg);
}
75% {
transform: translateX(-5%) rotate(-1deg);
}
100% {
transform: translateX(0) rotate(0deg);
}
}
.wobble {
animation: wobble 0.8s ease-in-out;
}
32. Jello
@keyframes jello {
0%, 100% {
transform: skewX(0deg) skewY(0deg);
}
30% {
transform: skewX(25deg) skewY(25deg);
}
40% {
transform: skewX(-15deg) skewY(-15deg);
}
50% {
transform: skewX(15deg) skewY(15deg);
}
65% {
transform: skewX(-5deg) skewY(-5deg);
}
75% {
transform: skewX(5deg) skewY(5deg);
}
}
.jello {
animation: jello 0.9s ease-in-out;
}
33. Rubber Band
@keyframes rubberBand {
0% {
transform: scaleX(1);
}
30% {
transform: scaleX(1.25) scaleY(0.75);
}
40% {
transform: scaleX(0.75) scaleY(1.25);
}
50% {
transform: scaleX(1.15) scaleY(0.85);
}
65% {
transform: scaleX(0.95) scaleY(1.05);
}
75% {
transform: scaleX(1.05) scaleY(0.95);
}
100% {
transform: scaleX(1) scaleY(1);
}
}
.rubber-band {
animation: rubberBand 1s ease-in-out;
}
Blur & Focus Animations
34. Blur In
@keyframes blurIn {
from {
filter: blur(10px);
opacity: 0;
}
to {
filter: blur(0);
opacity: 1;
}
}
.blur-in {
animation: blurIn 0.6s ease-out;
}
35. Blur Out
@keyframes blurOut {
from {
filter: blur(0);
opacity: 1;
}
to {
filter: blur(10px);
opacity: 0;
}
}
.blur-out {
animation: blurOut 0.6s ease-out;
animation-fill-mode: forwards;
}
36. Focus In
@keyframes focusIn {
from {
filter: blur(12px);
opacity: 0;
transform: scale(0.95);
}
to {
filter: blur(0);
opacity: 1;
transform: scale(1);
}
}
.focus-in {
animation: focusIn 0.8s ease-out;
}
Glow & Pulse Animations
37. Pulse
@keyframes pulse {
0% {
transform: scale(1);
}
50% {
transform: scale(1.05);
}
100% {
transform: scale(1);
}
}
.pulse {
animation: pulse 2s ease-in-out infinite;
}
38. Pulse Glow
@keyframes pulseGlow {
0% {
box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.7);
}
70% {
box-shadow: 0 0 0 10px rgba(59, 130, 246, 0);
}
100% {
box-shadow: 0 0 0 0 rgba(59, 130, 246, 0);
}
}
.pulse-glow {
animation: pulseGlow 2s infinite;
}
39. Glow
@keyframes glow {
0%, 100% {
filter: drop-shadow(0 0 2px currentColor);
}
50% {
filter: drop-shadow(0 0 20px currentColor);
}
}
.glow {
animation: glow 2s ease-in-out infinite;
}
40. Heartbeat
@keyframes heartbeat {
0% {
transform: scale(1);
}
14% {
transform: scale(1.3);
}
28% {
transform: scale(1);
}
42% {
transform: scale(1.3);
}
70% {
transform: scale(1);
}
}
.heartbeat {
animation: heartbeat 1.3s ease-in-out infinite;
}
Swing & Pendulum Animations
41. Swing
@keyframes swing {
20% {
transform: rotate(15deg);
}
40% {
transform: rotate(-10deg);
}
60% {
transform: rotate(5deg);
}
80% {
transform: rotate(-5deg);
}
100% {
transform: rotate(0deg);
}
}
.swing {
transform-origin: top center;
animation: swing 1s ease-in-out;
}
42. Tada
@keyframes tada {
0% {
transform: scale(1) rotate(0deg);
}
10%, 20% {
transform: scale(0.9) rotate(-3deg);
}
30%, 50%, 70%, 90% {
transform: scale(1.1) rotate(3deg);
}
40%, 60%, 80% {
transform: scale(1.1) rotate(-3deg);
}
100% {
transform: scale(1) rotate(0deg);
}
}
.tada {
animation: tada 1s ease-in-out;
}
Advanced Animations
43. Zoom In
@keyframes zoomIn {
from {
opacity: 0;
transform: scale(0.3);
}
50% {
opacity: 1;
}
to {
transform: scale(1);
}
}
.zoom-in {
animation: zoomIn 0.5s ease-out;
}
44. Zoom Out
@keyframes zoomOut {
from {
opacity: 1;
transform: scale(1);
}
50% {
opacity: 0;
transform: scale(0.3);
}
to {
opacity: 0;
}
}
.zoom-out {
animation: zoomOut 0.5s ease-in;
animation-fill-mode: forwards;
}
45. Roll In
@keyframes rollIn {
from {
opacity: 0;
transform: translateX(-100%) rotate(-120deg);
}
to {
opacity: 1;
transform: translateX(0) rotate(0deg);
}
}
.roll-in {
animation: rollIn 0.6s ease-out;
}
46. Roll Out
@keyframes rollOut {
from {
opacity: 1;
transform: translateX(0) rotate(0deg);
}
to {
opacity: 0;
transform: translateX(100%) rotate(120deg);
}
}
.roll-out {
animation: rollOut 0.6s ease-in;
animation-fill-mode: forwards;
}
47. Light Speed In Right
@keyframes lightSpeedInRight {
from {
transform: translateX(100%) skewX(-30deg);
opacity: 0;
}
60% {
transform: skewX(20deg);
opacity: 1;
}
80% {
transform: skewX(-5deg);
}
100% {
transform: translateX(0) skewX(0deg);
}
}
.light-speed-in-right {
animation: lightSpeedInRight 0.6s ease-out;
}
48. Hinge
@keyframes hinge {
0% {
transform-origin: top left;
animation-timing-function: ease-in-out;
}
20%, 60% {
transform: rotate(80deg);
transform-origin: top left;
animation-timing-function: ease-in-out;
}
40%, 80% {
transform: rotate(60deg);
transform-origin: top left;
animation-timing-function: ease-in-out;
opacity: 1;
}
100% {
transform: translateY(700px);
opacity: 0;
}
}
.hinge {
animation: hinge 2s ease-in-out;
animation-fill-mode: forwards;
}
49. Jack In The Box
@keyframes jackInTheBox {
from {
opacity: 0;
transform: scale(0.1) rotate(30deg);
transform-origin: center bottom;
}
50% {
transform: rotate(-10deg);
}
70% {
transform: rotate(3deg);
}
to {
opacity: 1;
transform: scale(1) rotate(0deg);
}
}
.jack-in-the-box {
animation: jackInTheBox 0.8s ease-out;
}
50. Flash
@keyframes flash {
0%, 50%, 100% {
opacity: 1;
}
25%, 75% {
opacity: 0;
}
}
.flash {
animation: flash 1s ease-in-out;
}
Timing Functions Reference
CSS Timing Function Presets
.timing-linear {
animation-timing-function: linear;
}
.timing-ease {
animation-timing-function: ease;
}
.timing-ease-in {
animation-timing-function: ease-in;
}
.timing-ease-out {
animation-timing-function: ease-out;
}
.timing-ease-in-out {
animation-timing-function: ease-in-out;
}
Custom Cubic Bezier Functions
.timing-elastic {
animation-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55);
}
.timing-fast-out-slow-in {
animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}
.timing-linear-out-slow-in {
animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
}
.timing-fast-out-linear-in {
animation-timing-function: cubic-bezier(0.4, 0, 1, 1);
}
.timing-smooth {
animation-timing-function: cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.timing-snap {
animation-timing-function: cubic-bezier(0, 1.5, 1, 1.5);
}
.timing-anticipate {
animation-timing-function: cubic-bezier(0.36, 0, 0.66, -0.56);
}
.timing-overshoot {
animation-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1);
}
Steps Timing Function
.timing-steps-start {
animation-timing-function: steps(4, jump-start);
}
.timing-steps-end {
animation-timing-function: steps(4, jump-end);
}
.timing-steps-both {
animation-timing-function: steps(4, jump-both);
}
.timing-steps-none {
animation-timing-function: steps(4, jump-none);
}
Common UI Animation Recipes
Modal/Dialog Animations
@keyframes modalBackdropFadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes modalContentScaleIn {
from {
opacity: 0;
transform: scale(0.9) translateY(-20px);
}
to {
opacity: 1;
transform: scale(1) translateY(0);
}
}
.modal-backdrop {
animation: modalBackdropFadeIn 0.2s ease-out;
}
.modal-content {
animation: modalContentScaleIn 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}
@keyframes modalBackdropFadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
@keyframes modalContentScaleOut {
from {
opacity: 1;
transform: scale(1) translateY(0);
}
to {
opacity: 0;
transform: scale(0.9) translateY(-20px);
}
}
.modal-backdrop-exit {
animation: modalBackdropFadeOut 0.2s ease-in;
animation-fill-mode: forwards;
}
.modal-content-exit {
animation: modalContentScaleOut 0.2s ease-in;
animation-fill-mode: forwards;
}
Toast/Notification Animations
@keyframes toastSlideIn {
from {
transform: translateY(-100%) translateX(-50%);
opacity: 0;
}
to {
transform: translateY(0) translateX(-50%);
opacity: 1;
}
}
@keyframes toastSlideOut {
from {
transform: translateY(0) translateX(-50%);
opacity: 1;
}
to {
transform: translateY(-100%) translateX(-50%);
opacity: 0;
}
}
.toast-enter {
animation: toastSlideIn 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}
.toast-exit {
animation: toastSlideOut 0.2s ease-in;
animation-fill-mode: forwards;
}
@keyframes toastSlideInBottom {
from {
transform: translateY(100%);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
.toast-bottom {
animation: toastSlideInBottom 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}
Dropdown Menu Animations
@keyframes dropdownFadeIn {
from {
opacity: 0;
transform: scaleY(0.95) translateY(-10px);
transform-origin: top;
}
to {
opacity: 1;
transform: scaleY(1) translateY(0);
transform-origin: top;
}
}
@keyframes dropdownFadeOut {
from {
opacity: 1;
transform: scaleY(1) translateY(0);
transform-origin: top;
}
to {
opacity: 0;
transform: scaleY(0.95) translateY(-10px);
transform-origin: top;
}
}
.dropdown-enter {
animation: dropdownFadeIn 0.15s cubic-bezier(0.16, 1, 0.3, 1);
}
.dropdown-exit {
animation: dropdownFadeOut 0.1s ease-in;
animation-fill-mode: forwards;
}
Accordion/Collapse Animations
@keyframes accordionExpand {
from {
max-height: 0;
opacity: 0;
}
to {
max-height: 1000px;
opacity: 1;
}
}
@keyframes accordionCollapse {
from {
max-height: 1000px;
opacity: 1;
}
to {
max-height: 0;
opacity: 0;
}
}
.accordion-expand {
animation: accordionExpand 0.3s ease-out;
overflow: hidden;
}
.accordion-collapse {
animation: accordionCollapse 0.3s ease-in;
animation-fill-mode: forwards;
overflow: hidden;
}
Skeleton Loading Animation
@keyframes shimmer {
0% {
background-position: -1000px 0;
}
100% {
background-position: 1000px 0;
}
}
.skeleton {
background: linear-gradient(
90deg,
#f0f0f0 0%,
#f8f8f8 50%,
#f0f0f0 100%
);
background-size: 1000px 100%;
animation: shimmer 2s infinite linear;
}
@keyframes skeletonPulse {
0%, 100% {
opacity: 1;
}
50% {
opacity: 0.5;
}
}
.skeleton-pulse {
background: #f0f0f0;
animation: skeletonPulse 1.5s ease-in-out infinite;
}
Tooltip Animations
@keyframes tooltipFadeIn {
from {
opacity: 0;
transform: translateY(5px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.tooltip-enter {
animation: tooltipFadeIn 0.2s cubic-bezier(0.16, 1, 0.3, 1);
}
@keyframes tooltipFadeInTop {
from {
opacity: 0;
transform: translateY(-5px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes tooltipFadeInLeft {
from {
opacity: 0;
transform: translateX(-5px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes tooltipFadeInRight {
from {
opacity: 0;
transform: translateX(5px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
Card Hover Effects
.card {
transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1),
box-shadow 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}
.card:hover {
transform: translateY(-8px);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15);
}
.card-flip-container {
perspective: 1000px;
}
@keyframes cardFlip {
from {
transform: rotateY(0deg);
}
to {
transform: rotateY(180deg);
}
}
.card-flip {
transition: transform 0.6s;
transform-style: preserve-3d;
}
.card-flip:hover {
transform: rotateY(180deg);
}
.card-front,
.card-back {
backface-visibility: hidden;
}
.card-back {
transform: rotateY(180deg);
}
Button Press Animation
.button {
transition: transform 0.1s cubic-bezier(0.16, 1, 0.3, 1),
box-shadow 0.1s cubic-bezier(0.16, 1, 0.3, 1);
}
.button:active {
transform: scale(0.96);
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
}
@keyframes ripple {
to {
transform: scale(4);
opacity: 0;
}
}
.button-ripple {
position: relative;
overflow: hidden;
}
.button-ripple::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 100px;
height: 100px;
background: rgba(255, 255, 255, 0.5);
border-radius: 50%;
transform: translate(-50%, -50%) scale(0);
opacity: 0;
pointer-events: none;
}
.button-ripple:active::after {
animation: ripple 0.6s ease-out;
}
Page Transition Animations
@keyframes pageFadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes pageFadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
.page-enter {
animation: pageFadeIn 0.3s ease-out;
}
.page-exit {
animation: pageFadeOut 0.3s ease-in;
}
@keyframes pageSlideInRight {
from {
transform: translateX(100%);
}
to {
transform: translateX(0);
}
}
@keyframes pageSlideOutLeft {
from {
transform: translateX(0);
}
to {
transform: translateX(-100%);
}
}
.page-slide-enter {
animation: pageSlideInRight 0.4s cubic-bezier(0.16, 1, 0.3, 1);
}
.page-slide-exit {
animation: pageSlideOutLeft 0.4s cubic-bezier(0.16, 1, 0.3, 1);
animation-fill-mode: forwards;
}
Loading Spinner Animations
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.spinner {
animation: spin 1s linear infinite;
}
@keyframes dotPulse {
0%, 80%, 100% {
opacity: 0.3;
transform: scale(0.8);
}
40% {
opacity: 1;
transform: scale(1);
}
}
.dot-loader .dot:nth-child(1) {
animation: dotPulse 1.4s ease-in-out infinite;
}
.dot-loader .dot:nth-child(2) {
animation: dotPulse 1.4s ease-in-out 0.2s infinite;
}
.dot-loader .dot:nth-child(3) {
animation: dotPulse 1.4s ease-in-out 0.4s infinite;
}
@keyframes progressIndeterminate {
0% {
transform: translateX(-100%);
}
100% {
transform: translateX(400%);
}
}
.progress-indeterminate {
animation: progressIndeterminate 1.5s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite;
}
Scroll-Driven Animation Patterns
Scroll-Triggered Fade In
.scroll-fade {
opacity: 0;
transform: translateY(30px);
transition: opacity 0.6s ease-out,
transform 0.6s ease-out;
}
.scroll-fade.in-view {
opacity: 1;
transform: translateY(0);
}
.scroll-fade.in-view .stagger-item {
animation: fadeInUp 0.6s ease-out backwards;
}
.scroll-fade.in-view .stagger-item:nth-child(1) { animation-delay: 0.1s; }
.scroll-fade.in-view .stagger-item:nth-child(2) { animation-delay: 0.2s; }
.scroll-fade.in-view .stagger-item:nth-child(3) { animation-delay: 0.3s; }
.scroll-fade.in-view .stagger-item:nth-child(4) { animation-delay: 0.4s; }
Parallax Scroll Effect
.parallax-slow {
transition: transform 0.5s cubic-bezier(0.16, 1, 0.3, 1);
will-change: transform;
}
.parallax-fast {
transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);
will-change: transform;
}
Scroll Progress Indicator
@keyframes progressGrow {
from {
transform: scaleX(0);
}
to {
transform: scaleX(1);
}
}
.scroll-progress {
transform-origin: left;
transition: transform 0.2s ease-out;
will-change: transform;
}
Sticky Header with Animation
.header {
position: sticky;
top: 0;
transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1),
background 0.3s ease,
padding 0.3s ease,
box-shadow 0.3s ease;
}
.header.scrolled {
padding: 0.5rem 1rem;
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
.header.hide {
transform: translateY(-100%);
}
.header.show {
transform: translateY(0);
}
Scroll-Snap Animations
.scroll-container {
scroll-snap-type: y mandatory;
scroll-behavior: smooth;
overflow-y: scroll;
height: 100vh;
}
.scroll-section {
scroll-snap-align: start;
height: 100vh;
}
.scroll-section {
opacity: 0.5;
transform: scale(0.95);
transition: opacity 0.6s ease,
transform 0.6s ease;
}
.scroll-section.active {
opacity: 1;
transform: scale(1);
}
Performance Patterns
GPU Acceleration Best Practices
.gpu-optimized {
transform: translateZ(0);
will-change: transform, opacity;
}
@keyframes optimized {
from {
transform: translateX(0) scale(1);
opacity: 0;
}
to {
transform: translateX(100px) scale(1.2);
opacity: 1;
}
}
.cpu-intensive {
}
@keyframes reflow-trigger {
from { width: 100px; }
to { width: 200px; }
}
@keyframes transform-alternative {
from { transform: scaleX(1); }
to { transform: scaleX(2); }
}
Will-Change Optimization
.animated-element {
will-change: transform, opacity;
}
.animated-element.animation-done {
will-change: auto;
}
.bad-will-change {
will-change: transform, opacity, filter, background, color, width, height;
}
* {
will-change: transform;
}
.modal-content {
will-change: transform, opacity;
}
.modal-content.closed {
will-change: auto;
}
Animation Performance Checklist
.contained-element {
contain: layout style paint;
}
.shadow-animation {
position: relative;
}
.shadow-animation::before {
content: '';
position: absolute;
inset: 0;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
opacity: 0;
transition: opacity 0.3s ease;
z-index: -1;
}
.shadow-animation:hover::before {
opacity: 1;
}
Reduce Motion Preference
.animated {
animation: fadeInUp 0.6s ease-out;
}
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
.animated {
animation: fadeIn 0.2s ease-out;
}
}
@media (prefers-reduced-motion: reduce) {
.slide-in {
animation: fadeIn 0.2s ease;
}
.bounce {
animation: none;
}
.parallax {
transform: none !important;
}
}
Accessibility Considerations
Focus Animations
.button,
.link,
.input {
outline: 2px solid transparent;
outline-offset: 2px;
transition: outline-color 0.2s ease,
outline-offset 0.2s ease;
}
.button:focus-visible,
.link:focus-visible,
.input:focus-visible {
outline-color: #3b82f6;
outline-offset: 4px;
}
@keyframes focusRing {
0% {
outline-width: 2px;
outline-offset: 2px;
}
50% {
outline-width: 3px;
outline-offset: 4px;
}
100% {
outline-width: 2px;
outline-offset: 2px;
}
}
.interactive:focus-visible {
animation: focusRing 0.6s ease-out;
outline: 2px solid #3b82f6;
}
Screen Reader Considerations
.animating[aria-hidden="true"] {
animation: fadeIn 0.3s ease;
}
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0;
}
.loading[aria-busy="true"] {
animation: pulse 1.5s ease-in-out infinite;
}
.loading::after {
content: 'Loading...';
}
Animation Duration Guidelines
.instant {
transition-duration: 0.15s;
}
.quick {
transition-duration: 0.2s;
}
.standard {
transition-duration: 0.3s;
}
.emphasized {
transition-duration: 0.5s;
}
Color Contrast with Animations
@keyframes colorFade {
from {
color: #000000;
background: #ffffff;
}
to {
color: #ffffff;
background: #000000;
}
}
@keyframes badColorFade {
from {
color: #333333;
}
50% {
color: #888888;
}
to {
color: #ffffff;
}
}
Browser Compatibility Notes
Modern Features Support
.cross-browser-safe {
animation: fadeIn 0.3s ease;
transform: translateX(20px);
}
.modern-with-fallback {
background: rgba(255, 255, 255, 0.9);
}
@supports (backdrop-filter: blur(10px)) {
.modern-with-fallback {
background: rgba(255, 255, 255, 0.7);
backdrop-filter: blur(10px);
}
}
@supports (transform: perspective(1000px)) {
.flip-card {
transform: perspective(1000px) rotateY(0deg);
transition: transform 0.6s;
}
.flip-card:hover {
transform: perspective(1000px) rotateY(180deg);
}
}
Vendor Prefixes
.with-prefix {
-webkit-animation: slideIn 0.3s ease;
animation: slideIn 0.3s ease;
}
@-webkit-keyframes slideIn {
from { -webkit-transform: translateX(-100%); }
to { -webkit-transform: translateX(0); }
}
@keyframes slideIn {
from { transform: translateX(-100%); }
to { transform: translateX(0); }
}
.transform-prefix {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
.backdrop-prefix {
-webkit-backdrop-filter: blur(10px);
backdrop-filter: blur(10px);
}
.filter-prefix {
-webkit-filter: blur(5px);
filter: blur(5px);
}
Mobile Browser Considerations
.tap-target {
-webkit-tap-highlight-color: transparent;
tap-highlight-color: transparent;
}
.ios-smooth {
-webkit-transform: translateZ(0);
transform: translateZ(0);
-webkit-perspective: 1000;
perspective: 1000;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
.no-orientation-animation {
transition: none;
}
@media (orientation: landscape) {
.no-orientation-animation {
transition: all 0.3s ease;
}
}
.android-fix {
-webkit-transform: translateZ(0);
transform: translateZ(0);
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
Troubleshooting Guide
Common Issues and Solutions
Issue 1: Janky/Stuttering Animations
@keyframes janky {
from { width: 100px; }
to { width: 200px; }
}
@keyframes smooth {
from { transform: scaleX(1); }
to { transform: scaleX(2); }
}
.smooth-animation {
transform: translateZ(0);
will-change: transform;
}
Issue 2: Animation Not Starting
.element {
animation-name: fadeIn;
animation-duration: 0.3s;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.element {
}
.element {
animation: fadeIn 0.3s ease 0s 1 normal forwards running;
}
Issue 3: Animation Flashing/Flickering
.no-flicker {
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
-webkit-perspective: 1000;
perspective: 1000;
}
.no-flicker-2 {
transform: translateZ(0);
transform: translate3d(0, 0, 0);
}
.no-flicker-3d {
transform-style: preserve-3d;
-webkit-transform-style: preserve-3d;
}
Issue 4: Animation Ends Then Jumps
.jumpy {
animation: slideIn 0.3s ease;
}
.no-jump {
animation: slideIn 0.3s ease forwards;
}
@keyframes slideIn {
from {
transform: translateX(-100%);
}
to {
transform: translateX(0);
}
}
.no-jump {
transform: translateX(0);
animation: slideIn 0.3s ease;
}
Issue 5: Hover Animation Reverses Too Quickly
.quick-reverse {
transition: transform 0.3s ease;
}
.quick-reverse:hover {
transform: scale(1.2);
}
.smooth-reverse {
transition: transform 0.6s cubic-bezier(0.16, 1, 0.3, 1);
}
.smooth-reverse:hover {
transition-duration: 0.3s;
transform: scale(1.2);
}
Issue 6: Animation Delays Page Load
.defer-animation {
animation: fadeIn 0.3s ease;
animation-play-state: paused;
}
.optimize-load {
}
.optimize-load.ready {
will-change: transform, opacity;
}
.optimize-load.done {
will-change: auto;
}
@keyframes lazy-loaded {
0% { opacity: 0; }
100% { opacity: 1; }
}
Issue 7: 3D Transform Not Working
.flat-3d {
transform: rotateY(45deg);
}
.parent-perspective {
perspective: 1000px;
perspective-origin: center;
}
.parent-perspective .child-3d {
transform: rotateY(45deg);
transform-style: preserve-3d;
}
.self-perspective {
transform: perspective(1000px) rotateY(45deg);
}
.flip-container {
perspective: 1000px;
}
.flip-card {
transform-style: preserve-3d;
transition: transform 0.6s;
}
.flip-card-face {
backface-visibility: hidden;
}
Issue 8: Animation Performance on Mobile
@media (max-width: 768px) {
.complex-animation {
animation: fadeIn 0.3s ease;
}
}
@media (max-width: 768px) {
@keyframes mobile-bad {
from { left: 0; }
to { left: 100px; }
}
}
@media (max-width: 768px) {
@keyframes mobile-good {
from { transform: translateX(0); }
to { transform: translateX(100px); }
}
}
@media (max-width: 768px) {
.mobile-optimize .item {
animation-delay: 0s !important;
}
}
Debug Checklist
Animation Not Working? Check:
1. ☐ Is animation-duration set? (defaults to 0)
2. ☐ Are keyframes defined correctly?
3. ☐ Is element visible? (display: none prevents animation)
4. ☐ Check browser DevTools > Animations panel
5. ☐ Is animation-play-state set to running?
6. ☐ Are there conflicting !important styles?
7. ☐ Check z-index stacking issues
8. ☐ Verify browser support (@supports)
9. ☐ Check for typos in animation-name
10. ☐ Is the element in the DOM when animation triggers?
Performance Issues? Check:
1. ☐ Using transform/opacity instead of layout properties?
2. ☐ Too many simultaneous animations?
3. ☐ Is will-change causing memory issues?
4. ☐ Complex box-shadow/filter animations?
5. ☐ Check with DevTools Performance tab
6. ☐ Mobile device testing
7. ☐ Forced reflows in JavaScript?
8. ☐ Large images or backgrounds being animated?
9. ☐ Missing GPU acceleration hints?
10. ☐ Browser extensions interfering?
Animation Utilities
Stagger Animations
.stagger-item:nth-child(1) { animation-delay: 0.1s; }
.stagger-item:nth-child(2) { animation-delay: 0.2s; }
.stagger-item:nth-child(3) { animation-delay: 0.3s; }
.stagger-item:nth-child(4) { animation-delay: 0.4s; }
.stagger-item:nth-child(5) { animation-delay: 0.5s; }
.stagger-container {
--stagger-delay: 0.1s;
}
.stagger-item {
animation: fadeInUp 0.5s ease both;
animation-delay: calc(var(--item-index, 0) * var(--stagger-delay));
}
Animation Presets
.duration-fast { animation-duration: 0.15s; }
.duration-normal { animation-duration: 0.3s; }
.duration-slow { animation-duration: 0.5s; }
.duration-slower { animation-duration: 0.8s; }
.delay-0 { animation-delay: 0s; }
.delay-1 { animation-delay: 0.1s; }
.delay-2 { animation-delay: 0.2s; }
.delay-3 { animation-delay: 0.3s; }
.delay-5 { animation-delay: 0.5s; }
.once { animation-iteration-count: 1; }
.twice { animation-iteration-count: 2; }
.infinite { animation-iteration-count: infinite; }
.fill-none { animation-fill-mode: none; }
.fill-forwards { animation-fill-mode: forwards; }
.fill-backwards { animation-fill-mode: backwards; }
.fill-both { animation-fill-mode: both; }
.paused { animation-play-state: paused; }
.playing { animation-play-state: running; }
Usage Examples
Complete Modal Implementation
<div class="modal-backdrop" id="modal">
<div class="modal-content">
<h2>Modal Title</h2>
<p>Modal content goes here</p>
<button onclick="closeModal()">Close</button>
</div>
</div>
.modal-backdrop {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
animation: modalBackdropFadeIn 0.2s ease-out;
}
.modal-backdrop.closing {
animation: modalBackdropFadeOut 0.2s ease-in;
}
.modal-content {
background: white;
padding: 2rem;
border-radius: 8px;
max-width: 500px;
width: 90%;
animation: modalContentScaleIn 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}
.modal-backdrop.closing .modal-content {
animation: modalContentScaleOut 0.2s ease-in;
}
function closeModal() {
const modal = document.getElementById('modal');
modal.classList.add('closing');
setTimeout(() => {
modal.remove();
}, 200);
}
Quick Reference
Most Common Animations
.fade-in { animation: fadeIn 0.3s ease; }
.fade-out { animation: fadeOut 0.3s ease forwards; }
.slide-in { animation: slideInUp 0.4s ease; }
.scale-in { animation: scaleIn 0.3s ease; }
.bounce { animation: bounce 2s infinite; }
.pulse { animation: pulse 2s infinite; }
.shake { animation: shake 0.6s ease; }
.rotate { animation: rotate360 1s linear infinite; }
.glow { animation: pulseGlow 2s infinite; }
.wobble { animation: wobble 0.8s ease; }
Speed Reference
Animation Timing Quick Guide:
Ultra Fast: 100ms - Instant feedback
Fast: 200ms - Quick transitions
Normal: 300ms - Standard UI (recommended default)
Medium: 500ms - Emphasized transitions
Slow: 800ms - Dramatic effects
Very Slow: 1000ms+ - Decorative/background
Property Performance
Performance Impact (Best to Worst):
⚡ Fastest (GPU-accelerated):
- transform (translate, scale, rotate)
- opacity
⚡ Fast (GPU-accelerated with caution):
- filter (blur, brightness, etc.)
- backdrop-filter
⚠️ Moderate (may cause repaint):
- color
- background-color
- box-shadow (use opacity on pseudo-element instead)
❌ Slow (causes layout recalculation):
- width, height
- top, left, right, bottom (on non-positioned elements)
- margin, padding
- border
- font-size
Resources
External Tools
Testing Tools
- Chrome DevTools > Animations Panel
- Chrome DevTools > Performance Panel
- Firefox DevTools > Performance
- Lighthouse Performance Audit
Browser Support
Conclusion
This animation library provides 50+ ready-to-use CSS animations covering:
- ✅ Fade, slide, scale, rotate, bounce, flip animations
- ✅ Shake, wobble, blur, glow, swing effects
- ✅ Complete UI animation recipes (modals, toasts, dropdowns, etc.)
- ✅ Scroll-driven animation patterns
- ✅ Performance optimization techniques
- ✅ Accessibility best practices
- ✅ Browser compatibility guidance
- ✅ Comprehensive troubleshooting guide
All animations are GPU-accelerated where possible and include accessibility considerations. Use this library as a reference for implementing smooth, performant, and accessible animations in your projects.
Remember: Always test animations on target devices, respect user preferences (prefers-reduced-motion), and prioritize performance for the best user experience.