Skip to content
buttery

v1.0.0

Source on GitHub

Version 1.0.0

Principles

The ten rules every buttery animation follows, and the few things it never animates.

buttery's motion follows ten rules, measured from apps that feel smooth to use. Use them to decide whether something should move at all, and how, before reaching for a preset.

The ten rules

  1. Direct manipulation is instant

    Dragging a slider or picking a swatch updates the result in the same frame. A value the person is driving is set, never tweened.

  2. Discrete changes settle in about 250ms

    A change of state settles with no overshoot, on spring.smooth. Small selection indicators, such as a segmented control's pill, are quicker, on spring.snappy.

  3. One surface morphs

    A surface changes shape instead of closing and reopening: a menu that switches sections resizes, and a card that opens becomes its dialog.

  4. Containers follow their content

    A container animates its height when what's inside it changes, and the content crossfades.

  5. New context dims

    Rather than blacking out, a menu over content blurs the page behind, and a dialog darkens it.

  6. Arrivals are choreographed

    A hero or a grid enters with a short rise and fade, staggered about 50ms, in 900ms at most, once.

  7. Exits are faster than entrances

    An exit takes about 60% as long as its entrance, because the person has already decided.

  8. Hover answers within 150ms

    An arrow extends, a card lifts 2px. Nothing is shown only on hover.

  9. Celebrations are rare

    Confetti fires only for a real finish, such as completing onboarding.

  10. Reduced motion is a mode of its own

    Springs become instant, reveals become plain fades of 100ms at most, loops stop and confetti is off. Layout still updates.

What never animates

  • Numbers a person typed or set.
  • Layout during a drag.
  • Anything longer than 400ms, apart from choreographed entrances and ambient loops.

CSS transitions

CSS transitions move only opacity, transforms, colors, shadows, filter and backdrop-filter. A change of size or position goes through Motion's layout.

Do

css

.chip {
  transition: background-color var(--bt-dur-fast) var(--bt-ease-out);
}

Transition the property that changes, on a token.

Don't

css

.chip {
  transition: all 120ms;
}

transition: all animates layout too, and buttery's stylelint config fails it.

  • Tokens

    The springs, durations, easings and delays every buttery animation is made of.

  • Presets

    The motion primitives that apply buttery's rules for you, from presence and morphing to reveals and loops.