Symmetric paths and origins
Exit the way you entered; grow menus out of their trigger.
From apple-design, §7 Spatial consistency.
Leave the way you came
Open a row, then close it. Watch where it goes.
In right, out bottomBad
Inbox
in: translateX · out: translateYIn and out the rightGood
Inbox
in and out: translateX.panel {
transform: translateX(100%);
visibility: hidden;
transition: transform 200ms var(--ease-out), visibility 0s 200ms;
}
.panel[data-state="open"] {
transform: none;
visibility: visible;
transition: transform 260ms var(--ease-out), visibility 0s;
}
Grow out of the trigger
Open both menus, then move the trigger.
Scales from centerBad
transform-origin: centerScales from triggerGood
transform-origin: calc(100% - 18px) -26px.menu {
transform-origin: var(--trigger-x) var(--trigger-y);
transform: scale(0.95);
opacity: 0;
transition: transform 200ms var(--ease-out), opacity 120ms ease;
}
.menu[data-open="true"] { transform: none; opacity: 1; }
.popover { transform-origin: var(--radix-popover-content-transform-origin); }
Return on the inverse curve
Play out and back; compare the ticks.
Same curve both waysBad
back: cubic-bezier(0.2, 0, 0, 1)Inverse curve backGood
back: cubic-bezier(1, 0, 0.8, 1).knob { transition: transform 300ms cubic-bezier(1, 0, 0.8, 1); }
.knob[data-at=b] { transition: transform 300ms cubic-bezier(0.2, 0, 0, 1); }
Why it matters, pros and cons
Why it matters
Motion tells you where hidden content lives. A different exit path loses it.
Pros
- Closed content has a predictable home.
- The menu points back to its trigger.
- Mid-flight reversals retrace the same path.
Cons
- Swipes leave in the finger's direction and speed.
- Different outcomes may take different paths on purpose.
- No visible trigger: scale from center instead.