Search code examples
csscss-animationscss-transitionscss-variables

Text underline animation in CSS - the simplest way?


I'm having an animated underline effect when user points the links on my website. The underline is a bit wider than the text itself, as there's a bit of horizontal padding.

Here's the effect I wanted to achieve and I did:

Underline animation

I was thinking if it was possible to simplify my code. After some trial and error, I used negative margin-left on the underline element and calc() to calculate its width as 100% + 2 * padding. It looks to me like an overcomplicated solution. Can the same effect be achieved without calc() and, perhaps, without negative margin?

Of note, adding a wrapper element is not an option. It needs to be a plain <a> element.

:root {
    --link-color: #f80;
    --link-underline-padding: .5em;
}

a {
    color: var(--link-color);
    display: inline-block;
    padding: 0 var(--link-underline-padding);
    text-decoration: none;
}

a:after {
    background-color: var(--link-color);
    content: '';
    display: block;
    height: .1em;
    margin-left: calc(var(--link-underline-padding) * -1);
    margin-top: .2em;
    transition: width .5s;
    width: 0;
}

a:hover:after {
    width: calc(100% + var(--link-underline-padding) * 2);
}
I find <a href="#">dogs</a> pretty cool.


Solution

  • A simple background animation can do this:

    a {
      background: linear-gradient(currentColor 0 0) 
        bottom left/
        var(--underline-width, 0%) 0.1em
        no-repeat;
      color: #f80;
      display: inline-block;
      padding: 0 .5em 0.2em;
      text-decoration: none;
      transition: background-size 0.5s;
    }
    
    a:hover {
      --underline-width: 100%;
    }
    I find <a href="#">dogs</a> pretty cool.

    Related:

    How to animate underline from left to right?

    How to hover underline start from center instead of left?