Arnav Borborah
Arnav Borborah

Reputation: 11789

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?

Upvotes: 1

Views: 1520

Answers (3)

Maria Campbell
Maria Campbell

Reputation: 417

I just actually finished setting this up, but did not even want to have any extra underline for any of my links. So I fixed it with pure css (scss actually) as well, but got specific. This is the css (scss) I used to make the underline only span the width of the text:

.main-nav {
    background: rgba(103, 128, 159, 1);
    display: block;
    height: 100vh;
    left: 0;
    right: 0;
    margin-top: 0;
    margin-left: 0;
    margin-right: 0;
    padding-top: 5rem;
    overflow-y: hidden;
    position: fixed;
    top: 0;
    /* hide the menu above the screen by default */
    transform: translateX(-100%);
    /* transition adds a little animation when sliding in and out the menu */
    transition: transform 0.2s ease;
    width: 100vw;
    /* needed for me because of my intro box in index.html.
    Otherwise navigation backgrop would be behind the intro box when opened */
    z-index: 10;
    /* so that the nav link underlining from framer motion does not span across the width of the main-nav backdrop */
    & li > a {
        display: block;
        width: 6rem;
    }

    & li:nth-of-type(1) > a {
        width: 3.5rem;
    }

    & li:nth-of-type(2) > a {
        width: 3.5rem;
    }

    & li:nth-of-type(3) > a {
        width: 2.75rem;
    }

    & li:nth-of-type(4) > a {
        width: 4.75rem;
    }

    & li:nth-of-type(5) > a {
        width: 6.5rem;
    }
    & li:nth-of-type(6) > a {
        width: 2.75rem;
    }
}

.main-nav is the class for the ul. I just set an arbitrary initial width, and then the specific ones for the specific anchor elements.

Upvotes: 0

Irin
Irin

Reputation: 1276

just use inline block to your style

a {
  display: 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%;
}
<!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>

Upvotes: 1

Paulie_D
Paulie_D

Reputation: 115061

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>

Upvotes: 4

Related Questions