20 CSS Neon Text Effects17 / 20

Pure CSSMIT licensed

Neon Glitch Cyberpunk Text

A datamoshed neon title that tears into offset cyan/magenta channels and clips into horizontal bands — the RGB-split glitch cyberpunk and web3 pages want, built from two pseudo-element clones and clip-path, no JS.

Published

Live Demo
Try it

The code

<div class="cnt-17">
  <h2 class="cnt-17__glitch" data-text="OVERRIDE">OVERRIDE</h2>
</div>
.cnt-17,
.cnt-17 *,
.cnt-17 *::before,
.cnt-17 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.cnt-17 ::selection {
  background: oklch(0.72 0.24 340);
  color: #fff;
}

.cnt-17 {
  --c1: oklch(0.82 0.16 200);
  --c2: oklch(0.72 0.26 340);
  font-family: 'Segoe UI',system-ui,sans-serif;
  width: 100%;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 60px 20px;
  background: repeating-linear-gradient(0deg,#070709 0 3px,#0a0a0d 3px 6px);
}

.cnt-17__glitch {
  position: relative;
  font-size: clamp(44px,11vw,110px);
  font-weight: 900;
  letter-spacing: .04em;
  color: #f4f6ff;
  text-shadow: 0 0 6px #fff,0 0 20px rgba(180,220,255,.5);
}

.cnt-17__glitch::before,
.cnt-17__glitch::after {
  content: attr(data-text);
  position: absolute;
  inset: 0;
  mix-blend-mode: screen;
}

.cnt-17__glitch::before {
  color: var(--c1);
  text-shadow: 0 0 14px var(--c1);
  animation: cnt-17-a 2.6s steps(2,end) infinite;
}

.cnt-17__glitch::after {
  color: var(--c2);
  text-shadow: 0 0 14px var(--c2);
  animation: cnt-17-b 2.1s steps(2,end) infinite reverse;
}

@keyframes cnt-17-a {
  0% {
    transform: translate(0,0);
    clip-path: inset(20% 0 55% 0);
  }

  20% {
    transform: translate(-4px,0);
    clip-path: inset(70% 0 10% 0);
  }

  40% {
    transform: translate(3px,0);
    clip-path: inset(10% 0 80% 0);
  }

  60% {
    transform: translate(-2px,0);
    clip-path: inset(48% 0 30% 0);
  }

  80% {
    transform: translate(4px,0);
    clip-path: inset(85% 0 2% 0);
  }

  100% {
    transform: translate(0,0);
    clip-path: inset(30% 0 45% 0);
  }
}

@keyframes cnt-17-b {
  0% {
    transform: translate(0,0);
    clip-path: inset(62% 0 12% 0);
  }

  25% {
    transform: translate(5px,0);
    clip-path: inset(12% 0 74% 0);
  }

  50% {
    transform: translate(-3px,0);
    clip-path: inset(40% 0 40% 0);
  }

  75% {
    transform: translate(3px,0);
    clip-path: inset(78% 0 6% 0);
  }

  100% {
    transform: translate(0,0);
    clip-path: inset(24% 0 58% 0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .cnt-17__glitch::before,
    .cnt-17__glitch::after {
    animation: none;
    clip-path: none;
    transform: none;
    opacity: .5;
  }
}
/* No JavaScript — two pseudo clones + animated clip-path insets create the RGB glitch. */
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
Here's a working CSS Neon Text Effect from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Neon Glitch Cyberpunk Text
Source: https://codefronts.com/motion/css-neon-text-effect/neon-glitch-cyberpunk-text/

A datamoshed neon title that tears into offset cyan/magenta channels and clips into horizontal bands — the RGB-split glitch cyberpunk and web3 pages want, built from two pseudo-element clones and clip-path, no JS.
## HTML
```html
<div class="cnt-17">
  <h2 class="cnt-17__glitch" data-text="OVERRIDE">OVERRIDE</h2>
</div>
```
## CSS
```css
.cnt-17,
.cnt-17 *,
.cnt-17 *::before,
.cnt-17 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.cnt-17 ::selection {
  background: oklch(0.72 0.24 340);
  color: #fff;
}

.cnt-17 {
  --c1: oklch(0.82 0.16 200);
  --c2: oklch(0.72 0.26 340);
  font-family: 'Segoe UI',system-ui,sans-serif;
  width: 100%;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 60px 20px;
  background: repeating-linear-gradient(0deg,#070709 0 3px,#0a0a0d 3px 6px);
}

.cnt-17__glitch {
  position: relative;
  font-size: clamp(44px,11vw,110px);
  font-weight: 900;
  letter-spacing: .04em;
  color: #f4f6ff;
  text-shadow: 0 0 6px #fff,0 0 20px rgba(180,220,255,.5);
}

.cnt-17__glitch::before,
.cnt-17__glitch::after {
  content: attr(data-text);
  position: absolute;
  inset: 0;
  mix-blend-mode: screen;
}

.cnt-17__glitch::before {
  color: var(--c1);
  text-shadow: 0 0 14px var(--c1);
  animation: cnt-17-a 2.6s steps(2,end) infinite;
}

.cnt-17__glitch::after {
  color: var(--c2);
  text-shadow: 0 0 14px var(--c2);
  animation: cnt-17-b 2.1s steps(2,end) infinite reverse;
}

@keyframes cnt-17-a {
  0% {
    transform: translate(0,0);
    clip-path: inset(20% 0 55% 0);
  }

  20% {
    transform: translate(-4px,0);
    clip-path: inset(70% 0 10% 0);
  }

  40% {
    transform: translate(3px,0);
    clip-path: inset(10% 0 80% 0);
  }

  60% {
    transform: translate(-2px,0);
    clip-path: inset(48% 0 30% 0);
  }

  80% {
    transform: translate(4px,0);
    clip-path: inset(85% 0 2% 0);
  }

  100% {
    transform: translate(0,0);
    clip-path: inset(30% 0 45% 0);
  }
}

@keyframes cnt-17-b {
  0% {
    transform: translate(0,0);
    clip-path: inset(62% 0 12% 0);
  }

  25% {
    transform: translate(5px,0);
    clip-path: inset(12% 0 74% 0);
  }

  50% {
    transform: translate(-3px,0);
    clip-path: inset(40% 0 40% 0);
  }

  75% {
    transform: translate(3px,0);
    clip-path: inset(78% 0 6% 0);
  }

  100% {
    transform: translate(0,0);
    clip-path: inset(24% 0 58% 0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .cnt-17__glitch::before,
    .cnt-17__glitch::after {
    animation: none;
    clip-path: none;
    transform: none;
    opacity: .5;
  }
}
```

## JavaScript
```js
/* No JavaScript — two pseudo clones + animated clip-path insets create the RGB glitch. */
```

How this works

The heading is cloned twice via ::before (cyan) and ::after (magenta) using content: attr(data-text). Each clone is nudged a few pixels on X with transform and animated by a @keyframes that jitters the offset — producing the classic chromatic-aberration RGB split.

The tearing comes from animating clip-path: inset() on each clone so only random horizontal bands show at a time; stepped timing makes the slices snap rather than slide. The base text stays lit underneath so the word never fully disappears.

Make it yours

  • Set the split hues via --c1/--c2; classic is cyan/magenta, but acid-green/red is harsher.
  • Dial glitch violence by widening the transform offsets and shortening the keyframe durations.
  • Reduce band count / raise stability by using fewer clip-path frames for an occasional twitch.
  • Trigger on :hover only (move the animation into the hover rule) for a glitch-on-interact CTA.

Gotchas — read before shipping

  • High-frequency glitch is exactly the kind of motion that triggers discomfort — the reduced-motion block stills it to a clean lit state.
  • Keep a legible base layer under the clones; pure glitch with no steady layer is unreadable.
  • Three stacked text layers with blend modes are paint-heavy — reserve for one hero, not repeated UI.

Browser support

ChromeSafariFirefoxEdge
111+15.4+113+111+

Floor set by oklch() as this demo is written. The core technique itself goes back further — Chrome 88+.

clip-path inset + pseudo clones + mix-blend-mode — broadly supported; color-mix optional.

Techniques used in this demo

Search CodeFronts

Loading…