Lift
Rises on hover while a shadow fades in.
Live demo
The preset here changes the whole site. Slow motion and reduced motion change this stage only.
Frame by frame
Every frame of the movement, on top of each other. Wide gaps are fast. Ghosts past the dashed outline are overshoot. It updates with the preset.
When to use
Cards, tiles, and list rows that open something on click. On hover the card rises distance.sm and a shadow layer fades in. It tells the user "this is clickable" before they click.
Use it on pointer hover and keyboard focus only. Touch screens have no hover, so the CSS export wraps it in @media (hover: hover). Pair it with press for the click itself.
Recipe
Hoverable cards and tiles. The card rises distance.sm on hover and its shadow fades in. It settles back when the pointer leaves.
| State | Property | Token | Now |
|---|---|---|---|
| rest | y | literal | 0 |
| shadow | literal | 0 | |
| hover | y | -{distance.sm} | -5 |
| shadow | literal | 1 | |
| transition | Movement (spring) | {spring.fast} | stiffness 715 · damping 53 |
| transition | Fade duration | {duration.fast} | 132ms |
| transition | Fade easing | {easing.standard} | cubic-bezier(0.2, 0, 0, 1) |
Tokens used
spring.fast stiffness 715 · damping 53duration.fast 132mseasing.standard cubic-bezier(0.2, 0, 0, 1)distance.sm 5px
Code
/* lift: Hoverable cards and tiles. The card rises distance.sm on hover and its shadow fades in. It settles back when the pointer leaves.
Use: <a class="motif-lift">. The shadow is a layer that fades, so only opacity and transform animate. */
.motif-lift {
position: relative;
transition: transform var(--motif-spring-fast-duration) var(--motif-spring-fast);
}
.motif-lift::after {
content: "";
position: absolute;
inset: 0;
border-radius: inherit;
box-shadow: 0 8px 24px -6px rgb(0 0 0 / 0.25);
opacity: 0;
pointer-events: none;
transition: opacity var(--motif-duration-fast) var(--motif-ease-standard);
}
@media (hover: hover) {
.motif-lift:hover {
transform: translateY(calc(-1 * var(--motif-distance-sm)));
}
.motif-lift:hover::after {
opacity: 1;
}
}
.motif-lift:focus-visible {
transform: translateY(calc(-1 * var(--motif-distance-sm)));
}
.motif-lift:focus-visible::after {
opacity: 1;
}
/* Reduced motion: the variable overrides at the end of motif.css set
travel to 0, scale to 1, and blur to 0, so this recipe needs no extra rule. */
Reduced motion
- No rise. The shadow still fades in, so the card still answers the pointer.
- Fades take 132ms (
duration.fast), so the state change stays visible. - Turn on the Reduced motion box under the demo to preview it, or set your system to reduce motion.