CSS spring example: Step-by-step
In this tutorial, we'll build the CSS spring example step-by-step.
This example is rated 1/5 difficulty, which means we'll spend some time explaining the Motion APIs that we've chosen to use (and why), and also any browser JavaScript APIs we encounter that might be unfamiliar to beginners.
Introduction
The CSS Spring example shows how to create natural-feeling CSS transitions using spring physics in React.
In this tutorial, we'll learn to use the spring
function from Motion to achieve this.
Get started
Let's start with the basic structure and functionality of our component:
"use client"
import { useState } from "react"
export default function CSSGeneration() {
const [state, setState] = useState(false)
return (
<div className="example-container">
<div className="box" data-state={state} />
<button onClick={() => setState(!state)}>Toggle position</button>
<style>
{`
.example-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 20px;
}
.example-container .box {
width: 100px;
height: 100px;
background-color: #0055ff;
border-radius: 10px;
transition: transform 0.3s ease;
transform: translateX(-100%);
}
.example-container .box[data-state="true"] {
transform: translateX(100%) rotate(180deg);
}
.example-container button {
background-color: #0055ff;
color: #000000;
border-radius: 5px;
padding: 10px;
margin: 10px;
}
`}
</style>
</div>
)
}
We're using React's useState
to create a state that moves the box between two positions. This state is toggled when the button is clicked.
If you try this code, you'll see that the box moves smoothly between the two positions. However, the animation uses a basic easing curve, which doesn't feel as natural as a spring-based animation would.
Let's animate!
Now we'll transform this basic animation into a spring animation.
Import from Motion
First, let's import the spring
function from Motion:
import { spring } from "motion"
Animations
Now let's replace the standard CSS transition with a spring animation:
.example-container .box {
width: 100px;
height: 100px;
background-color: #0055ff;
border-radius: 10px;
transition: transform ${spring(0.5, 0.8)};
transform: translateX(-100%);
}
We've replaced transition: transform 0.3s ease
with transition: transform ${spring(0.5, 0.8)}
.
spring
accepts two parameters:
- The first parameter (
0.5
) controls the perceived duration of the spring, in seconds. - The second parameter (
0.8
) controls the bounciness of the spring.0
is no bounce,1
is maximum bounce.
spring
can be used to sample points on a string, but by passing it into a string it returns a calculated duration and CSS linear()
easing function.
The reason why duration is considered a perceived duration is because this is roughly the amount of time it takes for the animation to complete, disregarding the bounciness of the spring.
This makes it easier to reason about the animation and synchronize it with other animations. If you want to make the spring bouncier, you can simply change the second parameter, while leaving the duration the same.
Conclusion
In this tutorial, we've learned how to:
- Use the
spring
function to create physics-based animations in CSS. - Apply spring animations to CSS transitions.
- Control spring behavior by adjusting duration and bounciness values.
Spring animations are perfect for creating more natural, engaging UIs. They're especially useful for transitional actions, like the one in this example, where elements need to physically move between defined states in a way that feels responsive.
Tutorial Project
We're currently working on adding a tutorial for every example on the Motion Examples website. So far, 12% of examples have a tutorial.