How to create a Cyberpunk 2077 glitch effect for an image using CSS

Photo by Hyunwon Jang on Unsplash
Photo by Hyunwon Jang on Unsplash

Going to the Cyberpunk 2077 website in the news section , I came across the "same" effect. It appeared when hovering over the post image. I found it interesting and I decided to see how it works. In this post, I would like to share what I found.





To achieve this effect, we need to display the image 2 times, superimposing them on top of each other. The effect itself will appear in the image that lies on top.





, . .





<div class="container">
  <div class="img"></div>
  <div class="glitch"></div>
</div>
      
      



.





.img,
.glitch {
  display: block;
  background-image: url('https://images.unsplash.com/photo-1551771685-c367c9127a03?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=1000&q=80');
  background-repeat: no-repeat;
  background-size: cover;
  width: 564px;
  height: 376px;
}
      
      



2 . , . .





.glitch {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}
.container {
  position: relative;
}
      
      



. . .





.glitch:hover {
 -webkit-animation-duration:2s;
 animation-duration:2s;
 -webkit-animation-timing-function:linear;
 animation-timing-function:linear;
 -webkit-animation-iteration-count:infinite;
 animation-iteration-count:infinite;
 -webkit-animation-name:glitch-anim;
 animation-name:glitch-anim;
 -webkit-animation-direction:alternate;
 animation-direction:alternate
}
      
      



:





  • animation-duration - , 2 ;





  • animation-timing-function - , ;





  • animation-iteration-count - ;





  • animation-name - , ;





  • animation-direction - the direction of the animation; if the alternate value is set, the animation goes from beginning to end, and then back.





The last detail remains - to describe the animation itself. For this, we will use the rule @keyframes



.





Spoiler
@keyframes glitch-anim {
 0% {
  opacity:1;
  -webkit-transform:translateZ(0);
  transform:translateZ(0);
  -webkit-clip-path:polygon(0 2%,100% 2%,100% 5%,0 5%);
  clip-path:polygon(0 2%,100% 2%,100% 5%,0 5%)
 }
 2% {
  -webkit-clip-path:polygon(0 78%,100% 78%,100% 100%,0 100%);
  clip-path:polygon(0 78%,100% 78%,100% 100%,0 100%);
  -webkit-transform:translate(-5px);
  transform:translate(-5px)
 }
 6% {
  -webkit-clip-path:polygon(0 78%,100% 78%,100% 100%,0 100%);
  clip-path:polygon(0 78%,100% 78%,100% 100%,0 100%);
  -webkit-transform:translate(5px);
  transform:translate(5px)
 }
 8% {
  -webkit-clip-path:polygon(0 78%,100% 78%,100% 100%,0 100%);
  clip-path:polygon(0 78%,100% 78%,100% 100%,0 100%);
  -webkit-transform:translate(-5px);
  transform:translate(-5px)
 }
 9% {
  -webkit-clip-path:polygon(0 78%,100% 78%,100% 100%,0 100%);
  clip-path:polygon(0 78%,100% 78%,100% 100%,0 100%);
  -webkit-transform:translate(0);
  transform:translate(0)
 }
 10% {
  -webkit-clip-path:polygon(0 54%,100% 54%,100% 44%,0 44%);
  clip-path:polygon(0 54%,100% 54%,100% 44%,0 44%);
  -webkit-transform:translate3d(5px,0,0);
  transform:translate3d(5px,0,0)
 }
 13% {
  -webkit-clip-path:polygon(0 54%,100% 54%,100% 44%,0 44%);
  clip-path:polygon(0 54%,100% 54%,100% 44%,0 44%);
  -webkit-transform:translateZ(0);
  transform:translateZ(0)
 }
 13.1% {
  -webkit-clip-path:polygon(0 0,0 0,0 0,0 0);
  clip-path:polygon(0 0,0 0,0 0,0 0);
  -webkit-transform:translate3d(5px,0,0);
  transform:translate3d(5px,0,0)
 }
 15% {
  -webkit-clip-path:polygon(0 60%,100% 60%,100% 40%,0 40%);
  clip-path:polygon(0 60%,100% 60%,100% 40%,0 40%);
  -webkit-transform:translate3d(5px,0,0);
  transform:translate3d(5px,0,0)
 }
 20% {
  -webkit-clip-path:polygon(0 60%,100% 60%,100% 40%,0 40%);
  clip-path:polygon(0 60%,100% 60%,100% 40%,0 40%);
  -webkit-transform:translate3d(-5px,0,0);
  transform:translate3d(-5px,0,0)
 }
 20.1% {
  -webkit-clip-path:polygon(0 0,0 0,0 0,0 0);
  clip-path:polygon(0 0,0 0,0 0,0 0);
  -webkit-transform:translate3d(5px,0,0);
  transform:translate3d(5px,0,0)
 }
 25% {
  -webkit-clip-path:polygon(0 85%,100% 85%,100% 40%,0 40%);
  clip-path:polygon(0 85%,100% 85%,100% 40%,0 40%);
  -webkit-transform:translate3d(5px,0,0);
  transform:translate3d(5px,0,0)
 }
 30% {
  -webkit-clip-path:polygon(0 85%,100% 85%,100% 40%,0 40%);
  clip-path:polygon(0 85%,100% 85%,100% 40%,0 40%);
  -webkit-transform:translate3d(-5px,0,0);
  transform:translate3d(-5px,0,0)
 }
 30.1% {
  -webkit-clip-path:polygon(0 0,0 0,0 0,0 0);
  clip-path:polygon(0 0,0 0,0 0,0 0)
 }
 35% {
  -webkit-clip-path:polygon(0 63%,100% 63%,100% 80%,0 80%);
  clip-path:polygon(0 63%,100% 63%,100% 80%,0 80%);
  -webkit-transform:translate(-5px);
  transform:translate(-5px)
 }
 40% {
  -webkit-clip-path:polygon(0 63%,100% 63%,100% 80%,0 80%);
  clip-path:polygon(0 63%,100% 63%,100% 80%,0 80%);
  -webkit-transform:translate(5px);
  transform:translate(5px)
 }
 45% {
  -webkit-clip-path:polygon(0 63%,100% 63%,100% 80%,0 80%);
  clip-path:polygon(0 63%,100% 63%,100% 80%,0 80%);
  -webkit-transform:translate(-5px);
  transform:translate(-5px)
 }
 50% {
  -webkit-clip-path:polygon(0 63%,100% 63%,100% 80%,0 80%);
  clip-path:polygon(0 63%,100% 63%,100% 80%,0 80%);
  -webkit-transform:translate(0);
  transform:translate(0)
 }
 55% {
  -webkit-clip-path:polygon(0 10%,100% 10%,100% 0,0 0);
  clip-path:polygon(0 10%,100% 10%,100% 0,0 0);
  -webkit-transform:translate3d(5px,0,0);
  transform:translate3d(5px,0,0)
 }
 60% {
  -webkit-clip-path:polygon(0 10%,100% 10%,100% 0,0 0);
  clip-path:polygon(0 10%,100% 10%,100% 0,0 0);
  -webkit-transform:translateZ(0);
  transform:translateZ(0);
  opacity:1
 }
 60.1% {
  -webkit-clip-path:polygon(0 0,0 0,0 0,0 0);
  clip-path:polygon(0 0,0 0,0 0,0 0);
  opacity:1
 }
 to {
  -webkit-clip-path:polygon(0 0,0 0,0 0,0 0);
  clip-path:polygon(0 0,0 0,0 0,0 0);
  opacity:1
 }
}
      
      







Explanations for the code.





The animation is split into parts by percentage. Certain changes take place in each part.





The property clip-path



cuts a polygon from the image and applies various effects to it. For example, transform: translate(-5px)



- shifts the polygon to the left and up.





You can see what happened here .








All Articles