Artificial truth

archives | latest | homepage | atom/rss/twitter

The more you see, the less you believe.

Glitch effect on text in pure css
Wed 01 December 2021 — download

My blog used to have a glitching title, initially done in svg, then in pure css when I realised that the Tor Browser didn't display the former in every level of security settings.

The svg version is pretty straightforward-ish, done via svg animations:

Svg glitch

The pure css version is a bit more interesting. The html is simply <h1 data-text='Artifical Truth' class='glitch'>Artificial Truth</h1>, while the css is a bit more involved: It's using the data-text attribute, to get the text from which to display a shadow of, two times: once in red a bit to the left, the other in green a bit to the right. To have the glitchy effect, the shadows are then clipped using a rectangle whose size is changed via css animations. Since there is no non-ugly way to generate random numbers in pure css, the animations are unfortunately hard-coded:

.glitch:after, .glitch:before {
  position: absolute;
  background: white;
  width: 40%;
  content: attr(data-text);
  clip: rect(0, 900px, 0, 0);
}
.glitch:after {
  animation: glitch-anim 2s infinite linear alternate-reverse;
  left: 1px;
  text-shadow: 1px 0 red;
}
.glitch:before {
  animation: glitch-anim-2 3s infinite linear alternate-reverse;
  left: -1px;
  text-shadow: -1px 0 limegreen;
}
@keyframes glitch-anim {
  0% { clip: rect(3px, 9999px, 93px, 0); }
  5% { clip: rect(53px, 9999px, 78px, 0); }
  10% { clip: rect(10px, 9999px, 75px, 0); }
  15% { clip: rect(32px, 9999px, 40px, 0); }
  20% { clip: rect(65px, 9999px, 62px, 0); }
  25% { clip: rect(31px, 9999px, 14px, 0); }
  30% { clip: rect(94px, 9999px, 87px, 0); }
  35% { clip: rect(81px, 9999px, 41px, 0); }
  40% { clip: rect(45px, 9999px, 50px, 0); }
  45% { clip: rect(82px, 9999px, 41px, 0); }
  50% { clip: rect(71px, 9999px, 3px, 0); }
  55% { clip: rect(75px, 9999px, 60px, 0); }
  60% { clip: rect(20px, 9999px, 49px, 0); }
  65% { clip: rect(67px, 9999px, 92px, 0); }
  70% { clip: rect(47px, 9999px, 55px, 0); }
  75% { clip: rect(63px, 9999px, 90px, 0); }
  80% { clip: rect(70px, 9999px, 92px, 0); }
  85% { clip: rect(41px, 9999px, 60px, 0); }
  90% { clip: rect(56px, 9999px, 79px, 0); }
  95% { clip: rect(21px, 9999px, 68px, 0); }
  100% { clip: rect(15px, 9999px, 72px, 0); }
}

@keyframes glitch-anim-2 {
  0% { clip: rect(65px, 9999px, 99px, 0); }
  5% { clip: rect(86px, 9999px, 70px, 0); }
  10% { clip: rect(79px, 9999px, 60px, 0); }
  15% { clip: rect(15px, 9999px, 88px, 0); }
  20% { clip: rect(24px, 9999px, 5px, 0); }
  25% { clip: rect(35px, 9999px, 3px, 0); }
  30% { clip: rect(56px, 9999px, 11px, 0); }
  35% { clip: rect(2px, 9999px, 38px, 0); }
  40% { clip: rect(60px, 9999px, 50px, 0); }
  45% { clip: rect(27px, 9999px, 4px, 0); }
  50% { clip: rect(79px, 9999px, 12px, 0); }
  55% { clip: rect(23px, 9999px, 8px, 0); }
  60% { clip: rect(65px, 9999px, 55px, 0); }
  65% { clip: rect(19px, 9999px, 7px, 0); }
  70% { clip: rect(43px, 9999px, 17px, 0); }
  75% { clip: rect(65px, 9999px, 91px, 0); }
  80% { clip: rect(45px, 9999px, 66px, 0); }
  85% { clip: rect(3px, 9999px, 2px, 0); }
  90% { clip: rect(58px, 9999px, 81px, 0); }
  95% { clip: rect(29px, 9999px, 20px, 0); }
  100% { clip: rect(82px, 9999px, 28px, 0); }
}

and it looks like this:

Artificial Truth

I think I initially borrowed the code from CSS Tricks.