Search code examples
htmlcsscss-animationsunderline

How do I animate a link underline to the width of the link, not the ul?


I have the following link hover animation:

*,
*::before,
*::after {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
  width: 100vw;
  height: 100vh;
}

body {
  font-family: Arial;
  background-color: red;
}

ul {
  list-style-type: none;
  width: 33vw;
  margin: 0;
  padding: 0;
}

li {
  margin: 0 10px;
  padding: 2px;
}

a {
  text-decoration: none;
  color: white;
  font-size: 25px;
}

a::after {
  content: "";
  width: 0;
  height: 2px;
  background-color: white;
  display: block;
  transition: width 0.5s;
}

a:hover::after {
  width: 100%;
}
<!DOCTYPE html>
<html>

<body>
  <ul>
    <li><a href="#">Home</a></li>
    <li><a href="#">About Us</a></li>
    <li><a href="#">Events</a></li>
    <li><a href="#">Contact</a></li>
  </ul>
</body>

</html>

In the above snippet, when I hover over each of the links, the underline properly animates. However, the underline ends at the width of the ul, not at the width of each link itself (e.g if I hover on the "Home" link, the animated underline goes way past the word "Home" itself, all the way to the end of the ul). How should I change my CSS for the a::after or a:hover::after pseudo-elements so that I get the behavior I'm looking for?


Solution

  • Make the link inline-block

    *,
    *::before,
    *::after {
      box-sizing: border-box;
    }
    
    html,
    body {
      margin: 0;
      padding: 0;
      width: 100vw;
      height: 100vh;
    }
    
    body {
      font-family: Arial;
      background-color: red;
    }
    
    ul {
      list-style-type: none;
      width: 33vw;
      margin: 0;
      padding: 0;
    }
    
    li {
      margin: 0 10px;
      padding: 2px;
    }
    
    a {
      text-decoration: none;
      color: white;
      font-size: 25px;
      display: inline-block;
    }
    
    a::after {
      content: "";
      width: 0;
      height: 2px;
      background-color: white;
      display: block;
      transition: width 0.5s;
    }
    
    a:hover::after {
      width: 100%;
    }
    <ul>
      <li><a href="#">Home</a></li>
      <li><a href="#">About Us</a></li>
      <li><a href="#">Events</a></li>
      <li><a href="#">Contact</a></li>
    </ul>