When building my blog, I decided to get rid of the default underline styling on <a> elements to use my custom underline effect. If you still don’t know what kind of style I am talking about, just try to hover this link or any other link in the blog post content.

Check the final result here

As you could see, when you hover a link in the content, two lines under the text start growing from left to right and from right to left with a slightly sliding effect. I did this with pseudo elements, and bellow I will show you can implement a similar effect on your website or web application.

The a element

Our first target is the <a> element, which comes with default CSS properties that we need to restart first, like color and the most important one, text-decoration:

a { color: #0099CC; position: relative; text-decoration: none; }

The color property was set to some variation of blue

property was set to some variation of blue The position property was set to relative . Below, I will explain why.

property was set to . Below, I will explain why. The text-decoration was set to none . This is the property that will style the <a> element with the line under the text.

Adding the pseudo-elements

a::before, a::after { bottom: 0; width: 0%; content: ""; height: 2px; position: absolute; transition: width .5s; background-color: #0099CC; } a::before { left: 0; } a::after { right: 0; }

The two lines that form the underline effect in the final result that we intend to achieve are in fact pseudo-elements attacthed to the <a> element.

In the code above, the first block describes the common CSS definitions between ::before and ::after :

bottom is set to 0 because I want the underline to actually appear under the text, in this case, the <a> element.

is set to because I want the underline to actually appear under the text, in this case, the element. width is initially set to 0 , it means that you won’t be able to see anything until the mouse is over the text. The :hover selector is not defined yet.

is initially set to , it means that you won’t be able to see anything until the mouse is over the text. The selector is not defined yet. content is a property required for the pseudo-elements. In this case, I set it to an empty string.

is a property required for the pseudo-elements. In this case, I set it to an empty string. The value of height can be arbitrary. However, you may want to define a value that visually will match the <a> element font-size.

can be arbitrary. However, you may want to define a value that visually will match the element font-size. The position was set to absolute so we are able to manipulate the left , right and bottom properties, in order to align both pseudo-elements relative to the <a> element.

was set to so we are able to manipulate the , and properties, in order to align both pseudo-elements relative to the element. To give the sliding effect I defined the transition property relative to the width property with a duration of 0.5 seconds.

property relative to the property with a duration of seconds. And of course the background-color . This can be anything you feel comfortable with.

Then in the code above, there are two more blocks, and they were defined so each pseudo-element could be aligned in the left and right side of the <a> tag.

Handling on mouse hover

At this point, you should not see any effect yet, and that’s because both pseudo-elements were defined with the width property set to 0 . This makes sense because the desired effect is that the underline only appears when the mouse is on top of the link.

a:hover::before, a:hover::after { width: 50%; }

In the code above I am saying this: each time the mouse hovers an element, the ::before and ::after pseudo-elements should have its width value set to 50% . Voilà, you should be able to see the underline effect I described at the beginning of this article.

You can see the final result here too.

References

Post cover by Keith Johnson