🎨 CSS

CSS Cubic Bezier Generator

Design custom acceleration curves visually by dragging control points. Preview animations in real time and export production CSS and Tailwind utilities.

Standard Motion Presets
Live Movement Preview
Tailwind CSS Utility

Architecture of Cubic Bezier Timing Functions: Mathematics, Kinematics, and GPU Compositing

Quick Answer: The CSS Cubic Bezier Generator provides an interactive visual canvas to craft custom easing functions for CSS transitions and keyframe animations. It allows developers to drag tangent control handles (P1 and P2), preview real-time physics against standard curves, test elastic overshoots, and export production-ready cubic-bezier() CSS rules and Tailwind theme tokens with zero server uploads.

Motion in physical reality is rarely linear. A billiard ball struck by a cue does not travel at a constant velocity and stop abruptly; it accelerates rapidly, rolls smoothly, and decelerates under friction before coming to rest. An apple falling from a tree accelerates continuously due to gravity until it strikes the ground. When digital interfaces present animations with constant linear speed, the human visual cortex perceives the motion as robotic, unnatural, and jarring.

To infuse digital interfaces with organic realism, modern CSS animation specifications rely on cubic Bezier curves. By adjusting the mathematical trajectory of a curve, designers and developers can simulate physical mass, tension, inertia, gravity, and spring elasticity. This generator provides an intuitive visual playground to sculpt these curves with precision, inspecting their mathematical coordinates and testing their physical behavior in real time.

Historical Foundations: From Automotive Engineering to Digital CSS

The mathematical foundation of Bezier curves originated in the French automotive manufacturing industry during the late 1950s and early 1960s. Two independent engineers, Paul de Casteljau at Citroen and Pierre Bezier at Renault, sought mathematical methods to model smooth, aerodynamic automobile body panels using digital computers.

Pierre Bezier formalized the parametric polynomial formulations that now bear his name. Originally developed to guide milling machines and computer-aided design (CAD) toolpaths, these curves proved so versatile that computer scientists later adapted them for PostScript fonts, vector graphics (SVG paths), and ultimately CSS transition timing functions. In CSS, a cubic Bezier curve does not map physical spatial contours; instead, it models the progression of time versus visual displacement.

Parametric Bernstein Polynomials: The Exact Mathematics of Cubic Curves

In mathematics, a cubic Bezier curve is a third-order parametric polynomial defined by four control points in two-dimensional coordinate space: $P_0$, $P_1$, $P_2$, and $P_3$. The general formula is expressed using Bernstein basis polynomials:

B(t) = (1 - t)^3 * P_0 + 3 * (1 - t)^2 * t * P_1 + 3 * (1 - t) * t^2 * P_2 + t^3 * P_3

Where the interpolation parameter t ranges continuously from 0.0 to 1.0.

In the CSS specification (CSS Transitions Level 1 and CSS Animations Level 1), two of these four points are permanently fixed:

Consequently, developers configure only the two intermediate control points: P1 (X1, Y1) and P2 (X2, Y2), yielding the familiar functional syntax: cubic-bezier(x1, y1, x2, y2).

How Browser Rendering Engines Solve Bezier Curves in Real Time

A subtle computational problem arises when executing Bezier timing in software. In the parametric formula, both the horizontal coordinate (X, representing time) and the vertical coordinate (Y, representing output displacement) are parameterized by t. However, when the browser compositor renders an animation frame at elapsed time x, it needs to find the corresponding visual displacement y.

Because there is no closed-form algebraic solution to directly calculate y from x for arbitrary cubic polynomials, browser rendering engines (such as Chrome Blink and WebKit) utilize numerical root-finding algorithms, primarily the Newton-Raphson iteration:

  1. Given the current time fraction x (between 0.0 and 1.0), the engine makes an initial estimate of t.
  2. It evaluates the derivative dX/dt and iteratively refines t until the error falls below a floating-point tolerance threshold (typically within 4 to 8 iterations).
  3. Once the exact parameter t is determined, the engine plugs t into the cubic formula for Y(t), yielding the precise visual progression value for that animation frame.

Asymmetric Constraints: Time Progress vs Output Displacement

When interacting with the control handles in our generator, you will notice a fundamental difference in how the horizontal and vertical axes behave:

Horizontal X Axis: Strict [0.0, 1.0] Bounds

The horizontal axis represents normalized elapsed time. The CSS specification strictly mandates that X1 and X2 must lie within the range [0.0, 1.0]. If a stylesheet declares cubic-bezier(-0.2, 0.5, 1.2, 0.8), the entire CSS property declaration is deemed invalid and discarded by the browser parser. This restriction reflects physical causality: an animation cannot run backward in time, nor can intermediate frames occur after total duration has elapsed.

Vertical Y Axis: Unbounded Real Numbers

In contrast, the vertical Y axis represents the completion ratio of the animated property. The CSS specification permits Y1 and Y2 to range freely into negative numbers or values greater than 1.0 (typically bounded between -2.0 and 2.0 for practical UI design):

Deconstructing Browser Keyword Timing Curves

CSS provides five built-in timing keywords. Every keyword is simply an alias for a specific cubic-bezier coordinate pair:

CSS Keyword Equivalent cubic-bezier() Syntax Acceleration Profile Ideal UI Use Case
linear cubic-bezier(0.0, 0.0, 1.0, 1.0) Zero acceleration (Constant velocity) Infinite spinners, background color cycles
ease (Default) cubic-bezier(0.25, 0.1, 0.25, 1.0) Fast start, smooth deceleration General transitions, hover states, card elevation
ease-in cubic-bezier(0.42, 0.0, 1.0, 1.0) Slow start, accelerates toward end Exiting elements, items moving off-screen
ease-out cubic-bezier(0.0, 0.0, 0.58, 1.0) Instant start, gradual deceleration Entering elements, modal dialogs sliding in
ease-in-out cubic-bezier(0.42, 0.0, 0.58, 1.0) Slow start, fast middle, slow finish Symmetrical toggle switches, accordion toggles

Kinematics and UI Motion Design Principles

Professional digital motion design applies classic animation principles, pioneered by Disney animators Frank Thomas and Ollie Johnston, to web software interactions:

Compositor Thread Acceleration and Clamping Hazards

CSS cubic-bezier transitions execute with hardware-accelerated precision on the browser GPU compositor thread when animating transform and opacity. However, developers must be mindful of property clamping hazards when using overshooting curves ($Y > 1.0$):

Standardizing Motion Tokens in Tailwind CSS and Design Systems

In enterprise design systems, easing curves should never be scattered as arbitrary hardcoded numbers across stylesheets. Instead, curves are registered as design tokens:

:root {
  --ease-standard: cubic-bezier(0.2, 0.0, 0.0, 1.0);
  --ease-decelerate: cubic-bezier(0.0, 0.0, 0.2, 1.0);
  --ease-accelerate: cubic-bezier(0.4, 0.0, 1.0, 1.0);
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1.0);
}

Inside tailwind.config.js, register custom curves under the transitionTimingFunction theme key:

module.exports = {
  theme: {
    extend: {
      transitionTimingFunction: {
        'spring': 'cubic-bezier(0.34, 1.56, 0.64, 1)',
        'snappy': 'cubic-bezier(0.16, 1, 0.3, 1)',
      }
    }
  }
}

This allows your engineering team to write clean utility classes like transition-all ease-spring duration-300 across component templates.

Accessibility: Vestibular Disorders and prefers-reduced-motion

Excessive spring overshoots, bouncy scaling, and prolonged motion curves can induce nausea, vertigo, and dizziness in users with vestibular balance disorders. WCAG 2.1 Success Criterion 2.3.3 (Animation from Interactions) mandates that motion triggered by user interaction must be suppressible:

@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;
  }
}

Always couple custom Bezier curves with reduced-motion safeguards to ensure every visitor experiences your digital product safely and comfortably.

Frequently Asked Questions

Why can I not drag the X coordinate handle past 0 or 1?

The X axis represents elapsed animation duration from 0% to 100%. Physical progression cannot run backward in time or exceed completion duration, so the CSS specification strictly confines X coordinates between 0.0 and 1.0.

Why are Y coordinates allowed to extend below 0 or above 1?

The Y axis governs transition progression output rather than time. Allowing values above 1.0 creates natural spring overshoot, while values below 0.0 produce anticipation pullbacks before forward acceleration.

Is the ball motion a real browser preview or a simulated timer?

The preview applies your generated cubic-bezier value directly to native CSS transition-timing-function properties, executing inside the browser rendering pipeline for exact production fidelity.

What standard timing curves do CSS keywords represent?

Standard keyword mappings include ease as cubic-bezier(0.25, 0.1, 0.25, 1.0), linear as cubic-bezier(0.0, 0.0, 1.0, 1.0), ease-in as cubic-bezier(0.42, 0.0, 1.0, 1.0), and ease-out as cubic-bezier(0.0, 0.0, 0.58, 1.0).

What is the difference between animation-timing-function and transition-timing-function?

Both properties use identical cubic-bezier syntax. Transition timing applies to state change interpolations like hover or focus, while animation timing governs keyframe sequences.

How does the SVG coordinate grid translate to bezier mathematical points?

Standard SVG viewport coordinates place origin (0,0) at the top-left corner. The generator inverts the vertical axis so dragging upward maps to higher positive Y values in the output formula.

What is the parametric Bernstein polynomial formula behind a cubic Bezier curve?

A cubic Bezier curve is defined parametrically by B(t) = (1-t)^3*P0 + 3*(1-t)^2*t*P1 + 3*(1-t)*t^2*P2 + t^3*P3 for t between 0 and 1, where P0 is (0,0) and P3 is (1,1).

How does easing influence the physical realism of UI micro-interactions?

In the physical world, objects possess mass and inertia, accelerating gradually and decelerating to a stop. Linear easing feels robotic, while cubic-bezier curves mirror real-world physics like spring tension and gravity.

Can cubic-bezier curves cause layout bugs if Y exceeds 1.0 on certain properties?

Yes. If applied to properties with strict lower or upper bounds like opacity or color channels, browser engines clamp values between 0 and 1. On transform or coordinate properties, overshoot renders smoothly beyond normal bounds.

How do I implement prefers-reduced-motion when using custom bezier transitions?

Wrap transition rules in a media query or supply an override @media (prefers-reduced-motion: reduce) block that reduces transition-duration to 0.01ms or replaces motion with subtle instantaneous opacity changes.