w3docs logo
  1. Snippets
  2. CSS
  3. How to Create Glitch Effect With CSS

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!

Create HTML

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

Add CSS

  • Style the first <h2> 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 <h2> tags. The :nth-child() pseudo-class selects and styles elements based on their index. For both the second and third child elements, specify the color and animation.
  • 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.
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

W3DOCS W3DOCS W3DOCS

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>
Do you find this helpful?