Skip to content

Motion

Five durations, five curves and three spring configurations. Seven presets alias them, so a sheet, a dialog and a toast move the same way in every screen and in the code.

On this page
  1. Duration
  2. Easing
  3. Springs
  4. Presets
  5. Components
  6. Animated components
  7. Reduce Motion

How long should a transition take?

120 ms for a small state change, 200 ms for a sheet, a dialog or a page push, 320 ms for progress and 480 ms for a skeleton loop. Click a row to run that one on its own.

  • motion/duration/instant0ms
  • motion/duration/fast120ms
  • motion/duration/base200ms
  • motion/duration/slow320ms
  • motion/duration/slower480ms
Duration, token, value in milliseconds, used by
TokenValue, msUsed by
motion/duration/instant0No component
motion/duration/fast120Sheet exit, toast enter, toggle state, Table sort, Spinner steps
motion/duration/base200Sheet enter, dialog enter, page push, Segmented Control, Tabs, Typing Indicator
motion/duration/slow320Progress Bar, Progress Ring
motion/duration/slower480Skeleton pulse

No preset reads instant. Progress Bar and Progress Ring read slow directly, so a component can name a duration without a preset, and the Components section below lists who reads what.

Which easing curve fits which movement?

Decelerate for what enters, accelerate for what leaves, standard for small changes that stay put, emphasized for hero moves and linear for loops. Duration says how long, easing says where the time goes.

  • motion/easing/linearcubic-bezier(0, 0, 1, 1)
  • motion/easing/standardcubic-bezier(0.2, 0, 0, 1)
  • motion/easing/deceleratecubic-bezier(0, 0, 0, 1)
  • motion/easing/acceleratecubic-bezier(0.3, 0, 1, 1)
  • motion/easing/emphasizedcubic-bezier(0.05, 0.7, 0.1, 1)
Easing, token, value, used by
TokenValueUsed by
motion/easing/linearcubic-bezier(0, 0, 1, 1)Skeleton pulse, Spinner, Typing Indicator
motion/easing/standardcubic-bezier(0.2, 0, 0, 1)Toggle state, Segmented Control, Tabs, Table sort
motion/easing/deceleratecubic-bezier(0, 0, 0, 1)Sheet enter, toast enter
motion/easing/acceleratecubic-bezier(0.3, 0, 1, 1)Sheet exit
motion/easing/emphasizedcubic-bezier(0.05, 0.7, 0.1, 1)Dialog enter, page push, Progress Bar, Progress Ring

decelerate and accelerate are a pair: a thing arriving slows into place, a thing leaving speeds away. emphasized is the steepest curve off the line, with about 78 percent of the distance covered in the first fifth of the time and then a long settle, which is why it carries the dialog and the page push. Never use linear for an entrance.

How do the three springs behave?

Three configurations, stated as response, damping and mass. Native code takes them as springs; on the web, sample the spring into a CSS linear() curve and run it over its response.

Springs, token, response, damping, mass
TokenResponseDampingMass
motion/spring/subtle0.300.901.0
motion/spring/default0.400.801.0
motion/spring/bouncy0.500.651.0

subtle carries motion/toast/enter and motion/toggle/state. default carries motion/sheet/enter and motion/dialog/enter.

bouncy is referenced by no preset, so it is there for a component that asks for it directly. Mass is 1.0 on all three, and response and damping are the only two things that move.

A spring on the webmotion/spring/subtle as CSS linear()
/* motion/spring/subtle: response 0.30, damping 0.90.
   Run it over its response, 300 ms. */
.toggle-handle {
  transition: transform 300ms linear(
    0, 0.0419 3.57%, 0.139 7.14%, 0.2596 10.71%,
    0.3843 14.29%, 0.5017 17.86%, 0.606 21.43%, 0.695 25%,
    0.7685 28.57%, 0.8277 32.14%, 0.8742 35.71%, 0.9101 39.29%,
    0.9372 42.86%, 0.9573 46.43%, 0.9719 50%, 0.9822 53.57%,
    0.9894 57.14%, 0.9943 60.71%, 0.9975 64.29%, 0.9995 67.86%,
    1.0006 71.43%, 1.0012 75%, 1.0015 78.57%, 1.0015 82.14%,
    1.0014 85.71%, 1.0012 89.29%, 1.0011 92.86%, 1.0009 96.43%,
    1
  );
}

The curve is the spring the Figma file plays, sampled at 29 points. subtle peaks at 1.0015 and default overshoots to 1.0152, which is the settle of a sheet or a dialog; the animated components below run both this way.

Which motion presets does the kit ship?

Seven presets, every one an alias. A preset holds no value of its own, it points at a duration, a curve and, where the platform can spring, a spring.

  • motion/sheet/enterbase 200ms, decelerate
  • motion/sheet/exitfast 120ms, accelerate
  • motion/dialog/enterbase 200ms, emphasized
  • motion/toast/enterfast 120ms, decelerate
  • motion/toggle/statefast 120ms, standard
  • motion/page/pushbase 200ms, emphasized
  • motion/skeleton/pulseslower 480ms, linear
Presets, preset, duration, easing, spring
PresetDurationEasingSpring
motion/sheet/enterbasedeceleratedefault
motion/sheet/exitfastaccelerateNone
motion/dialog/enterbaseemphasizeddefault
motion/toast/enterfastdeceleratesubtle
motion/toggle/statefaststandardsubtle
motion/page/pushbaseemphasizedNone
motion/skeleton/pulseslowerlinearNone

There is no motion/dialog/exit. Sheet ships both directions and dialog ships only enter, so the exit of a dialog has no token yet.

Which components move, and how?

The 14 components that move each name the preset they take their timing from, so retiming a preset retimes every component that reads it.

  • fast, standard120ms · Toggle, Checkbox, Radio, Table sort
  • base, standard200ms · Segmented Control, Tabs
  • base, emphasized200ms · Accordion
  • slow, emphasized320ms · Progress Bar, Progress Ring, Dynamic Island
  • slower, linear480ms · Skeleton
Motion in components: component, trigger, preset and timing
ComponentTriggerPresetTiming
AccordionClickmotion/duration/base200 ms, ease out
Button, loadingLoopmotion/skeleton/pulse600 ms, ease in out
CheckboxClickmotion/toggle/state120 ms, standard
Dynamic IslandPressmotion/dialog/enter320 ms, emphasized
Progress BarLoopmotion/duration/slow320 ms, emphasized, 600 ms dwell
Progress RingLoopmotion/duration/slow320 ms, emphasized, 600 ms dwell
RadioClickmotion/toggle/state120 ms, standard
Segmented ControlClickmotion/duration/base200 ms, standard
SkeletonLoopmotion/skeleton/pulse480 ms, linear
SpinnerLoopmotion/duration/fast80 ms per step, linear, 8 steps
Table, sortPressmotion/duration/fast120 ms, standard
TabsClickmotion/duration/base200 ms, standard
ToggleClickmotion/toggle/state120 ms, standard
Typing IndicatorLoopmotion/duration/base200 ms, linear, 100 ms dwell

The Timing column is what each component animates with in the Figma file. The collection holds 31 variables, and every component that moves reads from it.

Which components animate their own state change?

The library holds 9 Motion / sets that play their own transition on the Figma timeline. Search “Motion /” in the Assets panel and the instance animates as is. Each has one-shot variants and a Loop for presentations, all timed from the presets above.

Loop variants on the 2 s timeline
  • Toggle

    Turn on, Turn off, Loop

  • Checkbox

    Check, Uncheck, Loop

  • Radio

    Select, Deselect, Loop

  • Button

    Tap, Loop

  • Toast

    Enter, Exit, Loop

  • Skeleton

    One component, two pulses in 1.92 s

  • Dialog

    Enter, Exit, Loop

  • Sheet

    Enter, Exit, Loop

  • Page Push

    Push, Pop, Loop

The sets are Motion / Toggle, Checkbox, Radio, Button, Skeleton, Toast, Dialog, Sheet and Page Push. Place an instance in a top-level frame and press play. Use a one-shot variant in a prototype and Loop on a cover or in a presentation.

One-shot variants start at 0.2 s. Loop plays the change at 0.4 s and back at 1.4 s, so a 2 s timeline loops cleanly, and the drawings above play the Loop variants that way.

Animated components: component, variants, what moves, timing
ComponentVariantsWhat movesTiming
ToggleTurn on, Turn off, LoopThe handle travels 16, Track on fades inHandle motion/toggle/state/spring, subtle, 300 ms. Track 120 ms, standard
CheckboxCheck, Uncheck, LoopThe box scales in from 0.8 and the mark draws itself; Uncheck fades bothBox spring subtle, 300 ms. Fill and mark 120 ms, standard
RadioSelect, Deselect, LoopThe ring fills and the dot springs in from 0.4Dot spring subtle, 300 ms. Ring 120 ms, standard
ButtonTap, LoopScales to 96 percent and darkens on press, springs back on releasePress motion/duration/fast and motion/easing/standard, 120 ms. Release motion/spring/subtle
ToastEnter, Exit, LoopEnter drops 24 and fades in, Exit lifts 12 and fades outEnter position spring subtle, opacity 120 ms decelerate. Exit 120 ms, accelerate
DialogEnter, Exit, LoopThe card scales in from 0.92 over a scrim, and out to 0.96Enter scale motion/dialog/enter/spring, default, 400 ms, opacity 200 ms emphasized. Exit 120 ms, accelerate
SheetEnter, Exit, LoopThe sheet rises 387 over a scrimEnter sheet spring default, 400 ms, scrim 200 ms decelerate. Exit 120 ms, accelerate
Page PushPush, Pop, LoopThe new screen slides in from the trailing edge, the old one shifts 30 percent and dimsmotion/page/push, 200 ms, emphasized
SkeletonOne componentThree list rows pulse between 100 and 40 percentmotion/skeleton/pulse, 480 ms each way, linear, two cycles in 1.92 s

Every chart except Legend animates on the same timeline. Bar raises each column 12 from a fade over 480 ms, 50 ms apart, and Line draws its current series over 600 ms on standard.

Eight example screens enter in reading order, in Light and Dark.

What should motion do when Reduce Motion is on?

Swap the movement for a fade or an instant change and keep the state change. With Reduce Motion on, the Play buttons on this page move the dot to the end of the track without animating it.

A sheet still opens, a toggle still flips and a toast still appears. What goes is the travel: a slide, a scale or a spring becomes a fade at the same duration or a cut, so the new state is visible without the reader being moved across the screen.

Looping motion such as Skeleton pulse and Spinner stops on a still frame. The animated components above rest on their end state the same way, and their Pause button stops the loop at any time.