How to create glitch text and image effects in CSS
Create a distressed glitch text effect using CSS keyframes.
In this tutorial, we'll show you how to create a glitch text effect. Special effects and animations can help websites stand out, creating an immediate impact on the user before they've had a chance to get into reading the main content. If your homepage needs to wow visitors, you can create tons of different effects using just CSS.
Our process for creating glitch text here is actually pretty similar to working with animation software. We'll place keyframes at specific points, and use these to control the action. The difference with the keyframes in CSS is that they are written as percentages for the timeline of animation in the code. This isn't anywhere near as daunting as it sounds – once you try it, it's relatively straightforward to achieve good results. Want good results without coding? Try a website builder. And keep your site running smoothly with the right web hosting service.
There will be a small amount of JavaScript used in the tutorial – to remove the loading screen once the images load onto the page – but the main focus here is on CSS animation. We'll also use CSS Grid to position elements on the screen.
- Download the tutorial files from FileSilo (free, login required)
01. Get set up
To get started, open the start folder from the project files inside your code editor. Open the index.html page, which contains just a barebones skeleton HTML page. In the head section, the fonts need linking up so that the design displays correctly. Add the style link for the fonts.
<link href="https://fonts.googleapis.com/css?family=IM+Fell+English|Playfair+Display:900"rel="stylesheet">
02. Link the CSS
The basic layout in CSS has been started in the site.css file, but all of the important parts relating to the glitch effect are going to be added later. In the head section of the document link up the CSS so that the basic design of the page is in place.
<link rel="stylesheet" type="text/css"
href="css/site.css" />
03. Set up a loading screen
Now move to the body section of the page. This contains all the visible elements of the page that show up in the browser. Here add in a div that will hold the 'preloader screen' until everything on the page has loaded. This will display a logo in the centre of the page.
<div id="loader" class="loading">
<div class="loading-logo"><img src="img/logo.svg" class="logo"></div>
</div>
04. Add a header bar
Along the top of the screen will be a small header containing an SVG logo for the site on the left with a text heading. Then on the right-hand side of the screen, an inline menu will be in place for easy navigation. The structure of the code here adds those elements onto the page.
Get the Creative Bloq Newsletter
Daily design news, reviews, how-tos and more, as picked by the editors.
<div class="contentFixed">
<header class="header">
<h1 class="headerTitle"><img
src="img/logo.svg" class="logo"> HackerCon</h1>
</header>
<nav class="menu" id="siteNav">
<ul>
<li><a href="index.html">Home</a></li>
<li><a href="news.html">News</a></li>
<li><a href="contact.html">Contact</a></li>
<li><a href="about.html">About</a></li>
</ul>
</nav>
</div>
05. Add images
Now the section that follows contains several versions of the same image in the glitchit class. What this will do is have different parts of these images turned on and off at different times in order to give a glitch effect. Following this is the text that will sit over the top of the images.
<div class="content">
<div class="glitch">
<div class="glitchit"></div>
<div class="glitchit"></div>
<div class="glitchit"></div>
<div class="glitchit"></div>
<div class="glitchit"></div>
</div>
<div class="contentSection">
<h2 class="contentTitle">Hacker<span>Con</span></h2>
<p class="contentText">Add a description</p>
</div>
</div>
06. Trigger the glitch text effect
At the end of the body content the JavaScript tags are placed. All this does is check that the page has loaded and then removes the loading screen, which in turn triggers the glitch effect animation to start by adding a class to the body to affect the relevant glitch sections.
<script>
var loader = document.getElementById('loader');
window.addEventListener("load",
function(event) {
loader.classList.
remove('loading');
loader.classList.add('loaded');
document.body.classList.
add('imgloaded');
});
</script>
07. Set up CSS Variables
Save the page now and move over to the site.css file in the CSS folder. There is already code here, but right above any other code add in the variables shown below. These CSS Variables will hold colours and sizes that will be used later on in the design.
body {
--color-text: #fff;
--color-bg: #000;
--color-link: #555;
--color-link-hover: #98fadf;
--color-info: #f7cfb9;
--glitch-width: 100vw;
--glitch-height: 100vh;
--gap-horizontal: 10px;
--gap-vertical: 5px;
--time-anim: 4s;
--delay-anim: 2s;
08. Experiment with Variable settings
As you will see, these Variables are assigned to the body tag so they can be used by any tag on the page inside the body, which is essentially all the visible page. Here the transparency and blending modes are set up for the different images. There are five images and you can experiment with these settings to get different results.
--blend-mode-1: none;
--blend-mode-2: overlay;
--blend-mode-3: none;
--blend-mode-4: none;
--blend-mode-5: overlay;
--blend-color-1: transparent;
--blend-color-2: #7d948e;
--blend-color-3: transparent;
--blend-color-4: transparent;
--blend-color-5: #af4949;
}
09. Fill the screen with images
To keep the code neatly together, scroll down to the comment that mark steps 9 to 13 in the CSS file, adding in this code. Here the glitch code positions the div containing all images to fill the full screen and be positioned absolutely in the top left of the screen. Note it gets its width and height from the CSS Variables.
.glitch
{
position: absolute;
top: 0;
left: 0;
width: var(--glitch-width);
height: var(--glitch-height);
overflow: hidden;
}
10. Adjust image positioning
As the glitch effect is made up out of copies of the same image, this code positions each div in the page and makes it slightly larger than the screen. It positions it off the top and left to account for it being bigger, and the image is then placed in the background to fill the image.
.glitchit {
position: absolute;
top: calc(-1 * var(--gap-vertical));
left: calc(-1 * var(--gap-horizontal));
width: calc(100% + var(--gap-horizontal) *
2);
height: calc(100% + var(--gap-vertical) *
2);
background: url(../img/main.jpg) no-repeat
50% 0;
background-color: var(--blend-color-1);
background-size: cover;
transform: translate3d(0, 0, 0);
background-blend-mode: var(--blend-
mode-1);
}
11. Select images
The code here selects every image except the first image. This is because the first image stays on the page, while the others turn on and off over the top with the keyframe animation. These top images are hidden until they are needed with the opacity set to zero.
.glitchit:nth-child(n+2) {
opacity: 0;
}
.imgloaded .glitchit:nth-child(n+2) {
animation-duration: var(--time-anim);
animation-delay: var(--delay-anim);
animation-timing-function: linear;
animation-iteration-count: infinite;
}
12. Adjust images two and three
The second and third image are set to animate in this code. They are given the respective blend and colour modes so that they show up differently. The biggest difference here is that they are given different keyframe animations to follow to mix.
up the effects.
.imgloaded .glitchit:nth-child(2) {
background-color: var(--blend-color-2);
background-blend-mode: var(--blend-
mode-2);
animation-name: glitch-1;
}
.imgloaded .glitchit:nth-child(3) {
background-color: var(--blend-color-3);
background-blend-mode: var(--blend-
mode-3);
animation-name: glitch-2;
}
13. Adjust images four and five
This time the next two images are set up quite close to the others, but again this time there is different blending modes and animations for these images to show up. The keyframes have not yet been created for some of these animations and that will come next.
.imgloaded .glitchit:nth-child(4) {
background-color: var(--blend-color-4);
background-blend-mode: var(--blend-
mode-4);
animation-name: glitch-3;
}
.imgloaded .glitchit:nth-child(5) {
background-color: var(--blend-color-5);
background-blend-mode: var(--blend-
mode-5);
animation-name: glitch-flash;
}
14. Add the first set of keyframes
The keyframes work by grabbing different sections of the image and clipping it down so only that will be visible. The opacity is turned on and off at different times so that parts of the image are visible at different times to the other animations and thus creates the glitch effect. The image is moved slightly on the x-axis.
@keyframes glitch-1 {
0% {
opacity: 1;
transform: translate3d(var(--gap-
horizontal), 0, 0);
clip-path: polygon(0 2%, 100% 2%,
100% 5%, 0 5%);
} 2% {
clip-path: polygon(0 15%, 100% 15%,
100% 15%, 0 15%);
}
15. Use the clip-path
The clip path is taking a rectangle so the first two numbers are top left, then top right. This is followed by bottom right and bottom left. By moving these numbers different parts of the image become visible at different points.
4% {
clip-path: polygon(0 10%, 100% 10%,
100% 20%, 0 20%);
} 6% {
clip-path: polygon(0 1%, 100% 1%,
100% 2%, 0 2%);
} 8% {
clip-path: polygon(0 33%, 100% 33%, 1
00% 33%, 0 33%);
} 10% {
clip-path: polygon(0 44%, 100% 44%,
100% 44%, 0 44%);
}
16. Speed up the movement
By moving the clip path so quickly over a number of the keyframes, the effect builds up and different parts of the image appear to flash around in an erratic fashion. Add that more layers of images are also doing this and the effect works very well at what it does.
12% {
clip-path: polygon(0 50%, 100% 50%,
100% 20%, 0 20%);
} 14% {
clip-path: polygon(0 70%, 100% 70%,
100% 70%, 0 70%);
}16% {
clip-path: polygon(0 80%, 100% 80%,
100% 80%, 0 80%);
}18% {
clip-path: polygon(0 50%, 100% 50%,
100% 55%, 0 55%);
}20% {
clip-path: polygon(0 70%, 100% 70%,
100% 80%, 0 80%);
}
17. Finish up the image glitches
After 22% the image is turned off until the animation plays back again. This completes the glitch-1 effect with glitch-2 and glitch-3 already being supplied in the code. The next section will glitch the text that is over the top of the image as well.
21.9% {
opacity: 1;
transform: translate3d(var(--gap-
horizontal), 0, 0);
} 22%, 100% {
opacity: 0;
transform: translate3d(0, 0, 0);
clip-path: polygon(0 0, 0 0, 0 0, 0
0);
}
}
18. How to create glitch text
This code works extremely similarly to the previous code except that it flips the text upside down and then clips it, to give a jumping effect that is moved dramatically. Following that the clip path is revealing only smaller sections, with the fast movement through the keyframes.
@keyframes glitch-text {
0% {
transform: translate3d(calc(-1 *
var(--gap-horizontal)), 0, 0) scale3d(-1, -1,
1);
clip-path: polygon(0 20%, 100% 20%,
100% 21%, 0 21%);
} 2% {
clip-path: polygon(0 33%, 100% 33%,
100% 33%, 0 33%);
} 4% {
clip-path: polygon(0 44%, 100% 44%,
100% 44%, 0 44%);
}
19. More clipping
The effect continues in this section of code by rapidly changing the shape of the clipping path. The clip-path also comes with the -webkit- prefix but for brevity this has not been shown in any of the code here. At time of writing, Clip Path is currently not supported in IE, Edge or Opera Mini, but is in all other browsers.
5% {
clip-path: polygon(0 50%, 100% 50%,
100% 20%, 0 20%);
} 6% {
clip-path: polygon(0 70%, 100% 70%,
100% 70%, 0 70%);
} 7% {
clip-path: polygon(0 80%, 100% 80%,
100% 80%, 0 80%);
} 8% {
clip-path: polygon(0 50%, 100% 50%,
100% 55%, 0 55%);
}
20. Flip the text back
In the final text glitch animation the text flips back to its original position and waits for the keyframes to come around again. As you can see all of the animation takes place in 10 per cent while it stays dormant for 90 per cent of the time, giving the text the right amount of distress and allowing it to be readable.
9% {
clip-path: polygon(0 70%, 100% 70%,
100% 80%, 0 80%);
} 9.9% {
transform: translate3d(calc(-1 *
var(--gap-horizontal)), 0, 0) scale3d(-1, -1,
1);
} 10%, 100% {
transform: translate3d(0, 0, 0)
scale3d(1, 1, 1);
clip-path: polygon(0 0, 100% 0, 100%
100%, 0% 100%);
}
}
21. Create a quick flash
The final step is that one image is given the glitch-flash animation, and this series of keyframes just place the image on the screen with a 20 per cent opacity for a short period just to give an offset of the original. Save the CSS file now and the effect should start playing once the content loads in the browser.
@keyframes glitch-flash {
0%, 5% {
opacity: 0.2;
transform: translate3d(var(--gap-
horizontal), var(--gap-vertical), 0);
} 5.5%, 100% {
opacity: 0;
transform: translate3d(0, 0, 0);
} }
Got somewhere secure to save your design files? If not you'll need our guide to cloud storage options.
This article was originally published in creative web design magazine Web Designer. Buy issue 281 or subscribe.
Read more:
Thank you for reading 5 articles this month* Join now for unlimited access
Enjoy your first month for just £1 / $1 / €1
*Read 5 free articles per month without a subscription
Join now for unlimited access
Try first month for just £1 / $1 / €1
Mark is a Professor of Interaction Design at Sheridan College of Advanced Learning near Toronto, Canada. Highlights from Mark's extensive industry practice include a top four (worldwide) downloaded game for the UK launch of the iPhone in December 2007. Mark created the title sequence for the BBC’s coverage of the African Cup of Nations. He has also exhibited an interactive art installation 'Tracier' at the Kube Gallery and has created numerous websites, apps, games and motion graphics work.
Related articles
- XPPen Artist Pro 24 (Gen 2) review: bigger and better than the rest
- Why Dragon Quest III HD-2D Remake's 'zombie tech' is the future of retro-gaming
- Why Sword of the Sea's animation looks so silky smooth
- Alien: Rogue Incursion's terrifying Xenomorphs are a “happy accident” reveals the game's art director