overflow: hidden doesn't work on :after and :before pseudo elements

Issue

I am making this rounded scroll down button with an arrow inside. On hover I wanted to apply an animation that makes the arrow go from above to below the rounded div, and it should be hidden when outside the div.
I tried using overflow: hidden but for some reason it doesn’t work. Does anyone has a solution for this please?

Codepen: https://codepen.io/RaphaelleD/pen/vYpqxpm

@keyframes tipUp {
  0% {
    transform: translateY(-10px) rotateZ(225deg);
  }
  100% {
    transform: translateY(100px) rotateZ(225deg);
  }
}

@keyframes lineUp {
  0% {
    transform: translateY(-10px);
  }
  100% {
    transform: translateY(100px);
  }
}

.scrolldown {
  position: relative;
  margin: 0 auto;
 }
  
.scrolldown p {
    font-size: 1rem;
    font-weight: 600;
    padding-bottom: 0.8rem;
    text-align: center;
  }
 
 .scrolldown__arrow {
    width: 6rem;
    height: 6rem;
    border: 6px solid black;
    border-radius: 50%;
    margin: 0 auto;
    overflow: hidden;
  }
  
 .scrolldown__arrow:before {
    position: absolute;
    display: inline-block;
    content: "";
    background: black;
    width: 10px;
    height: 45px;
    top: 50%;
    left: 50%;
    margin-top: -50px;
    margin-left: -5px;
    transform: translateY(50px);
  }
 
 .scrolldown__arrow:after {
    position: absolute;
    display: inline-block;
    content: "";
    width: 22px;
    height: 22px;
    color: black;
    border-top: 9px solid;
    border-left: 9px solid;
    transform: rotateZ(45deg);
    top: 50%;
    left: 50%;
    margin-top: -30px;
    margin-left: -15.5px;
    transform: translateY(50px) rotateZ(225deg);
  }
 
.scrolldown__arrow:hover:before {
      animation: lineUp 1s cubic-bezier(0, 0.6, 1, 0.4) infinite 0.5s;
    }

.scrolldown__arrow:hover:after {
      animation: tipUp 1s cubic-bezier(0, 0.6, 1, 0.4) infinite 0.5s;
    }
  }
}
<body>

  <div class="scrolldown">
    <p>SCROLL DOWN</p>
    <div class="scrolldown__arrow"></div> 
  </div>

</body>

Solution

I believe this is because of position: absolute, which takes the arrow out of the normal flow. In order to kinda preserve it in the flow, I’ve added position: relative to the arrow parent, and had to adjust top position as well, seems to work as expected:

@keyframes tipUp {
  0% {
    transform: translateY(-10px) rotateZ(225deg);
  }
  100% {
    transform: translateY(100px) rotateZ(225deg);
  }
}

@keyframes lineUp {
  0% {
    transform: translateY(-10px);
  }
  100% {
    transform: translateY(100px);
  }
}

.scrolldown {
  position: relative;
  margin: 0 auto;
 }
  
.scrolldown p {
    font-size: 1rem;
    font-weight: 600;
    padding-bottom: 0.8rem;
    text-align: center;
  }
 
 .scrolldown__arrow {
    width: 6rem;
    height: 6rem;
    border: 6px solid black;
    border-radius: 50%;
    margin: 0 auto;
    overflow: hidden;
    position: relative;
  }
  
 .scrolldown__arrow:before {
    position: absolute;
    display: inline-block;
    content: "";
    background: black;
    width: 10px;
    height: 45px;
    top: 25%;
    left: 50%;
    margin-top: -50px;
    margin-left: -5px;
    transform: translateY(50px);
  }
 
 .scrolldown__arrow:after {
    position: absolute;
    display: inline-block;
    content: "";
    width: 22px;
    height: 22px;
    color: black;
    border-top: 9px solid;
    border-left: 9px solid;
    transform: rotateZ(45deg);
    top: 25%;
    left: 50%;
    margin-top: -30px;
    margin-left: -15.5px;
    transform: translateY(50px) rotateZ(225deg);
  }
 
.scrolldown__arrow:hover:before {
      animation: lineUp 1s cubic-bezier(0, 0.6, 1, 0.4) infinite 0.5s;
    }

.scrolldown__arrow:hover:after {
      animation: tipUp 1s cubic-bezier(0, 0.6, 1, 0.4) infinite 0.5s;
    }
  }
}
<body>

  <div class="scrolldown">
    <p>SCROLL DOWN</p>
    <div class="scrolldown__arrow"></div> 
  </div>

</body>

Answered By – Maxim Mazurok

Answer Checked By – Senaida (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.