W3docs

How to Create Glitch Effect With CSS

All of us can remember glitch effects from our TV sets! Learn how to create one of the coolest effects for your website and also catch the examples with pure 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!

Create HTML

  • Create <div> with the <span class="attribute">id</span> "example".
  • Add three <h2> tags and input your content on which the glitch effect should be applied.

How to use HTML <h2> tag inside div tag for creating glitch effect

<div id="example">
  <h2>W3DOCS</h2>
  <h2>W3DOCS</h2>
  <h2>W3DOCS</h2>
</div>

Add CSS

  • Style the first <span class="property"> XFI6 </span> tag by specifying its color, font-size, letter-spacing and font-weight. Set the text-align property to "center" and define the animation.
  • Use :nth-child() pseudo-class so as to put style to the next two <span class="property"> XFI7 </span> tags. The <span class="property">:nth-child() </span> pseudo-class selects and styles elements based on their index. For both the second and third child elements, specify the <span class="property">color</span> and <span class="property">animation</span>.
  • 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 how the animation should behave at some point. Here, we use the CSS transform and the opacity properties, where the first property specifies a three-dimensional transformation of the element and the second one sets the level of transparency of an element.

How to create keyframe with transform and opacity properties

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;
    }
  }

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

Example of creating a glitchy effect:

<!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>

Result

<div class="demo px-2.5 mt-1 mb-5 not-prose"> <div id="example">W3DOCS W3DOCS W3DOCS</div> </div> ### Example of creating a glitchy effect with more @keyframes values:

Example of creating a glitchy effect with more @keyframes values:

<!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 of creating a glitchy effect with the :hover selector:

<!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 of creating a glitchy effect using a linear-gradient:

<!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>