1

Consider the HTML

<section id="speak-to-our-experts">
    <a class="mega-link mega-link--primary" href="#">
        <h2>get in touch</h2>
        <span>speak to one of our experts</span>
    </a>
</section>

The following CSS causes me problems with the text in the anchor element.

#speak-to-our-experts {
  .mega-link {
    display: block;
    padding: 3.5rem 0 4.625rem;
    width: 100%;
    text-decoration: none;
    text-align: center;
    transition: background-color .3s;
    position: relative;
    
    &.mega-link--primary {
      background-color: #ef0d33;
      color: $white;
      overflow: hidden;
    }
    &.mega-link--primary:hover:before {
      transform: translateX(10%) skew(-20deg);
      opacity: 1;
    }
    &.mega-link--primary:before {
      content: "";
      position: absolute;
      top: 0;
      right: 0;
      width: 140%;
      height: 100%;
      transform: translateX(100%);
      background-color: #cb0b2b;
      opacity: 0;
      transition: transform 1.1s ease,opacity .3s ease;
    }
  }
}

Although I get the slide in effect from the pseudo element as required - the opacity causes me problems as it hides the text underneath. I've experimented with z-index to no avail. What's happening here?

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
cookie
  • 2,546
  • 7
  • 29
  • 55
  • opacity < 1 creates a new stacking context - see https://philipwalton.com/articles/what-no-one-told-you-about-z-index/ for a more in-depth explanation of the issue. – 04FS May 27 '19 at 12:12
  • @04FS it's more about painting order here. The opacity or the transform or the position:absolute will make the element to be painted after the content. – Temani Afif May 27 '19 at 12:15

1 Answers1

2

Adjust z-index like below. The one in .mega-link will create a stacking context preventing the pseudo element to go behind and the one on the pseudo element will make it the lowest layer inside that stacking context.

.mega-link {
  display: block;
  padding: 3.5rem 0 4.625rem;
  width: 100%;
  text-decoration: none;
  text-align: center;
  transition: background-color .3s;
  position: relative;
  z-index:0; /*added*/
}

.mega-link--primary {
  background-color: #ef0d33;
  color: #fff;
  overflow: hidden;
}

.mega-link--primary:hover:before {
  transform: translateX(10%) skew(-20deg);
  opacity: 1;
}

.mega-link--primary:before {
  content: "";
  position: absolute;
  z-index:-1; /*added*/
  top: 0;
  right: 0;
  width: 140%;
  height: 100%;
  transform: translateX(100%);
  background-color: #cb0b2b;
  opacity: 0;
  transition: transform 1.1s ease, opacity .3s ease;
}
<section id="speak-to-our-experts">
  <a class="mega-link mega-link--primary" href="#">
    <h2>get in touch</h2>
    <span>speak to one of our experts</span>
  </a>
</section>

Related: Why can't an element with a z-index value cover its child?


Another idea is to make sure the text will be painted later by adding position:relative for example:

.mega-link {
  display: block;
  padding: 3.5rem 0 4.625rem;
  width: 100%;
  text-decoration: none;
  text-align: center;
  transition: background-color .3s;
  position: relative;
}

.mega-link--primary {
  background-color: #ef0d33;
  color: #fff;
  overflow: hidden;
}

.mega-link--primary:hover:before {
  transform: translateX(10%) skew(-20deg);
  opacity: 1;
}

.mega-link--primary:before {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  width: 140%;
  height: 100%;
  transform: translateX(100%);
  background-color: #cb0b2b;
  opacity: 0;
  transition: transform 1.1s ease, opacity .3s ease;
}

.mega-link--primary *{
  position:relative;
}
<section id="speak-to-our-experts">
  <a class="mega-link mega-link--primary" href="#">
    <h2>get in touch</h2>
    <span>speak to one of our experts</span>
  </a>
</section>

Related: Why does position:relative; appear to change the z-index?

Temani Afif
  • 245,468
  • 26
  • 309
  • 415