I was recently working on project where I had to create a link style that would highlight when hovered over. On hover, the highlight would appear from left, and then disappear on hoverout to the right, sort of like passing over the text. I also needed to change the color of the text, and I wanted to set it up so that it would happen as the highlight passed over the text.
My first iteration was done very simply with a pseudo element that had a red background and would go from a width of 0%
to 100%
on hover, and I would also change the position from setting it on the left to the right in order to create that passing effect:
It worked well for links that didn't break into two lines, but that's not always going to be the case. As you can see in the second link that takes up two lines, the psueudo element can't do the same since it's set to a block element, so I had to find another solution.
After some digging around, I found a great way to handle this using linear gradients and no pseudo elements:
How does this work? The linear gradient just goes from red to red so it's not really a gradient. Why don't I just use a background color? That's because gradients are considered background images in CSS, allowing us to use the background-size
property to control the size of the gradient, which you can't do with background colors. This gives us that nice, smooth effect of a highlight with very little code.
The last item I wanted to setup was to make the text change color as the highlight moved over it. As it's currently setup, the text just transitions from red to black on hover with no sense of the highlight behind it. This can be very easily done using mix-blend-mode
on a span element inside the anchor tag. Since the background color is the same as the text color, setting mix-blend-mode
to difference
will give us a black text color on hover:
In order for mix-blend-mode
to work, a z-index
needs to be set on the anchor to setup the correct layering for the blend. With all of this, the entire effect can be achieved with very few lines of code:
a {
color: red;
text-decoration: none;
position: relative;
z-index: 1;
padding: 3px;
margin: -3px;
background: linear-gradient(to right, red, red) no-repeat right;
background-size: 0% auto;
transition: background-size 0.3s, background-position 0s;
&:hover {
background-size: 100% auto;
background-position: left;
}
span {
mix-blend-mode: difference;
}
}
Gradients are quite versatile, and I'm sure I'll be using this concept to create a few other interesting highlight effects in my projects.
Top comments (1)
Nice, thanks for sharing