In this article, we will create a custom transition animation in React/Tailwind app.
Let's build the CardContainer component with 3 cards. When we clicked on a single card, width and height changes. So the card becomes active.
Single Card component looks like this:
const Card = ({ title, color, id, setActiveCardId, activeCardId }) => {
return (
<div
onClick={() => setActiveCardId(id)}
className={`w-${activeCardId === id ? 40 : 32} border-2 border-black m-4`}
>
<div className="h-8 text-center">{title}</div>
<div className={`h-${activeCardId === id ? 40 : 32} bg-${color}`} />
<div className="h-12" />
</div>
);
};
If id and activeCardId props are equal, we set width and height to 40 if not, then to 32.
Now create a Card Container with 3 cards rendering inside:
function CardContainer() {
const [activeCardId, setActiveCardId] = React.useState("");
return (
<div className="flex items-center justify-center p-10">
{[
{ id: "1", title: "Wow", color: "red-600" },
{ id: "2", title: "Boss", color: "green-600" },
{ id: "3", title: "Coco", color: "pink-600" }
].map(card => (
<Card
key={card.id}
id={card.id}
title={card.title}
color={card.color}
activeCardId={activeCardId}
setActiveCardId={setActiveCardId}
/>
))}
</div>
);
}
It renders cards with an id, title, and color. And here we are storing the activeCardId. For now, tailwind.config.js:
empty module.exports = {
theme: {
extend: {}
},
variants: {},
plugins: []
};
and the results looks like this:
Looks good but can be even more perfect if we add some animation. First, let's modify tailwind.config.js with custom transitionProperty for width and height. And don’t forget to destruct defaultTheme.transitionProperty - we don’t want to overwrite other
const defaultTheme = require("tailwindcss/defaultTheme");
module.exports = {
theme: {
extend: {
transitionProperty: {
...defaultTheme.transitionProperty,
width: "width",
height: "height"
}
}
},
variants: {},
plugins: []
};
and in a Card adds this code 'transition-width duration-300 easy' for classes on width and height animation:
const Card = ({ title, color, id, setActiveCardId, activeCardId }) => {
return (
<div
onClick={() => setActiveCardId(id)}
className={`w-${
activeCardId === id ? 40 : 32
} border-2 border-black m-4 transition-width duration-300 easy`}
>
<div className="h-8 text-center">{title}</div>
<div
className={`h-${
activeCardId === id ? 40 : 32
} bg-${color} transition-width duration-300 easy`}
/>
<div className="h-12" />
</div>
);
};
Codesandbox example:
https://codesandbox.io/s/react-tailwind-starter-forked-bkrv4?file=/src/App.js
Top comments (1)
Wouldn't it be better to use scale instead of width? Research what is 60 fps animation?