Introduction
Today I would like to talk about how to make a Glitch effect using CSS. To do this, I will use one of the most popular options. This is when we use pseudo-elements to create copies of the main element.
Demo
HTML
In the HTML section, we need to create just 1 tag, inside which you should write the text, and also duplicate it in the data-text attribute.
Like that:
<h1 class="glitch" data-text="Glitch">Glitch</h1>
You can specify any tag. It is not necessary to use text tags.
CSS
We need to take into account that the pseudo-elements of our text should be located approximately at the same position as the main text.
Therefore, for pseudo-elements, we need to specify the position property with the value absolute.
.glitch {
position: relative;
&::before,
&::after {
content: attr(data-text);
position: absolute;
top: 0;
left: 0;
}
}
Now our text and its copies are on top of each other.
Before we continue creating the Glitch effect, it would be nice to add styles to our text to make it look more beautiful.
To do this, I will make our sans-serif font, the font size is larger, we create shadows and a linear gradient that completely copies our text.
.glitch {
position: relative;
font-family: sans-serif;
font-size: 7em;
text-transform: uppercase;
text-shadow: 6px -6px 0px #fd5f00;
background: repeating-linear-gradient(45deg, #005792, #005792 1px, #fff 2px, #fff 3px);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
Changing pseudo-elements
Now we need to shift each of our pseudo-elements in different directions. This is necessary in order to create the effect of shifting the text, as it happens during glitches.
To do this, we need to move each pseudo-element in the opposite direction from each other by a couple of pixels.
&::before {
left: 7px;
text-shadow: 1px 0 #fd5f00;
}
&::after {
left: 3px;
text-shadow: -1px 0 #fd5f00;
}
I decided to make the color of the pseudo-elements shadows the same as the main one, but you can make them different, in order to achieve the effect of a broken TV using black and blue colors.
Clip
Next, we need to use the clip property.
The clip property defines the area of the positioned element in which its contents will be displayed. Anything that doesn't fit in this area will be cut off and become invisible.
We use this property to alternately display the cropped parts of our pseudo elements.
Syntax:
clip: rect(Y1, X1, Y2, X2);
The values are the distance from the edge of the element to the clipping area.
clip: rect(
top/right/bottom/left);
Therefore, in order to completely crop our pseudo-elements, we set an indent of 900 pixels on the right side. (You can use any value depending on the size of your element)
&::before,
&::after {
content: attr(data-text);
position: absolute;
top: 0;
left: 0;
right: 0;
background: $secondaryColor;
color: $primaryColor;
clip: rect(0, 900px, 0, 0);
overflow: hidden;
}
It is very important that the background property of pseudo-elements is exactly the same as that of the background, so that they merge and there are no problems with the display.
Clip Animation
In order to qualitatively animate our elements, we need to create a step-by-step animation, where we will change the first and third values in the clip property, so that our pseudo-elements are displayed only in parts during the animation from top to bottom.
In this case, the second and fourth values of the clip property must be unchanged.
$steps: 20;
@keyframes glitch-effect{
@for $i from 0 through $steps{
#{percentage($i*(1/$steps))}{
clip: rect(random(100) + px, 9999px, random(100) + px, 0);
}
}
}
Personally, I use a 20-step animation, but you can specify any number of steps, since the animation is still random and generates changes in the values of the clip property itself. The more steps you specify, the faster the animation will be.
And now we just need to attach our animation to our two pseudo-elements. You also need to specify a different animation playback time for each pseudo-element. To achieve a more chaotic glitch animation effect.
&::before {
left: 7px;
text-shadow: 1px 0 #fd5f00;
animation: glitch-effect 3s infinite linear alternate-reverse;
}
&::after {
left: 3px;
text-shadow: -1px 0 #fd5f00;
animation: glitch-effect 2s infinite linear alternate-reverse;
}
It's all.
The End
Well, that's it. This was a very simple and very popular way to create a glitch effect on pure CSS. Thank you very much for your time on my post.





Top comments (13)
clip is deprecated, you should consider clip-path instead or mask.
Here is my idea using mask: dev.to/afif/still-100-css-loaders-... (loader #5 in the Classic IV)
Thank you for advice. I know that the clip property is already outdated, I just didn't want to recycle the working vanilla version. π
yes, but it may stop working at any time π
Here you are definitely right, I should then redo it to clip-path. Thanks
How to*
But good article
Wow this is so cool thank you for sharing!!!
Very cool man, cheers
Thanks π
Wow!
This is excellent! Now I know how to give my old geocities site the look and feel it deserves. With lagging scrolling and everything
Do you have instructions for doing this with a picture instead of text?
Unfortunately, not yet, I planned to make them in the future.
This is really helpful while developing AppLinked App. Get it from applinked.me/