'Pseudo element overlaps child element

Fiddle!

 .wrapper {
   justify-content: center;
   display: flex;
   background: black;
 }
 .outer {
   text-decoration: none;
   display: inline-block;
   position: relative;
   background: #555;
 }
 .outer::before {
   display: block;
   content: "";
   position: absolute;
   top: 0;
   width: 100%;
   height: 5px;
   background: orange;
   transition: all 0.3s;
 }
 .outer:hover::before {
   height: 100%;
 }
 .inner {
   display: inline-block;
   color: white;
   padding: 20px;
 }
<div class="wrapper">
  <a class="outer" href="#">
    <span class="inner">
            Hover
    </span>
  </a>
</div>

you look at the fiddle and hover over the box, you'll see that the ::before pseudo element overlaps the text. I researched for half an hour but didnt find an answer. I'd appreciate if you can give me some help on how I can make the element dont overlop the text. I can use data attributes.



Solution 1:[1]

Try adding position: relative to the CSS rules for .inner.

.wrapper {
  justify-content: center;
  display: flex;
  background: black;
}
.outer {
  text-decoration: none;
  display: inline-block;
  position: relative;
  background: #555;
}
.outer::before {
  display: block;
  content: "";
  position: absolute;
  top: 0;
  width: 100%;
  height: 5px;
  background: orange;
  transition: all 0.3s;
}
.outer:hover::before {
  height: 100%;
}
.inner {
  display: inline-block;
  position: relative;
  color: white;
  padding: 20px;
}
<div class="wrapper">
  <a class="outer" href="#">
    <span class="inner">
        Hover
    </span>
  </a>
</div>

I believe what's happening is that the position: absolute on .outer::before is putting it in a new stacking context, and span.inner is stuck in another stacking context below. Adding position: relative to .inner brings your text into a whole new stacking context above everything else.

I also forked your Fiddle here.

Solution 2:[2]

Instead of making the pseudo element transition to a larger size, transition the background color of the element to match the pseudo element. It gives the a similar effect.

jsfiddle

.wrapper {
    justify-content: center;
    display: flex;
    background: black;
}
.outer {
    text-decoration: none;
    display: inline-block;
    position: relative;
    background: #555;
    transition: all 0.3s;
}
.outer::before {
    display: block;
    content: "";
    position: absolute;
    top: 0;
    width: 100%;
    height: 5px;
    background: orange;
}
.outer:hover {
    height: 100%;
    background: orange;
}
.inner {
    display: inline-block;
    color: white;
    padding: 20px;
}

I didn't spend very long on this so maybe it can be tweaked to match your effect as originally intended.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 davidhartman00