Using Easing Functions for CSS Animations
Easing functions control the rate of change in animations, creating natural motion.
Standard CSS Easing
/* Built-in timing functions */
transition: transform 1s ease; /* Default */
transition: transform 1s ease-in; /* Slow start */
transition: transform 1s ease-out; /* Slow end */
transition: transform 1s ease-in-out; /* Slow start and end */
transition: transform 1s linear; /* Constant speed */
Custom Easing in JavaScript
type EasingFunction = (t: number) => number;
export const Easing: Record<string, EasingFunction> = {
// Linear - no easing
linear: (t: number) => t,
// Quad - quadratic easing
easeInQuad: (t: number) => t * t,
easeOutQuad: (t: number) => t * (2 - t),
easeInOutQuad: (t: number) => t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t,
// Cubic - cubic easing
easeInCubic: (t: number) => t * t * t,
easeOutCubic: (t: number) => --t * t * t + 1,
easeInOutCubic: (t: number) => t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1,
// Quart - quartic easing
easeInQuart: (t: number) => t * t * t * t,
easeOutQuart: (t: number) => 1 - --t * t * t * t,
easeInOutQuart: (t: number) => t < 0.5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t,
// Quint - quintic easing
easeInQuint: (t: number) => t * t * t * t * t,
easeOutQuint: (t: number) => 1 + --t * t * t * t * t,
easeInOutQuint: (t: number) => t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * --t * t * t * t * t,
// Sine - sinusoidal easing
easeInSine: (t: number) => -Math.cos(t * (Math.PI / 2)) + 1,
easeOutSine: (t: number) => Math.sin(t * (Math.PI / 2)),
easeInOutSine: (t: number) => -(Math.cos(Math.PI * t) - 1) / 2,
};
Usage in Animations
function animateValue(
from: number,
to: number,
duration: number,
easing: EasingFunction = Easing.linear,
onUpdate: (value: number) => void
): void {
const startTime = performance.now();
function update(currentTime: number) {
const elapsed = currentTime - startTime;
const progress = Math.min(elapsed / duration, 1);
const easedProgress = easing(progress);
const value = from + (to - from) * easedProgress;
onUpdate(value);
if (progress < 1) {
requestAnimationFrame(update);
}
}
requestAnimationFrame(update);
}
Frame-Based Animation (Remotion)
function calculateWithEasing(
frame: number,
duration: number,
easing: EasingFunction
): number {
const progress = frame / duration;
return easing(Math.min(Math.max(progress, 0), 1));
}
// Example: Fade in with ease-out
export const FadeIn: React.FC = () => {
const frame = useCurrentFrame();
const { durationInFrames } = useVideoConfig();
const fadeInFrames = 30;
const opacity = calculateWithEasing(
Math.min(frame, fadeInFrames),
fadeInFrames,
Easing.easeOut
);
return <div style={{ opacity }} />;
};
Common Easing Patterns
| Pattern | Use Case | Function |
|---|---|---|
| Ease Out | Natural movement, exits | easeOut, easeOutQuad |
| Ease In | Anticipation, building up | easeIn, easeInQuad |
| Ease In-Out | Smooth back-and-forth | easeInOut, easeInOutQuad |
| Linear | Constant, mechanical | linear |
Visual Comparison
linear: ━━━━━━━━━━━━━━━━━
easeIn: ╱╲╱╲╱╲╱╲╱╲╱╲
easeOut: ╲╱╲╱╲╱╲╱╲╱╲╱
easeInOut: ╱‾‾‾‾‾‾‾‾‾╲
CSS Cubic Bezier
Custom easing curves using cubic-bezier:
/* ease-in-out = cubic-bezier(0.425, 0, 0.575, 1) */
transition: transform 1s cubic-bezier(0.425, 0, 0.575, 1);
/* Custom sharp ease-in */
transition: transform 1s cubic-bezier(0.9, 0, 1, 1);
/* Custom bounce */
transition: transform 1s cubic-bezier(0.68, -0.55, 0.265, 1.55);
Bezier to Function Conversion
function cubicBezier(p1x: number, p1y: number, p2x: number, p2y: number): EasingFunction {
return (t: number) => {
// Cubic bezier formula
const u = 1 - t;
return (
3 * u * u * t * p1y +
3 * u * t * t * p2y +
t * t * t
);
};
}
// Usage
const customEase = cubicBezier(0.425, 0, 0.575, 1); // Similar to ease-in-out
Spring Easing
For springy, bouncy animations:
function springEasing(
t: number,
stiffness: number = 0.1,
damping: number = 0.3
): number {
const angularFreq = Math.sqrt(stiffness);
const decay = damping * angularFreq;
return 1 - Math.exp(-decay * t) * Math.cos(angularFreq * t);
}
Recommendations by Use Case
| Animation Type | Recommended Easing |
|---|---|
| Fade in/out | easeOut, easeInOut |
| Slide in | easeOutQuart |
| Scale/zoom | easeInOut |
| Rotation | easeInOutCubic |
| UI transitions | easeOut (snappy) |
| Background motion | linear (subtle) |
| Entrance | easeOutBack (overshoot) |
| Exit | easeIn (quick) |