Skip to content
Skip design navigation
Etesie Alpha
Loading account
← Back to transition patterns
Motion · Use the system · Guide

Applying a transition

Picking the pattern is the design decision. Wiring it is where transitions usually go wrong — two surfaces animating independently, a back gesture that does not undo the forward one, or a z-order that puts the outgoing screen on top. These are the mechanics.

Sequencing

The two surfaces are not symmetric

Outgoing Leaves early and fast

Starts immediately, uses an accelerating curve and the shorter duration. Nothing on it needs to stay readable, so its opacity can fall well before the movement completes.

--md-sys-motion-easing-emphasized-accelerate
Incoming Arrives and settles

Decelerates into place over the longer duration. If it also fades, the fade finishes before the movement does, so the content is legible while it is still settling.

--md-sys-motion-easing-emphasized-decelerate

Overlapping the two is what makes a transition read as one event rather than two. A hard hand-off — outgoing fully gone before incoming starts — is the most common reason a correct pattern still feels wrong.

Ownership

One element owns the transition

  1. The shared element wins. In a container transform the container animates; the content inside it cross-fades and does not run its own transition. Two competing animations on nested elements read as a glitch.
  2. The incoming surface sits on top. Z-order follows direction of travel, so the arriving surface covers the leaving one — otherwise the transition looks like it is running backwards.
  3. The reverse is the same transition, reversed. A back gesture replays the forward transition with the directions swapped. Substituting a different pattern on the way back makes the hierarchy unlearnable.
  4. Interruptions retarget, they do not restart. This is the argument for driving transitions with springs: a tap during the animation re-aims it instead of snapping to the end and starting over.
From your theme

A worked pairing

A sheet opening over part of the screen. Values are live, so they follow the scheme and speed you have set.

/* incoming sheet — decelerates into place */
.sheet[data-state='open'] {
  animation-name: sheet-enter;
  animation-duration: 300ms;
  animation-timing-function: var(--md-sys-motion-easing-emphasized-decelerate);
  animation-fill-mode: both;
}

/* outgoing scrim — leaves sooner, and faster */
.scrim[data-state='closed'] {
  animation-name: scrim-exit;
  animation-duration: 200ms;
  animation-timing-function: var(--md-sys-motion-easing-emphasized-accelerate);
  animation-fill-mode: both;
}

/* state changes inside the sheet stay on the physics system */
.sheet .chip {
  transition-property: background-color, color;
  transition-duration: var(--et-motion-spring-fast-effects-duration);
  transition-timing-function: var(--et-motion-spring-fast-effects-easing);
}

Note the split: the transition itself uses directional curves because a spring has no notion of leaving, while the state changes inside it use the physics system.