Morphing dialog
A morphing dialog is a modal that appears to grow from the control that opened it, then returns there on close. The blocking behaviour is still a modal.
FlipAlso called Shared element dialog, Morph modal, FLIP dialog, Expanding modal.
Here it is working.
Click Open. The tile becomes the note, then folds back.
For designers
The live Modal page owns the hard parts: whether the task should block the page, focus, inert background, Escape, and returning focus to the trigger. This page is the open and close drawing. If the task should have been a page or a drawer, a prettier origin will not fix that. Keep the tween short, 180 to 280 milliseconds. The first focusable control should be ready when the motion ends. On close, reverse to the trigger and put focus back on it. A beautiful open that dumps a keyboard user at the top of the document is still a broken dialog.
When to use morphing dialog
Use this when
- The live Modal rules already fit, and the trigger is still on screen.
- The task is short and local, so growing from that control makes the source obvious.
- You can finish the open before anyone tries to type.
- Reduced motion can show the dialog in place, with no Flip.
Reach for something else when
- The task should not block the page. Use a drawer or a popover.
- The content deserves a URL. Use a page.
- A plain fade from the centre would do. That is still a modal. Skip this page.
- The question is still the component. Start with the Modal page.
How to build it
Build a real dialog first. Native dialog with showModal gives you the trap, Escape and the backdrop. Pair it with inert on the page behind. Then add the morph. GSAP Flip can animate from the trigger box to the dialog box. Animate the surface, not the page behind it. Keep the overlay as a simple fade. On close, Flip back to the trigger, then move focus to that trigger. On reduced motion, show and hide the dialog with no Flip. The accessibility behaviour does not change.
Official GSAP
Flip.
const state = Flip.getState(tile);
tile.classList.add('is-open');
Flip.from(state, { duration: 0.45, ease: 'power2.inOut', absolute: true });Every plugin ships in the public GSAP package. Nothing here is copied from a paid pack.
Common questions
- Does this replace the live Modal page?
- No. When to block the page, focus, inert, Escape, and modal versus drawer all live there. This page is the grow.
- What if the trigger has scrolled off?
- Skip the morph and open in the centre. Flipping from a box that is gone looks like a jump from nowhere.
- How long should it take?
- 180 to 280 milliseconds. Past that, people click the overlay because they think nothing happened.
- What does reduced motion do?
- Show the dialog in its final place. No Flip, no scale. Focus still moves in.
- Should backdrop click still close it?
- Same rule as Modal. Fine for a low-stakes read. Not fine if it throws away a half-filled form.
Save as skill
A SKILL.md for this one animation: what it is, the official docs link, and a copy-paste block with the reduced-motion branch already in it. Copy gives you the same words.
Use this with your AI
Save the skill, drop it into Cursor, Claude, or whatever you use, and ask for this motion. That is all. The skill tells the agent to open this page, watch the working demo, and match it.
Last reviewed 26 AUG 2026
Next: Custom cursor