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>
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; } }
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>);
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); } } }
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; } } }
The result
You can see the complete code here. I hope you enjoyed it! ;)
Top comments (0)