DEV Community

Cover image for Front-End Journal #02 — CSS Glitch Effects
Paula Vaz
Paula Vaz

Posted on

Front-End Journal #02 — CSS Glitch Effects

This time, after a chat with a friend about a website that uses beautiful glitch effects, I decided to try to play with it aiming to explore how to create similar results utilizing only HTML and CSS. It’s a pleasure to share my journey with you.

Fist of all, our HTML couldn’t be more simple, it’s just an h1:

<body>
  <h1>we are not equally present in all parts of ourselves</h1>
</body>
Enter fullscreen mode Exit fullscreen mode

The key point

These days, I discovered how to play with pseudo-elements and this idea is particularly helpful to create our effect.

@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@900&display=swap');
$width: 800px;
$height: 280px;

body {
  background-color: black;
  color: white;
  font-family: 'Noto Sans JP', sans-serif;
  font-size: 30px;
  letter-spacing: 1px;
}

h1 {
  position: absolute;
  top: 50%;
  left: 50%;
  text-align: center;
  transform: translate(-50%, -50%);
  width: $width;
  height: $height;

  &::before,
  &::after {
    content: 'we are not equally present in all parts of ourselves';
    display: block;
    position: absolute;
    top: 0;
  }

  &::before {
    color: rgba(122, 180, 255, 1);
    z-index: -1;
  }

  &::after {
    color: rgba(123, 91, 217, 1);
    z-index: -2;
  }
}
Enter fullscreen mode Exit fullscreen mode

In lines 1 to 20, I just did the base style of our body and our h1 (positioning, font style, background color, etc).

The logic between lines 22 and 39 is our essential point. I created two pseudo-elements: :before and :after. These two elements are two copies of the h1, and the rules display: block, position: absolute and top: 0 guarantees the correct positioning perfectly behind the principal h1. Finally, I modified the text color of each pseudo-element.

Glitch Effect

I produced the glitch effect using the idea of clip.
The clip CSS property defines a visible portion of an element.

Formal syntax:

clip: rect(<top> <right> <bottom> <left>);
Enter fullscreen mode Exit fullscreen mode

The and values are offsets from the inside top border edge of the box, while and are offsets from the inside left border edge of the box — that is, the extent of the padding box.

It’s important to say here that I used clip property because I just needed a simple rect, but if you want to do more complex clips, you can check the newer clip-path property instead.

To obtain the glitch effect, I simply created an animation, which is a for loop (this is why I used SCSS). In each interaction, I randomly selected two values and used them to create the clip. If you want to understand a little bit more about CSS animations, click here.

@keyframes glitch {
  $steps: 40;
  @for $step from 0 through $steps {
    #{percentage($step / $steps)} {
      $top: random($height);
      $bottom: random($height);
      @while $bottom < $top {
        $bottom: random($height);
      }
      clip: rect(#{$top}px $width #{$bottom}px 0);
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Lastly, I attached the animation to the hover state of my pseudo-elements and added de left property so my pseudo-elements are displayed just when they’re on the hover state.

h1 {
  &:hover {
    &::before {
      animation: glitch 3s ease reverse infinite;
      left: 5px;
    }

    &::after {
      animation: glitch 3s ease infinite;
      left: -5px;
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

The result

You can see the complete code here. I hope you enjoyed it! ;)

Top comments (0)