visit
is a reusable React component that I’ve made to drop in whenever I want to quickly add some animation effects to my projects. A simple utility component, it combines CSS Animation with Tailwind classes to create fluid, eye-catching animations with minimal effort.
Let’s take a look at how it is used. After importing the component, define from
and to
states with Tailwind classes. Wrap the target element within <AnimateIn/> to see the animation come to life.
import AnimateIn from '../animation/AnimateIn';
<AnimateIn
from="opacity-0 scale-90"
to="opacity-100 scale-100"
duration={500}
>
<YourComponent />
</AnimateIn>
import AnimateIn from '../animation/AnimateIn';
<header>
<AnimateIn
as="h1"
from="opacity-0 translate-y-32"
to="opacity-100 translate-y-0"
delay={500}
duration={300}
className="text-4xl"
style={{transitionTimingFunction:"cubic-bezier(0.25, 0.4, 0.55, 1.4)"}}
>
My Big Headline
</AnimateIn>
<AnimateIn
as="h2"
from="opacity-0 scale-0"
to="opacity-100 scale-100"
delay={800}
duration={500}
className="text-lg"
>
This is a subtitle below the headline
</AnimateIn>
</header>
In the headline example, <AnimateIn/> is used to create a sliding effect combined with a fade-in. Here’s how each property contributes to the animation:
as
property: By setting as="h1"
, we tell AnimateIn to render the animation as an <h1>
element.
from
and to
properties: The from
property starts the headline off-screen (translate-y-32
, moving it 32 units down) and invisible (opacity-0
). The to
property then brings the headline to its final position (back to translate-y-0
) and makes it fully visible (opacity-100
).
duration
property: The animation is set to begin immediately with no delay and runs for a quick 300ms.
className
property: The className="text-4xl"
applies Tailwind's utility class to set the font size, making the headline prominently stand out.
style
property: The custom transitionTimingFunction
(cubic-bezier(0.25, 0.4, 0.55, 1.4)
) adds a unique ease to the animation, giving it a bounce-like effect.
as
property: Here, as="h2"
renders the component as an <h2>
element, suitable for a subtitle.
from
and to
properties: The subtitle starts scaled down to zero (scale-0
) and invisible (opacity-0
), then scales up to its natural size (scale-100
) and becomes fully visible (opacity-100
). This scaling effect, paired with a fade-in, adds depth to the animation.
delay
and duration
properties: The subtitle also starts after an 800ms delay so that it begins after the headline has fully animated. This staggered approach ensures that each element gets its moment of focus.
className
property: The className="text-lg"
sets the subtitle's font size, making it smaller than the headline but still significant.
To better understand what’s happening, let’s look at the source code for <AnimateIn/> :
<AnimateIn/> uses a useState
hook to initialize the animation state with the from
property, which should be one or more Tailwind utility classes, setting the stage for the animation’s starting point before any animation takes place.
The first useEffect
hook in the component is for respecting user preferences for reduced motion. By listening to the (prefers-reduced-motion: reduce)
media query, the animation behavior is based on the user’s system settings. If reduced motion is preferred, the animation is skipped entirely, directly setting the animation state to the to
property, allowing for an accessible experience.
The second useEffect
hook is where the animation logic resides. If the user has not indicated a preference for reduced motion, the component sets a timer that changes the animation state from the initial from
value to the final to
value after the specified delay. This transition creates the visual effect of animation.
The React.createElement
function call is the component’s rendering mechanism. It dynamically creates an HTML element based on the as
prop, allowing the use of the component across different HTML elements. The className
is constructed using thecn
function as , which combines Tailwind’s utility classes, the custom className
passed as a prop, and the current animation state. This dynamic class assignment is what applies the desired styles and transitions to the element.
Additionally, there is astyle
attribute that can be passed in to directly set styling properties on the animation container. The transitionDuration
is set based on the duration
prop, but it intelligently switches to 0ms
if the user prefers reduced motion, effectively disabling the animation while maintaining the component’s functionality.
If you’d like to use <AnimateIn/> in your own project and it already uses , then you already have everything you need, just and add it to your components.
Otherwise, you’ll want to as well as mxcn
the for merging tailwind classes.
Also, I’ve put together a nice demo page for playing around with creating different animations with <AnimateIn/> at .
Also published