Mastering Mouse Enter and Exit Events With CSS Transitions
While working on a recent post that utilized CSS transitions, I stumbled upon some interesting revelations completely by accident. Switching up where you place the transition syntax can have a dramatic effect on how the transition is carried out.
Today we’re going to go over the various options for CSS transition syntax and how each affects the animation given whether your mouse is entering or exiting a hover.
19+ Million Digital Assets, With Unlimited Downloads
Get unlimited downloads of 19+ million design resources, themes, templates, photos, graphics and more. An Envato subscription starts at $16 per month, and is the best unlimited creative subscription we've ever seen.
Mouse Events in CSS
CSS transitions give us the awesome ability to implement simple animations without JavaScript. However, since there’s really not much talk about it in CSS, you would think that differing your mouse over and mouse out effects would still be something squarely in the realm of JavaScript. After all, there’s no support for something like this:
div { mouseover-transition: all 2s ease; mouseout-transition: all 1s ease; }
br>
However, it turns out you can in fact effectively control these two different variables. It’s simply not a very intuitive process. Let’s take a look at how it works.
If you want to skip the discussion and go straight to the syntax, CSS Tricks has a good example of this technique.
The Normal Syntax: Mouse In and Out Are Equal
There are a few different ways that we can go about applying a CSS transition. The first one we’ll look at is the plain old default, meaning we’ll use the standard syntax that you’ll find if you run a Google search for how to implement a CSS transition.
For experimentation purposes, we’ll keep the demo simple. We want the transition to animate the shift from a black square to a gray circle. Here’s how this looks (browser prefixes omitted for cleanliness):
#loremdiv { height: 200px; width: 200px; background: black; transition: all 1s ease; } #loremdiv:hover { background: gray; transform: rotate(1080deg); border-radius: 100px; }
br>
The behavior of this animation is typical. When you hover over the black square, in the course of one second it spins around as it increases its border radius to 100px and changes its color, making it a gray circle. Then when you take your mouse out, the opposite happens. The square spins counter clockwise back to its original position has its border radius steadily decreases and its color goes back to black.
Demo: Click here to see this example in action.
Reversed Syntax: No Mouse Out Transition
In the previous example, we placed the transition syntax in the #loremdiv selector. What happens if we reverse this and place the same snippet inside of the #loremdiv: hover selector?
#loremdiv { height: 200px; width: 200px; background: black; } #loremdiv:hover { background: gray; transform: rotate(1080deg); border-radius: 100px; transition: all 1s ease; }
br>
Even though it feels wrong, it turns out that this still produces a transition. However, it only produces a transition on the hover event, when the user exits the hover, the transformation is immediate.
This effectively gives us what we were looking for: a way to vary the mouse in and mouse out transitions. However, the mouse out is really no transition at all at this point, which isn’t very exciting.
Demo: Click here to see this example in action.
Doubled Syntax: Two Customizable Transitions
Now we’ve tried linking the transition to the normal selector and we’ve tried putting it in the hover selector, now let’s see what happens when we put a transition in both places.
#loremdiv { height: 200px; width: 200px; background: black; transition: all 0.3s ease; } #loremdiv:hover { background: gray; transform: rotate(1080deg); border-radius: 100px; transition: all 1s ease; }
br>
Notice that I’ve reduced the amount of time on the first transition so that we can tell what it does. Interestingly enough, the result here is the opposite of what many people expect.
Intuitively, you might come to the conclusion that the first transition statement will be applied on mouse in and the second on mouse out. However, the opposite is true. As we discovered in our last example, the snippet associated with the hover selector affects the mouse in event, leaving the other one for the mouse out.
Now we have the setup that we were shooting for! This gives us complete freedom to vary the mouse in and mouse out effects. What I’ve done with this example is reduce the amount of time that it takes for the animation to complete when the user exits the hover.
Demo: Click here to see this example in action.
Varying the Effects
Taking this idea even further, you can’t only vary the time, you can also vary the property and timing function. Here’s an example:
#loremdiv { height: 200px; width: 200px; background: black; transition: border-radius 0.5s ease-in; } #loremdiv:hover { background: gray; transform: rotate(1080deg); border-radius: 100px; transition: all 1s ease; }
br>
Here I stuck with the same animation that we’ve been using for the hover event, but when the user exits the hover, the only thing that animates back is the border radius.
Demo: Click here to see this example in action.
Conclusion
To sum up, there are three basic ways that you can approach CSS transitions. The first way is to link the transition to a non-hover selector. This makes the hover in and out transitions the same (only in reverse of course). The second way is to link the transition to a hover selector. This creates a hover in transition but eliminates the hover out transition.
Finally, the third way is to link transitions to both selectors. In this case, the non-hover transition will affect the hover out event and the hover transition will effect the hover in event. This is the technique that you’ll want to go with if you want the most control over the separate events.
Leave a comment below and let us know what you think of all this. Have you ever noticed that separate hover in/out events were possible? Have you utilized this in any way?