I was really scratching my head trying to get CSS transitions to work with React.
I created most of a project using React’s create-react-app and CSS, and I really liked the way it looked. I had one feature left, but I needed CSS transitions to make it look right.
Most of the internet suggested using React Transition Group and had this been a larger project, I would have gone that way. However, I really didn’t want to bring in another library when I was so close to being finished.
My stubbornness prevailed and I researched my way into a solution. Thanks to a Joe Davis blog, I learned a clever trick for adding and removing classnames, allowing me to add CSS transitions and create a carousel feature like in the gif below.
By the way, this is a long one so thanks ahead of time if you read it. I believe the most clever part of the carousel is covered in the section called “Function for Setting Classes” if you want to skip to it.
What follows is my strategy for putting five root beer pictures in a carousel. If you’d like to get the whole thing, here’s the GitHub.
Table of Contents
- Preliminary Junk
- Arrow Design & Functionality
- CSS Transitions
- Function for Setting Classes
File Structure & Design Pattern
First, I installed a
create-react-app, deleted a bunch of default stuff, and set up the file structure and components.
CardContainer.js handles the logic and state which are passed down to its children, each displayed as a
I threw my root beer images in a folder and created an
index.js file to handle their export.
Card.js is a very simple component that takes
props of an image source,
imgSrc , and a string,
classList that is returned by the function
setClass() changes the
classList string will serve the dual purpose of selecting which classes are on each
Card.js and triggering a render causing the CSS
transition animation. More on this in a bit.
Card.js in CardContainer.js
Next, I added a
Card for each image in the
I will explain the
prop in the section ‘Function for Setting Classes’, but that is how I will dynamically add and remove classes triggering a
Arrow Design & Functionality
I was a little extra with the arrow design. You could easily use buttons or links to control the carousel, but instead, I did some small scale CSS art.
I made two divs each with thick borders on the same corner and turned them in each direction — 45 degrees and 225 degrees.
To flip through my five pictures, I set up a
useState hook called
cardNum with an initial state of
On the arrow divs, I set a conditional style so the left arrow will not display if
cardNum === 1 and the right arrow will not display if
cardNum === 5.
Another possible design would be adding a clause that sets
1if it hits
5if it hits
0, allowing for a full rotation of cards.
If you’re unfamiliar, the CSS transition property animates an element so when it renders, its style properties slide from the old values to the new ones.
First, I set up three CSS classes:
Card has the
present class, it will be centered in our
previous class hides the picture off screen on the left, and the
next class hides things off screen on the right.
transition takes a duration value in seconds(
s). As the initial
Card class properties change according to
previous the transition will smooth them out for my set duration.
In this case, the current
present component will get shoved off screen and turn invisible while, based on
previous component will become visible and be pulled to the center.
One of the weaknesses of my current set-up is the changing of
absolute. I added a
25%to keep the element from awkwardly flying to the default,
top: 0. It might be a minor issue, it will be inconsistent depending on screen size.
Function for Setting Classes
At this point, we can change our
cardNum with the arrows, and our CSS is set up to employ our
transitions. All That’s left is to tie the
cardNum to each
Each Card receives a
classList which is the return value of
setClass(), a string of classnames.
Here is the
First, I set up an array called
classArr with the string
This string will be plugged into the component’s
classNames and will be read as two classnames that give some general CSS,
background-color, etc. to our
Then, based on a series of conditionals, I push
num parameter is the same as
cardNum, I push
present. I push
num is greater than
num is less than
That’s it! Clicking the arrows causes the
cardNum state to change. That triggers a render of the
CardContainer. On that render,
setClass() will be called on each
Card component. The
Cards will then have their
classList prop changed so when they render, the appropriate
Cards will transition off and on to the screen.
From top to bottom, that’s the whole thing. The nifty design concept I learned is using a function to set an array of classnames and hitting
join() on that array. Then, it’s easy to tie that to state of the parent component and manipulate that state.
As always, I hope this helps someone. If you have any suggestions or corrections, feel free to comment or email me at email@example.com.
Don’t hesitate to hit me up, I love to be correct so I love to be corrected. Also, isn’t root beer great?