Shots in this scene
Morphing Shapes
In one line
CSS can animate a path's d property, but only between two paths with the same commands in the same order. Anything else does not blend: it jumps at the halfway point. To morph any two shapes, resample both into the same number of points first.
Think of it like this
A rubber band pinned at 4 nails, which you move to 4 other nails. The band stretches smoothly because each nail has a partner. Give it 4 nails and then 5, and there is no partner for the extra one, so it jumps.
Words you'll meet
New words in this topic, in plain English. Come back here whenever one feels fuzzy.
- d
- The path data of a
<path>: a list of commands such asM(move),L(line),C(curve),A(arc) andZ(close). In Chromium it is also a CSS property. - command
- One letter of a path with its numbers. A capital means absolute coordinates, a small letter relative ones.
- resample
- Walk along a path in equal steps and write the points down as a new path, so that two paths get the same number of points.
- interpolate
- Work out the values between a start and an end value, frame by frame. A value that cannot be blended is shown as the start until the middle and the end after it.
- winding
- The direction a path is drawn in, clockwise or not, and the point it starts at. Morphing pairs points by their order, so both must match.
Step by step
01Read the table
"Which pairs blend?" prints five rows: the first point of each shape at 0, 499, 501 and 1000 ms. The first two rows change by 0.06 between 499 and 501: smooth. The last three jump from (20, 20) to (50, 10) across 2 ms.
02Watch each pair
Press each button. Pause at 0.1× near the middle of the 1200 ms run. The first two shapes are half way between a square and a diamond. The others are a square, then at once the other shape.
03Morph the square into a circle
In "A square into a circle" press Morph as written and step past 600 ms: the square is replaced by a circle in one frame. Press Morph resampled: at 600 ms the shape is a rounded square, and it ends as a circle.
04Count the commands
The console says as written: 5 commands against 4 and resampled: 65 commands against 65. The equal counts are what let the browser pair the points.
Try it yourself
- 1
Start the circle at the wrong corner
In the second example change the circle text to
M78.28 78.28 A40 40 0 0 1 21.72 21.72 A40 40 0 0 1 78.28 78.28 Zand press Morph resampled. At 600 ms the shape has shrunk to a cross a few pixels across, in the middle. Each point crosses the shape to meet its partner. - 2
Use fewer points
Change
resample(d, n = 64)ton = 8. Near the end of the run the circle is a clearly angular polygon, with visible corners. More points make smoother shapes and longer path text. - 3
Find the jump on the timeline
In the first example press the
L against Cbutton, pause at 0.1× and step through the middle of the 1200 ms run: the shape changes in one frame, and the track gives no hint of it.
Code & diagrams
Each row shows the start of the shape at 0, 499, 501 and 1000 ms. A blend changes a little between 499 and 501. A pair that cannot blend jumps.
Nothing is moving yet. Hover, click or scroll the page: every animation it starts shows up here as a track.
Console
Nothing logged yet.Expected console output
same commands (L L L L Z): (20, 20) (34.97, 15.01) (35.03, 14.99) (50, 10)
relative l against absolute L: (20, 20) (34.97, 15.01) (35.03, 14.99) (50, 10)
H and V against L: (20, 20) (20, 20) (50, 10) (50, 10)
L against C: (20, 20) (20, 20) (50, 10) (50, 10)
4 points against 5 points: (20, 20) (20, 20) (50, 10) (50, 10)Press **Morph as written**, then **Morph resampled**, and step through the middle of each.
Nothing is moving yet. Hover, click or scroll the page: every animation it starts shows up here as a track.
Console
Nothing logged yet.Expected console output
as written: 5 commands against 4
resampled: 65 commands against 65Break it on purpose
Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.
Break #1
Morph without resampling
In the second example press Morph as written.
Myth vs fact
Myth
If both shapes look similar, the browser will morph them.
Fact
It needs the same command letters in the same order: one H against an L made it jump.
Pro corner
Extra depth for experienced readers. New to this? Skip it for now and come back later.
- ▸
A resampled path is a polygon, not a curve: with 64 points a circle of radius 40 looks round, but zooming far in shows corners. Use it for the in-between frames and show the original
dat rest if the shape must stay exact. - ▸
Equal steps along the length are not always the best pairing: points pair by distance fraction, so a long thin part of one shape can land on a short part of the other. Tools like MorphSVG let you choose. For icons, draw both shapes with the same commands by hand.
- ▸
Reduced motion for a morph: skip the in-between and show the final shape at once (as the
morph()answer below does).
Remember this
- 1
The problem this solves: a menu icon becomes a cross, a heart becomes a star, a square becomes a circle. The shape changes outline, not position.
d: path("…")is a CSS property in Chromium, so@keyframesorelement.animate()can use it. MDN lists it as not Baseline (checked October 2026), so read its compatibility table for Safari before you ship it. Writing the right path pairs is the whole craft. - 2
What blends. The browser moves each coordinate from the first path to the matching one in the second. For that the two paths need the same list of command types. We measured five pairs at 0, 499, 501 and 1000 ms of a 1000 ms animation, printing where each path starts. Four
Lpoints against fourLpoints: (20, 20), then (34.97, 15.01) at 499 and (35.03, 14.99) at 501, a smooth glide. Relativelagainst absoluteLblends with the same numbers, because both become absolute before blending. - 3
What does not blend.
HandVagainstL(a different command letter),LagainstC(a line against a curve) and four points against five all gave (20, 20) at 499 ms and (50, 10) at 501 ms: the first shape until the halfway point, the second after it. There is no error. The same jump happens for any value that cannot be blended, such asdisplay. - 4
Why tools resample. To morph a square into a circle, written with 4 and 5 commands (
M H V H ZandM A A Z), you walk along each path in equal steps and write the points down asM x y L x y … Z. Both shapes then have the same number ofLpoints and blend smoothly. In the second example the two paths had 5 and 4 commands as written and 65 and 65 after resampling 64 points.getTotalLength()andgetPointAtLength()do the walking. - 5
Where the start point and direction matter. Point 1 of the first shape blends with point 1 of the second. Start the circle at the same corner and go the same way as the square (the second example does) and the shapes grow into each other, a rounded square at 600 ms. From the opposite corner every point crosses the middle (tryIt 1).
- 6
What CSS cannot morph. The
pointsattribute of<polygon>and<polyline>is not a CSS property here (CSS.supports("points", …)was false). Rewrite the shape as adpath, animatepointswith SMIL (Topic 13.5), or use a library: GSAP's MorphSVG plugin does the pairing and resampling for you (Phase 14). - 7
On the timeline. A
dtrack is red (layout: the cost table, measured in headless Chromium, listsdwithcx,randstroke-width), because the browser rebuilds the shape's geometry each frame. Fine for an icon; measure before morphing a large drawing.
Explain it without notes
What must be true of two paths for CSS to morph them smoothly, and what happens otherwise?
How do you morph a square into a circle?
Practice
Morph a plus sign into a cross by animating d: both are written with 12 L commands. What do you check first?
Write morph(el, from, to) that resamples two path strings and animates d once, with no animation under reduced motion.
Done when you can
You can say which path pairs blend and which jump
You can resample two paths so they morph
You know why the start point and direction matter
You know
pointsis not animatable in CSS here