Link Underline Deconstructed
I love a good link hover effect. Maggie Appleton has a great selection across their whole site.
My favourite is used on the site header and article topic links. It has a lovely underline effect that draws in from both sides like closing curtains.
Maggie has made the site source available on GitHub, which includes the CSS for this link hover effect.
Here’s a copy & paste recreation:
See the Pen Untitled by Mike (@m-allanson) on CodePen.
Most of the work is done with a background colour and a polygon specifying a clip-path
. On hover, the polygon coordinates are transformed to different positions. The initial polygon is:
clip-path: polygon(
0% 0%,
0% 100%,
0 100%,
0 0,
100% 0,
100% 100%,
0 100%,
0 100%,
100% 100%,
100% 0%
);
And the end polygon is:
clip-path: polygon(
0% 0%,
0% 100%,
100% 100%,
50% 0,
50% 0,
50% 100%,
50% 100%,
0 100%,
100% 100%,
100% 0%
);
This is a ten point polygon that when transformed, somehow creates the curtain closing animation effect.
I couldn’t work out how the polygon coordinates result in that animation. So I plotted them out. Like this:
See the Pen Untitled by Mike (@m-allanson) on CodePen.
Drag the slider around to see how the polygon is transformed throughout the animation.
It turns out that two of the points are not needed for this animation to work. Remove point 7 and point 8, and you’re left with eight points describing two trapezoids. Like this:
See the Pen Effect Visualisation by m-allanson (@m-allanson) on CodePen.
While this is still fairly tricky to visualise in my head, it makes much more sense to me than the ten point polygon.
Finally, I recreated the effect using two separate polygons.
See the Pen Link Hovers by Mike (@m-allanson) on CodePen.
This is more verbose than the first version, but I think the polygons are easier to understand without dropping the coordinates into a separate tool to visualise them.
&::before {
clip-path: polygon(0% 0%, 0% 0%, 0% 100%, 0% 100%);
}
&:hover::before {
clip-path: polygon(0% 0%, 50% 0%, 100% 100%, 0% 100%);
}
&::after {
clip-path: polygon(100% 0%, 100% 0%, 100% 100%, 100% 100%);
}
&:hover::after {
clip-path: polygon(100% 0, 50% 0, 0% 100%, 100% 100%);
}