3D✨ Premium

Bezier Curve

A 22 px orange ball travels back and forth along a cubic Bézier arc in 2.5 s, slowing down at both ends, with both handles and their control points drawn in dotted lines: you see the curve and how it is built, and a ground shadow follows the ball, shrinking as it rises — CSS only, zero JavaScript, ball resting at the top when the user reduces motion.

CSSBezierAnimation

Updated

This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. 3D has 50 effects, including 8 free. Explore the category →

3 usage examples

The Bézier handle explained — online vector drawing course — Bezier Curve example 1

① The Bézier handle explained — online vector drawing course

WhenLesson 4 of a course on the pen tool: the left column explains anchors and handles, on the right the ball runs along the curve between two handles labeled "Handle 1" and "Handle 2".
WhyIt is the only effect in the catalog that shows the control points next to the curve: the ball demonstrates the pen tool, and students see that the curve is pulled toward the handles without ever touching them.
SettingsRoot without background on a dotted canvas; path, handles and points made stronger in yellow #fbbf24 (5 px radius points); white square anchors at both ends; labels "Handle 1", "Handle 2", "Start", "End" placed in the scene.
The ball passed from one hand to the other — circus school page — Bezier Curve example 2

② The ball passed from one hand to the other — circus school page

WhenAnnouncement of the spring break juggling camp for ages 8 to 12: text and sign-up button on the left, on the right a red ball passing from one drawn hand to the other.
WhyThe back-and-forth on an arc, slowing down above each hand, is the one-ball cascade move: kids and parents recognize the first day's exercise.
SettingsBall recolored red (radial-gradient from #fca5a5 to #991b1b); pale pink path; handles and control points hidden (display: none); shadow hidden (it would land on the palms); two CSS hands placed under the ends of the arc.
The lob — pétanque club tutorial — Bezier Curve example 3

③ The lob — pétanque club tutorial

WhenTutorial no. 3 of the club: the boule leaves the throwing circle, rises very high and lands next to the jack, on a gravel court.
WhyThe parabola and its handles show the throwing height to aim for better than a sentence, and the shadow shrinking on the gravel makes height readable even when you only look at the ground.
SettingsSteel boule (white → #475569 radial-gradient); shadow recolored dark brown rgba(60,45,25,.8) for a light background; olive green path and handles; gravel band aligned with the bottom of the ball at both ends; jack and throwing circle drawn in CSS.

How it works

The .fx-0033-root root (background #0a0a0f, at least 300 px tall) centers a 300 × 220 px .mp-bezier-scene. An <svg> of the same size draws three things in faint lines: the dotted arc M30,190 C30,30 270,30 270,190, the two control points (30,30) and (270,30), and the two handles that link them to the ends of the arc. On top sit two divs: .mp-bezier-shadow, the shadow, and .mp-bezier-ball, the ball (#f59e0b → #f97316 gradient and an orange glow).

The ball gets offset-path: path("M 30 190 C 30 30 270 30 270 190"), the same path as the svg, and an animation that takes offset-distance from 0 to 100% in 2.5 s, ease-in-out, alternate: it goes, slows down, comes back. The browser places the center of the ball on the path point; the ball therefore has no negative margin, and its center stays on the drawn curve (measured gap: 0.2 px at most in Chromium 151, Firefox 153 and WebKit 26, with identical positions in all three). The path matches everywhere because the svg is not stretched: 300 × 220 px for a 300 × 220 viewBox.

The shadow is a 32 × 8 px orange ellipse placed under the ends of the arc. It cannot follow the ball with a second offset-path: offset-distance measures the distance traveled along the curve, not the horizontal position, and the ball rises almost vertically at first. Its fx0033Shadow keyframes therefore give, every 5% of the time, the horizontal position of the ball already computed on the curve, with the ease-in-out easing baked in; the shadow animation is linear, with the same duration and alternate. Measured gap between the ball and its shadow: 0.1 px. At the same time, the shadow goes from scale 1 and 90% opacity on the ground to 0.5 and 40% at the top: that is what conveys height.

Accessibility

  • Reduced motion: under prefers-reduced-motion: reduce, a block scoped to .fx-0033-root stops the ball at the top of the curve (offset-distance: 50%), between the two handles, with the shadow right below. Measured: 0% of pixels change over 0.8 s in Chromium, Firefox and WebKit, versus 1.2% in normal mode.
  • Decorative content: the scene carries no text; the svg and the empty divs are ignored by screen readers. If the curve explains something (a drawing tool, a sports move), write the explanation next to it, as in the examples above.
  • Contrast: the orange ball reads well on the dark background; the path and handles are deliberately faint (12% and 30% opacity). For a lesson where the construction matters, make them stronger (see "Customize").
  • Rhythm: one trip in 2.5 s, no flashing; the motion stays within a 300 × 220 px frame.

Browser compatibility

CSS only: offset-path: path(), animated offset-distance and a transform animation for the shadow, no JavaScript, no dependency. Measured in Chromium 151, Firefox 153 and WebKit 26 (Safari's engine): same ball positions to within half a pixel, same shadow, same stop under reduced motion. Not checked on a real Safari.

Chrome 55+✓ Full
Firefox 72+✓ Full
Safari 16+✓ WebKit 26 measured, Safari not checked
Edge 79+✓ Full
Mobile iOS 16+✓ Not checked on a device
Android Chrome✓ Full

A browser without offset-path leaves the ball still at the top left of the scene; the path, the handles and the shadow (which keeps sliding along the ground) stay visible.

The code

HTML structure to paste into your page (the CSS + JS come with your purchase):

index.html — structure
<div class="fx-0033-root">
  <div class="mp-bezier-scene">
    <svg viewBox="0 0 300 220" fill="none">
      <path d="M30,190 C30,30 270,30 270,190" … />   <!-- the curve -->
      <circle … /> <circle … />                    <!-- control points -->
      <line … /> <line … />                        <!-- handles -->
    </svg>
    <div class="mp-bezier-shadow"></div>
    <div class="mp-bezier-ball"></div>
  </div>
</div>

One-time payment, no subscription — the code is yours forever

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
Ball color (CSS — .mp-bezier-ball) #f59e0b → #f97316 gradient, orange glow Change the background and the box-shadow color. On a light background, replace the glow with a small drop shadow.
Ground shadow (CSS — .mp-bezier-shadow) 32 × 8 px orange ellipse On a light background, switch the gradient to dark brown or gray (rgba(60,45,25,.8)): a black shadow vanishes on a black background, hence the default orange. To remove it, delete the div and its rule.
Speed (CSS — 2.5s in both animation declarations) 2.5 s per trip Change the ball AND shadow durations together, otherwise the shadow drifts. 1.5 s gives a quick throw, 4 s a slow demonstration.
Handles and control points (HTML — svg circle and line) 3 px points at 30%, handles at 8% opacity For a lesson, raise the opacity or recolor them; for plain decoration, hide them in CSS (display: none): only the dotted curve remains.
Curve shape (HTML + CSS) M30,190 C30,30 270,30 270,190 The path is written three times: the svg path d, the ball's offset-path, and the shadow keyframes, computed for this curve. If you change the curve, change the first two and recompute the keyframes (horizontal position of the ball every 5% of the time), or remove the shadow.
Background (CSS — .fx-0033-root) #0a0a0f Change or remove the root background to set the scene on your page; then check the path and shadow colors.

FAQ

Because the ball moves along the curve, not at a constant horizontal speed: at first it rises almost vertically. A shadow sliding on a straight line with the same offset-distance would drift by 27 px at the worst moment. The 21 keyframes give the real horizontal position of the ball, easing included; measured, the shadow stays within 0.1 px under the ball. The cost: if you change the curve or the easing, they must be recomputed.
animation-direction: alternate: every other trip plays in reverse, and the ease-in-out easing makes the ball almost stop at each end. It is the back-and-forth of a ball tossed between two people. With normal, the ball would jump from the end back to the start on every loop: add a fade then, or use a closed path.
Bezier Curve is the only one of the three that shows how the curve is built: two handles and their control points, plus a shadow that conveys height. Path Drawing draws the line as it goes with stroke-dashoffset; Bounce Path chains five lower and lower bounces. To explain a curve, a move or a throwing height, use Bezier Curve.