2

I'm trying to animate the elements in my navbar to have a ease-in-out underline when hovered over. However, instead of underlining only the selected link, it underlines the entire ul element.

How can I fix this?

a {
  text-decoration: none;
  color: black;
}

.nav a::before {
  content: "";
  position: absolute;
  width: 100%;
  height: 2px;
  bottom: 0;
  left: 0;
  background-color: rgb(92, 149, 112);
  visibility: hidden;
  transform: scaleX(0);
  transition: all 0.3s ease-in-out 0s;
}

.nav a:hover::before {
  visibility: visible;
  transform: scaleX(1);
}

ul.nav {
  font-size: 11px;
  list-style: none;
  position: fixed;
  display: block;
  padding: 0;
  margin: 0;
  z-index: 100;
  top: 0.5em;
  right: 1.5em;
}

.nav li {
  display: inline-block;
  margin: 7px 15px;
}

.nav a:active::before {
  visibility: visible;
  transform: scaleX(1)
}
<ul class="nav">
  <li id="nav-home"><a id="a-home" href="#">Home</a></li>
  <li id="nav-services"><a href="#">Services</a></li>
  <li id="nav-about"><a href="#">About</a></li>
  <li id="nav-contact"><a href="#">Contact</a></li>
</ul>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415

2 Answers2

4

You need to include a relative parent li to enclose the absolutely positioned element a. Absolute Positioning inside Relative Positioning The absolutely positioned a was taking the whole ul as the relative parent until then.

Added Code:

.nav li {
  position: relative;
}

.nav a::before  { 
   bottom: -2px; /* To match the border height */
}

a {
  text-decoration: none;
  color: black;
}

.nav li {
  position: relative;
}

.nav a::before {
  content: "";
  position: absolute;
  width: 100%;
  height: 2px;
  bottom: -2px;
  left: 0;
  background-color: rgb(92, 149, 112);
  visibility: hidden;
  transform: scaleX(0);
  transition: all 0.3s ease-in-out 0s;
}

.nav a:hover::before {
  visibility: visible;
  transform: scaleX(1);
}

ul.nav {
  font-size: 11px;
  list-style: none;
  position: fixed;
  display: block;
  padding: 0;
  margin: 0;
  z-index: 100;
  top: 0.5em;
  right: 1.5em;
}

.nav li {
  display: inline-block;
  margin: 7px 15px;
}

.nav a:active::before {
  visibility: visible;
  transform: scaleX(1)
}
<ul class="nav">
  <li id="nav-home"><a id="a-home" href="#">Home</a></li>
  <li id="nav-services"><a href="#">Services</a></li>
  <li id="nav-about"><a href="#">About</a></li>
  <li id="nav-contact"><a href="#">Contact</a></li>
</ul>
m4n0
  • 29,823
  • 27
  • 76
  • 89
  • why your reopened the question when it's a perfect duplicate? – Temani Afif Jan 06 '20 at 09:54
  • This can have multiple solutions altering the structure. There is no mention of positioning in the question. – m4n0 Jan 06 '20 at 12:16
  • 1
    whataver the structure/solution is, the issue remain the same which is a lack of position:relative when dealing with position:absolute. The OP will not mention positionning since he didn't know about his issue. By the way, your answer and the other one confirms the duplicate. – Temani Afif Jan 06 '20 at 13:22
2

The problem here is that the pseudo element a::before is absolutely positioned relative to the ul.nav, since that is the closest positioned element above it. As a result, the element is broken out of the flow of the document, and so width: 100%" is making it take 100% of the available width of the ul. Add position: relative to your a style as in the following example and it will work as you expected:

a {
  text-decoration: none;
  color: black;
  position: relative;
}

.nav a::before {
  content: "";
  position: absolute;
  width: 100%;
  height: 2px;
  bottom: 0;
  left: 0;
  background-color: rgb(92, 149, 112);
  visibility: hidden;
  transform: scaleX(0);
  transition: all 0.3s ease-in-out 0s;
}

.nav a:hover::before {
  visibility: visible;
  transform: scaleX(1);
}

ul.nav {
  font-size: 11px;
  list-style: none;
  position: fixed;
  display: block;
  padding: 0;
  margin: 0;
  z-index: 100;
  top: 0.5em;
  right: 1.5em;
}

.nav li {
  display: inline-block;
  margin: 7px 15px;
}

.nav a:active::before {
  visibility: visible;
  transform: scaleX(1)
}
<ul class="nav">
  <li id="nav-home"><a id="a-home" href="#">Home</a></li>
  <li id="nav-services"><a href="#">Services</a></li>
  <li id="nav-about"><a href="#">About</a></li>
  <li id="nav-contact"><a href="#">Contact</a></li>
</ul>
Michael Rodriguez
  • 2,142
  • 1
  • 9
  • 15