How to Create Glitch Effect With CSS

Do you remember the earlier television sets right? Then you definitely will remember the glitches effects!

You have also noticed that nowadays glitchy effects are quite trendy. Let’s dive in and create the most catching glitch effect for our website!

1. Create HTML.

  • Create <div> with the id "example". Then add three <h2> tags and input your content on which the glitch effect should be applied. This could be a number or a word. We choose our website name "W3docs".
<div id="example">
  <h2>W3DOCS</h2>
  <h2>W3DOCS</h2>
  <h2>W3DOCS</h2>
</div>

2. Add CSS.

  • Set style to the first <h2> tag. Pick a color, font-size for your content and define the animation. We name the animation "glitch1", set the animation-duration to 0.5s meaning that it takes 0.5 seconds to complete one cycle of animation and the animation-iteration-count to "infinite" so as the animation will be played endlessly. Also, define the space between the letters with the letter-spacing property and use the font-weight property to set the boldness and thickness of the font.
h2 {
  text-align: center;
  color: #d9fff9;
  font-size: 80px;
  letter-spacing: 6px;
  font-weight: 300;
  margin: 0;
  line-height: 0;
  animation: glitch1 0.5s infinite;
}
  • Use :nth-child() pseudo-class so as to put style to the next two <h1> tags. The :nth-child() pseudo-class selects and styles elements based on their index.
  • Set the animation-duration 1.0 second for both the second and the third child.
h2:nth-child(2) {
  color: #0ef0e1;
  animation: glitch2 1.0s infinite;
}
h2:nth-child(3) {
  color: #ff94eb;
  animation: glitch3 1.0s infinite;
}

Now it is time to define the starting and the ending point of animation. The keyframe declaration block includes CSS properties and their values. The keyframe selector can start with a percentage (%) or with the keywords “from” (same as 0%) and “to” (same as 100%). 0% is a starting point of the animation, 100% is the endpoint. The values define at which point the animation should behave. Here we use the transform and the opacity CSS properties where the first one specifies three-dimensional transformation of the element and the second set the level of transparency of an element.

@keyframes glitch1 {
  0% {
    transform: none;
    opacity: 1; 
  }
  50% {
    transform: skew(-2deg, 0.6deg);
    opacity: 0.75;
  }
  100% {
    transform: none;
    opacity: 1;
  }
}
@keyframes glitch2 {
  0% {
    transform: none;
    opacity: 0.25;
  }
  50% {
    transform: translate(-3px, -1px);
    opacity: 0.5;
  }
  100% {
    transform: none;
    opacity: 0.25;
  }
@keyframes glitch3 {
  0% {
    transform: none;
    opacity: 0.25;
  }
  50% {
    transform: translate(3px, 1px);
    opacity: 0.5;
  }
  100% {
    transform: none;
    opacity: 0.25;
  }
}

Now let’s bring all the parts together and see the result!

Example

<!DOCTYPE html>
<html>
  <head>
    <title>The title of the document</title>
    <style>
      body {
      background-color: #eee;
      }
      #example {
      width: 450px;
      margin: 250px auto;
      }
      h2 {
      text-align: center;
      color: #d9fff9;
      font-size: 80px;
      letter-spacing: 6px;
      font-weight: 300;
      margin: 0;
      line-height: 0;
      animation: glitch1 0.5s infinite;
      }
      h2:nth-child(2) {
      color: #0ef0e1;
      animation: glitch2 1.0s infinite;
      }
      h2:nth-child(3) {
      color: #ff94eb;
      animation: glitch3 1.0s infinite;
      }
      @keyframes glitch1 {
      0% {
      transform: none;
      opacity: 1;
      } 
      50% {
      transform: skew(-2deg, 0.6deg);
      opacity: 0.75;
      }
      100% {
      transform: none;
      opacity: 1;
      }
      }
      @keyframes glitch2 {
      0% {
      transform: none;
      opacity: 0.25;
      }
      50% {
      transform: translate(-3px, -1px);
      opacity: 0.5;
      }
      100% {
      transform: none;
      opacity: 0.25;
      }
      }
      @keyframes glitch3 {
      0% {
      transform: none;
      opacity: 0.25;
      }
      50% {
      transform: translate(3px, 1px);
      opacity: 0.5;
      }
      100% {
      transform: none;
      opacity: 0.25;
      }
      }
    </style>
  </head>
  <body>
    <div id="example">
      <h2>W3DOCS</h2>
      <h2>W3DOCS</h2>
      <h2>W3DOCS</h2>
    </div>
  </body>
</html>

Another example with more @keyframes values defined:

Example

<!DOCTYPE html>
<html>
  <head>
    <title>The title of the document</title>
    <style>
      body {
      background-color: #eee;
      }
      #example {
      width: 450px;
      margin: 250px auto;
      }
      h2 {
      text-align: center;
      color: #d9fff9;
      font-size: 80px;
      letter-spacing: 6px;
      font-weight: 300;
      margin: 0;
      line-height: 0;
      animation: glitch1 3.5s infinite;
      }
      h2:nth-child(2) {
      color: #0ef0e1;
      animation: glitch2 2.5s infinite;
      }
      h2:nth-child(3) {
      color: #ff94eb;
      animation: glitch3 2.5s infinite;
      }
      @keyframes glitch1 {
      0% {
      transform: none;
      opacity: 1;
      }
      8% {
      transform: skew(-0.5deg, -0.9deg);
      opacity: 0.75;
      }
      10% {
      transform: none;
      opacity: 1;
      }
      28% {
      transform: none;
      opacity: 1;
      }
      30% {
      transform: skew(0.8deg, -0.1deg);
      opacity: 0.75;
      }
      33% {
      transform: none;
      opacity: 1;
      }
      45% {
      transform: none;
      opacity: 1;
      }
      55% {
      transform: skew(-1deg, 0.2deg);
      opacity: 0.75;
      }
      60% {
      transform: none;
      opacity: 1;
      }
      72% {
      transform: none;
      opacity: 1;
      }
      78% {
      transform: skew(0.4deg, 1deg);
      opacity: 0.75;
      }
      80% {
      transform: none;
      opacity: 1;
      }
      100% {
      transform: none;
      opacity: 1;
      }
      }
      @keyframes glitch2 {
      0% {
      transform: none;
      opacity: 0.25;
      }
      8% {
      transform: translate(-2px, -3px);
      opacity: 0.5;
      }
      10% {
      transform: none;
      opacity: 0.25;
      }
      28% {
      transform: none;
      opacity: 0.25;
      }
      30% {
      transform: translate(-5px, -2px);
      opacity: 0.5;
      }
      33% {
      transform: none;
      opacity: 0.25;
      }
      45% {
      transform: none;
      opacity: 0.25;
      }
      55% {
      transform: translate(-5px, -1px);
      opacity: 0.5;
      }
      60% {
      transform: none;
      opacity: 0.25;
      }
      72% {
      transform: none;
      opacity: 0.25;
      }
      78% {
      transform: translate(-2px, -6px);
      opacity: 0.5;
      }
      80% {
      transform: none;
      opacity: 0.25;
      }
      100% {
      transform: none;
      opacity: 0.25;
      }
      }
      @keyframes glitch3 {
      0% {
      transform: none;
      opacity: 0.25;
      }
      8% {
      transform: translate(2px, 3px);
      opacity: 0.5;
      }
      10% {
      transform: none;
      opacity: 0.25;
      }
      28% {
      transform: none;
      opacity: 0.25;
      }
      30% {
      transform: translate(5px, 2px);
      opacity: 0.5;
      }
      33% {
      transform: none;
      opacity: 0.25;
      }
      45% {
      transform: none;
      opacity: 0.25;
      }
      55% {
      transform: translate(5px, 1px);
      opacity: 0.5;
      }
      60% {
      transform: none;
      opacity: 0.25;
      }
      72% {
      transform: none;
      opacity: 0.25;
      }
      78% {
      transform: translate(2px, 6px);
      opacity: 0.5;
      }
      80% {
      transform: none;
      opacity: 0.25;
      }
      100% {
      transform: none;
      opacity: 0.25;
      }
      }
    </style>
  </head>
  <body>
    <div id="example">
      <h2>W3DOCS</h2>
      <h2>W3DOCS</h2>
      <h2>W3DOCS</h2>
    </div>
  </body>
</html>

Another example with :hover selector:

Example

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      .content {
      display: flex;
      width: 100vw;
      height: 100vh;
      background-color: black;
      background-image: url("https://images.unsplash.com/photo-1489875347897-49f64b51c1f8?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjM4MDE5fQ&auto=format&fit=crop&w=1050&q=80");
      background-repeat: no-repeat;
      background-position: center;
      background-size: cover;
      }
      .text {
      margin: auto;
      font-family: 'Montserrat', sans-serif;
      font-size: 120px;
      text-transform: uppercase;
      }
      .glitch {
      position: relative;
      color: white;
      mix-blend-mode: lighten;
      }
      .glitch:before, .glitch:after {
      content: attr(data-text);
      position: absolute;
      top: 0;
      width: 100%;
      background: black;
      clip: rect(0, 0, 0, 0);
      }
      .glitch:before {
      left: -1px;
      text-shadow: 1px 0 rgba(255, 0, 0, 0.7);
      }
      .glitch:after {
      left: 1px;
      text-shadow: -1px 0 rgba(0, 0, 255, 0.7);
      }
      .glitch:hover:before {
      text-shadow: 4px 0 rgba(255, 0, 0, 0.7);
      animation: glitch-loop-1 0.8s infinite ease-in-out alternate-reverse;
      }
      .glitch:hover:after {
      text-shadow: -5px 0 rgba(0, 0, 255, 0.7);
      animation: glitch-loop-2 0.8s infinite ease-in-out alternate-reverse;
      }
      @keyframes glitch-loop-1 {
      0% {
      clip: rect(36px, 9999px, 9px, 0);
      }
      25% {
      clip: rect(25px, 9999px, 99px, 0);
      }
      50% {
      clip: rect(50px, 9999px, 102px, 0);
      }
      75% {
      clip: rect(30px, 9999px, 92px, 0);
      }
      100% {
      clip: rect(91px, 9999px, 98px, 0);
      }
      }
      @keyframes glitch-loop-2 {
      0% {
      top: -1px;
      left: 1px;
      clip: rect(65px, 9999px, 119px, 0);
      }
      25% {
      top: -6px;
      left: 4px;
      clip: rect(79px, 9999px, 19px, 0);
      }
      50% {
      top: -3px;
      left: 2px;
      clip: rect(68px, 9999px, 11px, 0);
      }
      75% {
      top: 0px;
      left: -4px;
      clip: rect(95px, 9999px, 53px, 0);
      }
      100% {
      top: -1px;
      left: -1px;
      clip: rect(31px, 9999px, 149px, 0);
      }
      }
    </style>
  </head>
  <body>
    <div class="content">
      <h1 class="text glitch is-glitching" data-text="Hover me!">Hover me!</h1>
    </div>
  </body>
</html>

Let’s see another example:

Example

<!DOCTYPE html>
<html>
  <head>
    <title>The title of the document</title>
    <style>
      body, h1 {
      padding: 0;
      margin: 0;
      font-family: 'Montserrat', sans-serif;
      }
      #example {
      height: 100vh;
      width: 100%;
      margin: 0;
      padding: 0;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      background: linear-gradient(rgba(5, 5, 5, 0.6), rgba(0, 0, 0, 0)), repeating-linear-gradient(0, transparent, transparent 2px, black 3px, black 3px), url("https://images.unsplash.com/photo-1528372444006-1bfc81acab02?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=675&q=80");
      background-size: cover;
      background-position: center;
      z-index: 1;
      }
      #wrapper {
      text-align: center;
      }
      .glitch {
      position: relative;
      color: white;
      font-size: 4em;
      letter-spacing: .4em;
      animation: glitch-skew 0.5s infinite linear alternate-reverse;
      }
      .glitch::after {
      content: attr(data-text);
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      left: -2px;
      text-shadow: -2px 0 #00fff9, 2px 2px #ff00c1;
      animation: glitch-anim2 1s infinite linear alternate-reverse;
      }
      @keyframes glitch-anim {
      0% {
      clip: rect(30px, 9999px, 42px, 0);
      transform: skew(0.85deg);
      }
      5% {
      clip: rect(59px, 9999px, 21px, 0);
      transform: skew(0.34deg);
      }
      10% {
      clip: rect(99px, 9999px, 15px, 0);
      transform: skew(0.01deg);
      }
      15% {
      clip: rect(25px, 9999px, 61px, 0);
      transform: skew(0.97deg);
      }
      20% {
      clip: rect(35px, 9999px, 42px, 0);
      transform: skew(0.94deg);
      }
      25% {
      clip: rect(39px, 9999px, 62px, 0);
      transform: skew(0.31deg);
      }
      30% {
      clip: rect(62px, 9999px, 55px, 0);
      transform: skew(0.9deg);
      }
      35% {
      clip: rect(36px, 9999px, 31px, 0);
      transform: skew(0.13deg);
      }
      40% {
      clip: rect(27px, 9999px, 26px, 0);
      transform: skew(0.01deg);
      }
      45% {
      clip: rect(55px, 9999px, 9px, 0);
      transform: skew(0.5deg);
      }
      50% {
      clip: rect(69px, 9999px, 73px, 0);
      transform: skew(0.85deg);
      }
      55% {
      clip: rect(53px, 9999px, 89px, 0);
      transform: skew(0.15deg);
      }
      60% {
      clip: rect(20px, 9999px, 28px, 0);
      transform: skew(0.62deg);
      }
      65% {
      clip: rect(81px, 9999px, 28px, 0);
      transform: skew(0.1deg);
      }
      70% {
      clip: rect(54px, 9999px, 93px, 0);
      transform: skew(0.3deg);
      }
      75% {
      clip: rect(22px, 9999px, 6px, 0);
      transform: skew(0.84deg);
      }
      80% {
      clip: rect(23px, 9999px, 5px, 0);
      transform: skew(0.55deg);
      }
      85% {
      clip: rect(24px, 9999px, 76px, 0);
      transform: skew(0.68deg);
      }
      90% {
      clip: rect(3px, 9999px, 29px, 0);
      transform: skew(0.48deg);
      }
      95% {
      clip: rect(43px, 9999px, 95px, 0);
      transform: skew(0.37deg);
      }
      100% {
      clip: rect(58px, 9999px, 66px, 0);
      transform: skew(0.05deg);
      }
      }
      @keyframes glitch-anim2 {
      0% {
      clip: rect(66px, 9999px, 28px, 0);
      transform: skew(0.12deg);
      }
      5% {
      clip: rect(85px, 9999px, 40px, 0);
      transform: skew(0.7deg);
      }
      10% {
      clip: rect(14px, 9999px, 33px, 0);
      transform: skew(0.81deg);
      }
      15% {
      clip: rect(48px, 9999px, 76px, 0);
      transform: skew(0.57deg);
      }
      20% {
      clip: rect(77px, 9999px, 16px, 0);
      transform: skew(0.4deg);
      }
      25% {
      clip: rect(15px, 9999px, 43px, 0);
      transform: skew(0.27deg);
      }
      30% {
      clip: rect(33px, 9999px, 11px, 0);
      transform: skew(0.84deg);
      }
      35% {
      clip: rect(50px, 9999px, 51px, 0);
      transform: skew(0.16deg);
      }
      40% {
      clip: rect(52px, 9999px, 11px, 0);
      transform: skew(0.21deg);
      }
      45% {
      clip: rect(39px, 9999px, 58px, 0);
      transform: skew(0.98deg);
      }
      50% {
      clip: rect(88px, 9999px, 42px, 0);
      transform: skew(0.42deg);
      }
      55% {
      clip: rect(98px, 9999px, 11px, 0);
      transform: skew(0.51deg);
      }
      60% {
      clip: rect(73px, 9999px, 73px, 0);
      transform: skew(0.81deg);
      }
      65% {
      clip: rect(82px, 9999px, 59px, 0);
      transform: skew(1deg);
      }
      70% {
      clip: rect(64px, 9999px, 84px, 0);
      transform: skew(0.94deg);
      }
      75% {
      clip: rect(41px, 9999px, 44px, 0);
      transform: skew(0.38deg);
      }
      80% {
      clip: rect(23px, 9999px, 35px, 0);
      transform: skew(0.54deg);
      }
      85% {
      clip: rect(20px, 9999px, 100px, 0);
      transform: skew(0.76deg);
      }
      90% {
      clip: rect(9px, 9999px, 96px, 0);
      transform: skew(0.64deg);
      }
      95% {
      clip: rect(29px, 9999px, 82px, 0);
      transform: skew(0.47deg);
      }
      100% {
      clip: rect(15px, 9999px, 94px, 0);
      transform: skew(0.76deg);
      }
      }
      @keyframes glitch-skew {
      0% {
      transform: skew(2deg);
      }
      10% {
      transform: skew(4deg);
      }
      20% {
      transform: skew(4deg);
      }
      30% {
      transform: skew(-2deg);
      }
      40% {
      transform: skew(4deg);
      }
      50% {
      transform: skew(2deg);
      }
      60% {
      transform: skew(-3deg);
      }
      70% {
      transform: skew(-1deg);
      }
      80% {
      transform: skew(-3deg);
      }
      90% {
      transform: skew(-2deg);
      }
      100% {
      transform: skew(-2deg);
      }
      }
    </style>
  </head>
  <body>
    <div id="example">
      <div id="wrapper">
        <h1 class="glitch" data-text="glitch">glitch</h1>
      </div>
    </div>
  </body>
</html>

Do you find this helpful?

Related articles