Hover animations with pure CSS.
Recently, I was working on a React web app for my project ranna. I was thinking about how to display general information about the service like endpoints, versions, copyright and imprint. But I wanted to keep the UI as clean and straight-forward as possible, so something like a router page or footer was no choice.
So, I thought of a popup which appears when you hover over the logo. Of course, with some fancy animation. The result looks like shown below.
The thing is, implementing an element which has an in and out animation on hover is not that straightforward as you might think — or already know.
I guess, the first thing most peoples would go for is to use the display
property. But the thing is, when you toggle display on hover, all your animation control specified with transition
is ignored, because display
can not be animated with CSS.
But why use display
at all? Just toggle the opacity and call it a day! Well, that will not have the desired result, sadly. Try to click the button in the example below and you know what I mean.
Just because an element is "not visible" (translucent to be concise), that does not mean it "does not exist" anymore. It is still rendered above the elements below and will block mouse events, because you actually interact with the translucent element.
Of course, you can set an animation
. But this only triggers when the element appears. There is no way (currently) to trigger an animation on element disappear.
If you really want to, you can also use really ugly JavaScript to achieve this effect by binding the mouseenter
and mouseleave
events to functions which set the element style opacity and display. This also needs to be done with timings, otherwise you would end up with a result like solution #1.
But there is a way better solution to do it in raw CSS. As you might know — or maybe not — there is a CSS property called pointer-events
which can control the click behavior of an element. So, just toggle pointer-events
to none
when the element is translucent and set pointer-events
back to all
when it is visible.
Now, the element becomes translucent when not hovered over the "icon". It is still there, like in #2, but now mouse events are ignored by this element, so underlying elements can be interacted with.
Easy! Isn't it?
If you are interested in how I implemented it in the React web app of ranna, take a look into the repository, if you want. 😏