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)