Playing with Pseudo-elements: Hover Effects
Peter Adomokai
Senior Software Engineer (Fullstack Developer) and Interaction Designer
Alright. This actually took longer to write than I expected (so much to do so little time) but it's here now so let's dive right in.
Hover effects. These are probably the most underrated feature of modern day web design. Imagine having to navigate a site that didn't let you know what element you cursor was hovering over and whether the element was clickable or not. That would be horrible.
Fortunately, CSS gives us a lot of ways we can target elements and really make them pop. Unfortunately, most people can't be bothered and settle for a very basic: element:hover {color: different_color} or element:hover {background-color: different_color}.
It works. It's effective but how do we make it even better. With Pseudo-elements that's how, specifically with ::before (or ::after).
Setting the stage
<div class="container">
<div class="content">
<div class="box">
</div>
</div>
<div class="content">
<div class="box">
</div>
</div>
<div class="content">
<div class="box">
</div>
</div>
<div class="content">
<div class="box">
</div>
</div>
</div>
Now for some CSS
.container {
margin: 50px; //not important
height: 100%;
grid-gap: 20px;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px , 1fr));
margin-top: 175px; //not important
}
.container .content {
border: 2px solid black;
overflow: hidden; //super important
}
.box {
position: relative;
min-height: 420px;
width: 100%;
}
So what did I do? I used CSS grids to create 4 grids with a minimum width of 300px and a margin or grid-gap of 20px between them. Then I asked the boxes to fill the entire column and I put a border around their parent (the content) so it would be visible.
How does it look?
NB* the box has a position property of relative because we would like to move the ::before element around relative to it.
So what's next? Next we prep the pseudo-element to work its magic.
.box::before {
content: "";
height: 100px;
width: 100px;
border-radius: 50%;
background-color: black;
position: absolute;
transition: 0.5s ease;
top: -100px;
left: 50%;
transform: translateX(-50%)
}
That's a lot of CSS. Let's go over them one by one.
- Content: We went over this in the first issue, you can't use ::before or ::after without generated content. So here, we create the content and set it to empty.
- Height and width: We're setting the height and width of the generated element.
- Border-radius: With this we're transforming the generated element into a perfect circle.
- Background-color: Doesn't matter what color we set here all that matters is that we set a color.
- Position: This so we can move the generated element
- Transition: This allows to smoothly move from the pre-hover state to the post-hover state over a duration of 0.5s.
- Top: This positions the generated content relative to parent content. In this case, we're placing it above the box content (and because the content has overflow set to hidden, it doesn't show)
- Left and Transform: We use this to center the content in the middle. (for some reason, setting the left to 50% doesn't directly place it in the center, so we need to transform it by 50% to place it in the center.
Here's how it looks if we remove the overflow: hidden from the parent div.
The Effect
So next we want the circle to scale up on hover and fill out the entire box.
.content:hover .box::before {
transform: scale(11);
}
And voila. NB* I increased the transition duration to 2s so you can see the effect clearly.
I changed the positioning of the generated element. Top in the first box, left in the second box and from the top-left in the third. In the fourth box to get the sliding effect, I changed the generated content to a rectangle and set it to transform: scaleY() and transform-origin: top so it scaled downwards.
So you can let you creativity determine how you want the transition to happen (from which direction and which shape you'd like to use). Mostly, you could use this for a button but there's still other uses. I've attached below an example of how it could be used.
NB* I set the transition back down to 0.5s for this demo.
Hopefully, this article was educative or useful to you. Let me know if there's something I missed or if you have something you'd like me to cover in another article.
Cheers
FullStack Software Developer
5 年Cool ??
Expert B2B Copywriter for IT and SaaS Companies| 3D Artist | C++ Game Dev | Unreal Engine | Freelance| alterok s4 | spectreseek s5
5 年Even though I don't do web dev, the article was helpful as it made me think of elemental design differently. And the black transform looked awesome by the way. Really nice.