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?