Cards hover animation - WotW
June 19, 2018
Welcome to the Widget of the Week series, where I take gifs or videos of awesome UI/UX components, and bring them to life with code.
I’ve been quite busy for a couple of weeks, preparing and giving a Vue.js course in Wizeline Academy, but I’m back with another interactive component.
Today we’ll make a list of cards that animate when hovered (or clicked in mobile), the inspiration comes from this dribble created by Kreativa Studio and looks like this:
Preparations
For today’s widget we will be using Vue.js, and for some specific animations we’ll use the TweenMax.
If you want to follow along you can fork this codepen template that already has the dependencies.
The initial markup
For this component I’ll start by making a single card. It will be divided in two parts: the image and the footer with the text elements. Also for each element I’ll set a specific class so we can style it later.
At this point we should only have a big image and some text below.
Styling
Before doing anything else we need to make the card look like the reference in order to handle any needed animation.
First I’ll match the body background color, then int the card-row
I’ll make use of flex
, the justify-content
property and align-items
to center the content, in this case the cards.
Now let’s style the card. The position
will be set to relative
to be able to position the footer element and stick it to the bottom. Also we set the overflow
property to hidden
to be able to resize the background image without it getting outside the card.
For the image I set the position
to absoulte
and the left
and right
properties to -9999px
, that trick should center the image horizontally even when we animate it’s width.
Last but not least, we need to style the footer and it’s contents. For that position: absolute
and bottom:0
should keep the container at the bottom. The rest are just rules to make the elements look a little bit like the reference.
After that we should have something like this:
The behavior
For the next steps we will need more than a single card, so let’s declare the data for at least three cards.
Then let’s create the Vue instance and bind to it’s data the cards data and declare a variable to track the current card:
And now in our template we can render those cards with a v-for
directive like this:
You might have noticed that I binded a couple of events @mouseover
and mouseout
. Both are triggering a method called hoverCard
that we have not declared yet, so let’s do that.
Make the hover effect
We will make use of that selectedCard
property and also the isSelected
method to set a class to the elements we are going to animate, but first let’s add some simple CSS transitions for the whole card.
By adding the transition line in the .card
we are indicating that the height
and box-shadow
should be animated, then when the card is hovered, its height will increase along with the shadow to make it look like it is getting closer to us.
Now we’ll use the isSelected
method to set the .selected
card to the image. I’m not using :hover
in this case, because the user can be hovering the text and we still want the image animation to run, not only when the image is hovered.
And just like we did with the card let’s add a transition and a .selected
state:
The image will change it’s size when hovered and we only need to set the height because the width will automatically adjust to keep the aspect ratio.
Now that the image is expanding, I feel that the author text is too bright and can’t be read clearly. I’ll just repeat the lasts steps to make it look darker when the card is hovered:
Separate the other cards
We are almost there, but there’s still something missing. In the reference, when the card is hovered the other cards move away from it, like a repelling effect.
That effect can’t easily be done with just CSS, we will need to do the animation by calculating where each card should move and then animate it with TweenMax
.
I’ll create a new method called animateCards
that will be triggered when the selectedCard
changes.
Then for each of the cards we need to know in which direction should they move.
- First when no card is selected everything should stay the same
direction = 0
. - When a card is before the selected card it should move to the left
direction = -1
. - If the card is after the selected card it must move to the right
direction = 1
. - Finally if the card is the selected one, it should not move
direction = 0
.
After calculating the direction, with the help of this.$refs
we can select each card and make TweenMax change it’s position.
And now the final result!
That’s it for this Widget of the Week.
If you’re hungry for more you can check other WotW:
Also if you want to see a specific widget for next week, post it in the comments section.