Link to this headingContext
When a user hovers over something actionable, like a button or a link, it can be useful to indicate to the user that the item can be interacted with. Typically this is done with a color change or an underline, but we can be more creative than that!
A favourite trick of mine is to scale up the item on hover, and add a brief
transition. That way, it appears to grow under the cursor:
The problem with this effect is that text sometimes looks wonky when scaled up, especially on non-retina monitors. The effect isn't always crisp.
A fancier way to do this would be to only scale the background when we hover:
This effect is a bit more quirky and eye-catching, and you get to avoid all the funkiness with text crispness.
Link to this headingUsage
Link to this headingWith vanilla HTML/CSS
Link to this headingWith React
We can create a utility component for this effect:
display: inline-block to the
Wrapper so that the container shrinks down to cover the children, without expanding to fill the available horizontal space.
Link to this headingExplanation
The trick to this effect is animating the pseudo-element.
We definitely want to use a
transform: scale transition, since it's both more performant and more smooth than trying to animate
height, or fussing with
If we wanted, we could also add a blank
<div> instead of using a pseudo-element… but it feels way nicer to use a pseudo-element, since it means a style concern is encapsulated entirely within our CSS.
Link to this headingAdditional Exploration
There's so much more you can do with this concept. Here are some suggestions:
- Experiment with other transforms (rotation, skew, translate…).
- Use opacity to pronounce the hover even further (say, going from 0.8 opacity to 1).
- Give other easing timing functions a shot.
- Use a keyframe animation to include several "steps" in the transition.
:active(on a button or link) to have a different effect when the user is interacting with the element.
- Apply a slightly different transition to the element itself, so that both the element and the
::afterpseudo-element move independently (but in a synchronized way).
- Use spring physics to produce a more natural effect.