First blog: Building an interactive card fan with CSS
Introduction
I won’t lie to you saying this is my first time trying to start a blog. But this is the first time I have an actual idea of what I’m gonna write about. See, in past attempts I’ve always tried to write these long insightful articles about technology and science, but the problem is I’m not by any means a writer, let alone a good one (You’ll find out).
So I thought I’d keep it simple and technical. I’ll look for cool shit to build in places like dribbble.com or instagram, like UX concepts and UI bits, and try to explain how to build them in a step by step fashion with code snippets, demos and images as best as I can.
If that’s something You might find interesting I suggest you stick around and see what happens ;)
Now let’s get that card fan going…
Here’s what we’re trying to build
Let’s build a card fan. You could use this to display actual cards, record covers, images, whatever you like. But for now let’s leave them blank.
Markup
The HTML is super simple let’s just write it.
<div class="cards">
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
</div>
Styles
Of course we’re not gonna write vainilla CSS. I’m not insane! Let’s just use SCSS to make things a little bit easier.
First let’s add some styling to the cards and container so the cards stay centered in the window.
Now, to make the cards spread in a fan-like fashion we’re gonna use the transform property to rotate
each card to a different angle.
We will make use of the @for
SASS keyword to “iterate” over the cards and change their rotation. Something like this:
@for $i from 1 through 5 {
div:nth-child(#{$i}) {
transform: rotate(10deg * $i);
}
}
You can learn more about this SASS syntax here.
Of course we want to keep the translate()
transform so the cards stay centered.
So it would look like this with the rest of the code:
If you check out the result, it looks a bit insane right now, for a couple of reasons:
- We are rotating the cards from the center: let’s fix that with the
transform-origin
attribute which lets us change the point of the card where the rotation is being applied. We want that to be the bottom center of the card, so the spread will show at the top of the cards - We’re starting to rotate the cards from the vertical position: Ideally we would want the cards to spread from left to right, so for example if we want the cards to spread 50 degrees, we’d want the spread to go from -25deg to 25deg, so the card group would still stay centered in the window.
To change the origin of the rotation let’s add the transform-origin
attribute to the card
.card {
...
transform-origin: center 120%;
}
You could use center bottom
too for the origin position. I used 120%
because if you position the transform-origin farther from the cards, the arc the cards will form will be bigger. Hopefully this image would make this a bit clearer:
Now, let’s change our @for
loop so the rotation of the cards start from -25deg to 25deg. So the rotate function will look something like this:
$angle: 50deg;@for $i from 1 through 5 {
div:nth-child(#{$i}) {
transform:
translate(-50%, -50%) rotate(-$angle / 2 + $angle / 6 * $i);
}
}
I’d say we’re looking pretty close right now. There’s a couple of things that could be abstracted and reused. We’re gonna extract the @for
loop styles into a @mixin
so we could reuse it later.
Learn more about mixins here
We can abstract a couple of things, like the number of cards and the angle to spread the cards. Let’s put those as mixin parameters.
Now that we can reuse the fan styling easily, we could alter some of the parameters of the fan when the user hovers over the cards container. Let’s try changing the spread from 50deg
to 60deg.
.cards {
...
@include fan(5, 50deg);
&:hover {
@include fan(5, 60deg);
}
}
Great! Now the cards spread a little bit more when hovering :D
Let’s make it a bit smoother adding a transition property to the cards, so they animate to the new rotation while hovering.
Result
Feedback
Mission accomplished! I think?
Let me know what you think! Was this useful? Was it too detailed? Is there something You would like me to build? Let me know in the comments! :)
Until next post!