20 CSS Loaders 07 / 20

CSS Glitch Flicker Loader

Three cyberpunk CSS loaders — a glitching text title with RGB channel split, a CRT scan-line box, and a matrix binary rain column — evoking terminal hacking and retro sci-fi aesthetics.

Pure CSS MIT licensed
Live Demo Open in tab

This is a full-page demo — interact inside the frame above, or open it in the playground for the full-screen experience.

Open in playground

The code

<div class="ld-07">
  <div class="ld-07__stage">
    <div class="ld-07__cell">
      <div class="ld-07__text" data-text="LOADING">LOADING</div>
      <span class="ld-07__label">Glitch Text</span>
    </div>
    <div class="ld-07__cell">
      <div class="ld-07__scan"></div>
      <span class="ld-07__label">Scan Line</span>
    </div>
    <div class="ld-07__cell">
      <div class="ld-07__matrix">
        <div class="ld-07__col"><span>1</span><span>0</span><span>1</span><span>0</span><span>1</span><span>0</span></div>
        <div class="ld-07__col"><span>0</span><span>1</span><span>0</span><span>1</span><span>0</span><span>1</span></div>
        <div class="ld-07__col"><span>1</span><span>1</span><span>0</span><span>0</span><span>1</span><span>0</span></div>
        <div class="ld-07__col"><span>0</span><span>0</span><span>1</span><span>1</span><span>0</span><span>1</span></div>
      </div>
.ld-07,.ld-07 *,.ld-07 *::before,.ld-07 *::after{box-sizing:border-box;margin:0;padding:0}
.ld-07{
  --bg:#080808;--c1:#00ff41;--c2:#ff003c;--c3:#00d4ff;
  background:var(--bg);display:flex;align-items:center;justify-content:center;min-height:100vh;font-family:'Courier New',monospace;
}
.ld-07__stage{display:flex;gap:80px;flex-wrap:wrap;justify-content:center;padding:40px;align-items:center}
.ld-07__cell{display:flex;flex-direction:column;align-items:center;gap:24px}
.ld-07__label{color:rgba(255,255,255,.3);font-size:11px;letter-spacing:2px;text-transform:uppercase}

/* Glitch text */
.ld-07__text{font-size:28px;font-weight:700;color:var(--c1);letter-spacing:4px;position:relative;text-shadow:0 0 10px var(--c1);animation:ld-07-flicker 3s step-end infinite}
.ld-07__text::before{content:attr(data-text);position:absolute;left:0;top:0;color:var(--c2);animation:ld-07-glitch-r 2.5s step-end infinite;clip-path:polygon(0 20%,100% 20%,100% 40%,0 40%)}
.ld-07__text::after{content:attr(data-text);position:absolute;left:0;top:0;color:var(--c3);animation:ld-07-glitch-b 2s step-end infinite;clip-path:polygon(0 60%,100% 60%,100% 80%,0 80%)}
@keyframes ld-07-flicker{0%,100%{opacity:1}92%{opacity:1}93%{opacity:0}94%{opacity:1}96%{opacity:0}97%{opacity:1}}
@keyframes ld-07-glitch-r{0%{transform:translateX(0)}15%{transform:translateX(-3px)}16%{transform:translateX(3px)}17%{transform:translateX(0)}85%{transform:translateX(0)}86%{transform:translateX(2px)}87%{transform:translateX(-2px)}88%{transform:translateX(0)}}
@keyframes ld-07-glitch-b{0%{transform:translateX(0)}10%{transform:translateX(2px)}11%{transform:translateX(-2px)}12%{transform:translateX(0)}75%{transform:translateX(0)}76%{transform:translateX(-3px)}77%{transform:translateX(3px)}78%{transform:translateX(0)}}

/* Scan line loader */
.ld-07__scan{width:80px;height:80px;background:#111;border:1px solid var(--c1);border-radius:4px;position:relative;overflow:hidden;box-shadow:0 0 20px rgba(0,255,65,.2)}
.ld-07__scan::before{content:'';position:absolute;left:0;width:100%;height:2px;background:var(--c1);box-shadow:0 0 8px var(--c1);animation:ld-07-scan 1.5s linear infinite;opacity:.8}
.ld-07__scan::after{content:'';position:absolute;inset:0;background:repeating-linear-gradient(0deg,transparent,transparent 3px,rgba(0,255,65,.03) 3px,rgba(0,255,65,.03) 4px)}
@keyframes ld-07-scan{0%{top:0}100%{top:100%}}

/* Binary rain letters */
.ld-07__matrix{width:80px;height:80px;overflow:hidden;background:#050505;border:1px solid rgba(0,255,65,.2);border-radius:4px;display:flex;gap:1px;padding:2px}
.ld-07__col{display:flex;flex-direction:column;gap:1px;animation:ld-07-matrix-col 1.5s linear infinite}
.ld-07__col:nth-child(2){animation-delay:.3s}
.ld-07__col:nth-child(3){animation-delay:.6s}
.ld-07__col:nth-child(4){animation-delay:.9s}
.ld-07__col span{font-size:9px;color:var(--c1);opacity:.15;display:block;line-height:12px;text-align:center;animation:ld-07-digit 2s step-end infinite}
.ld-07__col span:nth-child(1){animation-delay:0s}
.ld-07__col span:nth-child(2){animation-delay:.2s;opacity:.4}
.ld-07__col span:nth-child(3){animation-delay:.4s;opacity:.7}
.ld-07__col span:nth-child(4){animation-delay:.6s;opacity:1;color:#fff;text-shadow:0 0 4px var(--c1)}
.ld-07__col span:nth-child(5){animation-delay:.8s;opacity:.4}
.ld-07__col span:nth-child(6){animation-delay:1s;opacity:.1}
@keyframes ld-07-matrix-col{0%{transform:translateY(-20px)}100%{transform:translateY(20px)}}
@keyframes ld-07-digit{0%,100%{content:'0'}25%{content:'1'}50%{content:'0'}75%{content:'1'}}

@media(prefers-reduced-motion:reduce){
  .ld-07__text,.ld-07__text::before,.ld-07__text::after,.ld-07__scan::before,.ld-07__col{animation:none}
}

How this works

The glitch text uses two ::before / ::after pseudo-elements that both display the same data-text attribute content but are coloured in red and cyan channel colours. Each pseudo is clipped to a horizontal band via clip-path: polygon(0 20%, 100% 20%, 100% 40%, 0 40%) and offset with translateX(±3px) on irregular step-end keyframes — the asynchronous jitter at 85–88% of the cycle creates a convincing chromatic aberration split. The base text also has an occasional opacity:0 blink via a separate @keyframes ld-07-flicker.

The scan-line box uses a ::before pseudo-element with a 2px-tall background: var(--c1) that animates top: 0 → top: 100% linearly, while a ::after adds a static repeating-linear-gradient scanline texture overlay. The matrix columns are flex containers that translateY downward while inner span digits pulse brightness through a stepped keyframe.

Customize

  • Adjust glitch intensity by changing the translateX offset from ±3px to ±8px for extreme distortion or ±1px for a subtle chromatic aberration.
  • Change the clip bands on pseudo-elements to create a different split pattern — try polygon(0 0%, 100% 0%, 100% 15%, 0 15%) for a top-slice glitch.
  • Speed up the scan line by reducing its animation-duration from 1.5s to 0.8s — slower is more ominous; faster feels like active processing.
  • Swap the green terminal colour to amber (#ff9f00) for a classic 80s CRT look, or white (#e0e0e0) for a modern IDE aesthetic.
  • Increase matrix column count by adding more .ld-07__col divs — the container width auto-grows; ensure the outer wrapper has sufficient overflow control.

Watch out for

  • The glitch pseudo-element content: attr(data-text) requires the HTML attribute to be set — if the attribute is missing, pseudo-elements render empty and the effect disappears.
  • clip-path: polygon() on pseudo-elements is not inherited and must be set directly on ::before / ::after — placing it on the parent element has no effect.
  • The scan-line top: 0 → top: 100% animation only works if the parent has position:relative; overflow:hidden — missing either causes the line to escape the box.

Browser support

ChromeSafariFirefoxEdge
55+ 13.1+ 72+ 55+

clip-path polygon support requires Safari 13.1+; older Safari ignores the clip and shows full pseudo-element bands.

Search CodeFronts

Loading…