Morph transition
Morph between shapes on hover — square to circle, pentagon to diamond, and back.
Quick implementation
/* Square to circle morph */
.morph {
width: 6rem;
height: 6rem;
border-radius: 0.5rem;
background: oklch(0.55 0.18 265);
transition: border-radius 0.6s cubic-bezier(0.4, 0, 0.2, 1),
background 0.6s ease;
}
.morph:hover,
.morph:focus-visible {
border-radius: 50%;
background: oklch(0.60 0.20 310);
}
/* Clip-path morph: pentagon to diamond */
.morph-clip {
clip-path: polygon(50% 0%, 100% 38%, 82% 100%, 18% 100%, 0% 38%);
background: oklch(0.55 0.18 25);
transition: clip-path 0.6s cubic-bezier(0.4, 0, 0.2, 1),
background 0.6s ease;
}
.morph-clip:hover,
.morph-clip:focus-visible {
clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%, 0% 50%);
background: oklch(0.60 0.20 200);
}
@media (prefers-reduced-motion: reduce) {
.morph,
.morph-clip {
transition-duration: 0.01s;
}
}
Prompt this to your LLM
Includes role, constraints, two framework variants, and edge cases to handle.
You are a senior frontend engineer building interactive shape animations.
Goal: Morph an element between two shapes on hover using CSS transitions — border-radius and clip-path approaches.
Technical constraints:
- border-radius morph: transition from a small radius to 50% for a square-to-circle effect.
- clip-path morph: use polygon() with the same number of points in both states so the browser can interpolate.
- Use cubic-bezier(0.4, 0, 0.2, 1) for a natural easing curve.
- Use oklch() for all color values — no hex or rgba().
- Include :focus-visible alongside :hover for keyboard users.
Framework variant (pick one):
A) Vanilla HTML + CSS only.
B) React component — accept shape prop ("square" | "circle" | "pentagon" | "diamond") and morph on hover.
Edge cases to handle:
- Respect prefers-reduced-motion: reduce duration to near-instant.
- clip-path polygon points must match count in both states, otherwise the browser can't interpolate.
- border-radius + width/height morph together triggers layout — prefer transform: scale() if performance is critical.
Return CSS only.
Why this matters in 2026
Shape morphing used to require SVG <animate> or JavaScript FLIP libraries. Modern CSS can transition border-radius and clip-path: polygon() natively, letting you morph between shapes with a single transition rule. This is especially powerful for avatar frames, icon states, and decorative elements that need to feel alive.
The logic
For border-radius morphs, the browser interpolates between numeric values — 0.5rem to 50% creates a smooth square-to-circle arc. For clip-path, both the start and end polygon() must have the same number of vertices. The browser interpolates each vertex independently, producing a fluid shape morph. Use cubic-bezier(0.4, 0, 0.2, 1) for a material-design deceleration curve that feels natural.
Accessibility & performance
clip-path transitions are paint-only and GPU-friendly. border-radius changes trigger paint but not layout (unless combined with size changes). Pair morphs with :focus-visible so keyboard users can trigger the effect. Always gate animations behind prefers-reduced-motion — shape changes can be disorienting for some users.