Front-End Journal #02 — CSS Glitch Effects
Tags: html, css, animations, devjournal
Published: 2020-08-09 16:12:24

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**:

```html
<body>
  <h1>we are not equally present in all parts of ourselves</h1>
</body>
```

#The key point

These days, I discovered how to play with [pseudo-elements](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements) and this idea is particularly helpful to create our effect.

```scss
@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;
  }
}
```

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](https://developer.mozilla.org/en-US/docs/Web/CSS/clip).
*The clip CSS property defines a visible portion of an element.*

Formal syntax:
```
clip: rect(<top> <right> <bottom> <left>);
```

The <top> and <bottom> values are offsets from the inside top border edge of the box, while <right> and <left> 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](https://developer.mozilla.org/en-US/docs/Web/CSS/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](https://dev.to/pcosvaz/front-end-journal-01-first-steps-with-css-animations-1bl4).

```scss
@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);
    }
  }
}
```

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.

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

    &::after {
      animation: glitch 3s ease infinite;
      left: -5px;
    }
  }
}
```

#The result

{% codepen https://codepen.io/pcosv/pen/poyJRRr %}

You can see the complete code [here](https://codepen.io/pcosv/pen/poyJRRr). I hope you enjoyed it! ;)