Result

Motion preview

Two keyframes. One deliberate transition.

Transform + opacity

Preview paused. Enable JavaScript to play or inspect the animation.

The stage clips large transforms. The exported pixel distances stay exact.

Timing curve

ease-in-out

Time moves left to right. The curve maps time to progress. Control points can create overshoot.

Cubic Bézier easing graph Ease-in-out curve from zero to full progress.
CSS

.motion-element {
  animation-name: element-motion;
  animation-duration: 1.8s;
  animation-timing-function: ease-in-out;
  animation-delay: 0s;
  animation-iteration-count: infinite;
  animation-direction: alternate;
  animation-fill-mode: both;
  transform-origin: center;
}

@keyframes element-motion {
  from {
    transform: translate(-64px, 16px) rotate(-12deg) scale(0.8);
    opacity: 0.3;
  }
  to {
    transform: translate(64px, -16px) rotate(12deg) scale(1);
    opacity: 1;
  }
}

@media (prefers-reduced-motion: reduce) {
  .motion-element {
    animation: none;
    transform: translate(64px, -16px) rotate(12deg) scale(1);
    opacity: 1;
  }
}

Build a small CSS animation with an inspectable timing curve

  1. Set a duration, delay and easing. For a custom curve, edit its two control points.
  2. Choose the start and end translations, rotation, scale and opacity.
  3. Play, pause, restart or scrub the first forward iteration to inspect the transition.
  4. Copy or download the CSS and add class="motion-element" to your element. Add its visual styling separately.

What does the export contain?

The CSS includes an animation rule, two keyframes and a prefers-reduced-motion override. Transforms are emitted in translate, rotate, scale order with a center origin. Fill mode is both, so the start state applies during the delay and the end state remains after a single normal run. Alternate changes the direction of successive iterations; it does not add a reverse trip when Repeat is Once.

How do cubic Bézier values work?

The curve begins at (0, 0) and ends at (1, 1). X1 and X2 must stay between zero and one for a valid timing function. Y1 and Y2 can go outside that range to create overshoot; this builder allows -2 to 3. For example, cubic-bezier(0.2, 0, 0.2, 1) reaches the end quickly, then settles. Opacity is clamped by the browser to its visible range even when an easing curve overshoots.

Playback and reduced motion

The preview starts paused and pauses again when settings change or the page becomes hidden. The scrubber selects progress within the first forward iteration, after the delay; it is an inspection control, not a live playback meter. With reduced motion enabled, you can explicitly choose to play the preview. Exported CSS instead stops the animation and shows the configured end state. Check that this state keeps essential content visible.

Scope and bounds

This builder uses two keyframes, transform and opacity, a duration of 0.1 to 20 seconds, and a delay of 0 to 10 seconds. Translation is bounded to ±160px horizontally and ±100px vertically, rotation to ±360 degrees, scale to 0.25–2 and opacity to 0–1. Values are rounded to three decimals for consistent preview and export. It does not generate spring physics, arbitrary property animation, scroll timelines or motion paths. Existing transforms or animation rules on your element may need to be combined manually.

References

See MDN’s cubic-bezier() reference , Element.animate() API , and CSS keyframes reference .