Motion
Afloat is ikada’s motion: the raft takes your weight. A press settles, the release springs back once, and nothing else bounces.
Try it
Live ikada components. Press and hold, then let go. With reduced motion on, the same controls fade instead of moving.
- 01
Takes your weight
The press settles 1px and 3%; the release returns on a spring that overshoots once.
press 90ms · bob 0.45s, bounce 0.25 - 02
A pebble on a tray
One raised indicator slides across a recessed tray.
snappy 0.35s, bounce 0.15 - 03
Thumb and check
The switch thumb squishes toward its travel; a checkbox bobs once as it fills.
snappy · bob, on change only - 04
Success sprouts
The success glyph grows from its base and sends one ring out. Only success and creation sprout.
sprout 480ms · ring 700ms
Rules
- Press and release. A press settles the control 1px down and to scale 0.97 in 90ms ease-out and presses the shadow in; letting go returns it on the bob spring.
- Nothing else bounces. Hover is colour plus a lift in the cast shadow (120ms). Menus and table rows do not animate their highlight. Exits are short and plain: popups and toasts 110ms, dialogs 150ms, all ease-out.
- Controls. The switch thumb squishes toward its travel while pressed and slides on snappy. A checkbox bobs once as it fills. The segmented control and tabs share one raised pebble on a recessed tray.
- Success sprouts. StatusGlyph sprout grows the success shape up from its base and sends one ring out, once. Only success and creation sprout.
- Keyboard opens do not animate. A menu, select, popover or dialog opened with a key press skips the transition; ⌘K palettes do not animate at all.
- Reduced motion substitutes, never removes. Every scale becomes 1 and every offset 0, every spring collapses to a 160ms ease-out, and opacity and colour fades stay. data-motion="reduce" on <html> does the same from an app setting.
Springs
Each spring is a duration and a bounce, sampled to a CSS linear() curve at build time, so it runs on the compositor and an interrupted spring needs no JavaScript.
| Token | Spring | Used for |
|---|---|---|
| --sb-spring-smooth | 0.35s, bounce 0 | Dialogs and drawers arriving; no overshoot |
| --sb-spring-snappy | 0.35s, bounce 0.15 | Popups, toasts, the segmented and tab pebble, the switch thumb |
| --sb-spring-bob | 0.45s, bounce 0.25 | Release of a press, a checkbox filling, a success glyph landing |
Durations
| Token | Value | Reduced motion |
|---|---|---|
| --sb-duration-hover | 120ms | Unchanged: fades stay |
| --sb-duration-press | 90ms | Unchanged: fades stay |
| --sb-duration-tooltip-in | 150ms | Unchanged: fades stay |
| --sb-duration-tooltip-out | 100ms | Unchanged: fades stay |
| --sb-duration-popup-in | 140ms | Unchanged: fades stay |
| --sb-duration-popup-out | 110ms | Unchanged: fades stay |
| --sb-duration-dialog-in | 220ms | Unchanged: fades stay |
| --sb-duration-dialog-out | 150ms | Unchanged: fades stay |
| --sb-duration-slide | 250ms | Unchanged: fades stay |
| --sb-duration-toast-in | 300ms | Unchanged: fades stay |
| --sb-duration-toast-out | 110ms | Unchanged: fades stay |
| --sb-duration-wake | 520ms | Unchanged: fades stay |