16 CSS Glitch Text Effects12 / 16

Pure CSSMIT licensed

Hacker Terminal Glitch

Realistic macOS terminal window with authentic dot buttons and multiple output lines, where one critical error line fires a three-frame RGB-split displacement burst every 3 seconds -- clinical, developer-focused aesthetic.

Published

Live Demo
Try it

The code

<div class="gt-12">
  <div class="gt-12__window">
    <div class="gt-12__titlebar">
      <div class="gt-12__dot"></div>
      <div class="gt-12__dot"></div>
      <div class="gt-12__dot"></div>
      <span class="gt-12__title-text">zsh — 80×24</span>
    </div>
    <div class="gt-12__body">
      <div class="gt-12__line gt-12__line--prompt">▸ npm run deploy --env=production</div>
      <div class="gt-12__line gt-12__line--output">  ✓ Building optimized bundle...</div>
      <div class="gt-12__line gt-12__line--output">  ✓ Compressing assets (847 files)</div>
      <div class="gt-12__line gt-12__line--warning">  ⚠ Integrity hash mismatch on layer 3</div>
      <div class="gt-12__line gt-12__line--glitch" data-text="  ✗ KERNEL_INJECT :: 0xDEAD_BEEF">  ✗ KERNEL_INJECT :: 0xDEAD_BEEF</div>
      <div class="gt-12__line gt-12__line--error">  ✗ Deploy failed — see logs above</div>
      <div class="gt-12__line gt-12__line--prompt">▸ <span class="gt-12__cursor"></span></div>
    </div>
  </div>
</div>
.gt-12,
.gt-12 *,
.gt-12 *::before,
.gt-12 *::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.gt-12 ::selection {
  background: #22d3ee;
  color: #000;
}

.gt-12 {
  --cyan: #22d3ee;
  --dim-cyan: #164e63;
  --bg: #060d10;
  --term-bg: #040b0d;
  --text: #cffafe;
  --muted: rgba(207,250,254,0.4);
  min-height: 100vh;
  background: var(--bg);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px 20px;
  font-family: 'Fira Code', 'Source Code Pro', 'Courier New', monospace;
}

.gt-12__window {
  width: 100%;
  max-width: 520px;
  border-radius: 10px;
  overflow: hidden;
  box-shadow: 0 20px 60px rgba(0,0,0,0.6), 0 0 0 1px rgba(34,211,238,0.12);
}
/* macOS-style titlebar */

.gt-12__titlebar {
  background: #111c1f;
  padding: 10px 14px;
  display: flex;
  align-items: center;
  gap: 8px;
  border-bottom: 1px solid rgba(34,211,238,0.08);
}

.gt-12__dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
}

.gt-12__dot:nth-child(1) {
  background: #ff5f57;
}

.gt-12__dot:nth-child(2) {
  background: #febc2e;
}

.gt-12__dot:nth-child(3) {
  background: #28c840;
}

.gt-12__title-text {
  flex: 1;
  text-align: center;
  font-size: 11px;
  color: var(--muted);
  letter-spacing: 1px;
}
/* Terminal body */

.gt-12__body {
  background: var(--term-bg);
  padding: 20px 22px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.gt-12__line {
  font-size: 13px;
  color: var(--muted);
  line-height: 1.8;
  letter-spacing: 0.5px;
}

.gt-12__line--prompt {
  color: var(--cyan);
}

.gt-12__line--output {
  color: rgba(207,250,254,0.7);
}

.gt-12__line--warning {
  color: #fbbf24;
}

.gt-12__line--error {
  color: #f87171;
}
/* The glitchy highlight line */

.gt-12__line--glitch {
  position: relative;
  color: var(--text);
  text-shadow: 0 0 6px rgba(34,211,238,0.5);
  animation: gt-12-line-shift 3s steps(1) infinite;
}

.gt-12__line--glitch::before {
  content: attr(data-text);
  position: absolute;
  inset: 0;
  color: #f0f;
  animation: gt-12-ghost-before 3s steps(1) infinite;
}

.gt-12__line--glitch::after {
  content: attr(data-text);
  position: absolute;
  inset: 0;
  color: #0ff;
  animation: gt-12-ghost-after 3s steps(1) infinite;
}

@keyframes gt-12-line-shift {
  0%,
    85%,
    100% {
    transform: translateX(0);
  }

  87% {
    transform: translateX(-4px);
  }

  89% {
    transform: translateX(3px);
  }

  91% {
    transform: translateX(-1px);
  }

  93% {
    transform: translateX(0);
  }
}

@keyframes gt-12-ghost-before {
  0%,
    85%,
    93%,
    100% {
    opacity: 0;
    transform: translateX(0);
  }

  87% {
    opacity: 0.8;
    transform: translateX(-5px);
  }

  89% {
    opacity: 0.5;
    transform: translateX(3px);
  }

  91% {
    opacity: 0.3;
  }
}

@keyframes gt-12-ghost-after {
  0%,
    85%,
    93%,
    100% {
    opacity: 0;
    transform: translateX(0);
  }

  87% {
    opacity: 0.6;
    transform: translateX(5px);
  }

  89% {
    opacity: 0.4;
    transform: translateX(-3px);
  }

  91% {
    opacity: 0.2;
  }
}
/* blinking cursor */

.gt-12__cursor {
  display: inline-block;
  width: 8px;
  height: 13px;
  background: var(--cyan);
  margin-left: 2px;
  vertical-align: middle;
  animation: gt-12-cur 1s steps(1) infinite;
}

@keyframes gt-12-cur {
  0%,
    49% {
    opacity: 1;
  }

  50%,
    100% {
    opacity: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .gt-12__line--glitch,
    .gt-12__cursor {
    animation: none;
  }

  .gt-12__line--glitch::before,
    .gt-12__line--glitch::after {
    display: none;
  }
}
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 Glitch 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: Hacker Terminal Glitch
Source: https://codefronts.com/motion/css-glitch-text-effect/hacker-terminal-glitch/

Realistic macOS terminal window with authentic dot buttons and multiple output lines, where one critical error line fires a three-frame RGB-split displacement burst every 3 seconds -- clinical, developer-focused aesthetic.
## HTML
```html
<div class="gt-12">
  <div class="gt-12__window">
    <div class="gt-12__titlebar">
      <div class="gt-12__dot"></div>
      <div class="gt-12__dot"></div>
      <div class="gt-12__dot"></div>
      <span class="gt-12__title-text">zsh — 80×24</span>
    </div>
    <div class="gt-12__body">
      <div class="gt-12__line gt-12__line--prompt">▸ npm run deploy --env=production</div>
      <div class="gt-12__line gt-12__line--output">  ✓ Building optimized bundle...</div>
      <div class="gt-12__line gt-12__line--output">  ✓ Compressing assets (847 files)</div>
      <div class="gt-12__line gt-12__line--warning">  ⚠ Integrity hash mismatch on layer 3</div>
      <div class="gt-12__line gt-12__line--glitch" data-text="  ✗ KERNEL_INJECT :: 0xDEAD_BEEF">  ✗ KERNEL_INJECT :: 0xDEAD_BEEF</div>
      <div class="gt-12__line gt-12__line--error">  ✗ Deploy failed — see logs above</div>
      <div class="gt-12__line gt-12__line--prompt">▸ <span class="gt-12__cursor"></span></div>
    </div>
  </div>
</div>
```
## CSS
```css
.gt-12,
.gt-12 *,
.gt-12 *::before,
.gt-12 *::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.gt-12 ::selection {
  background: #22d3ee;
  color: #000;
}

.gt-12 {
  --cyan: #22d3ee;
  --dim-cyan: #164e63;
  --bg: #060d10;
  --term-bg: #040b0d;
  --text: #cffafe;
  --muted: rgba(207,250,254,0.4);
  min-height: 100vh;
  background: var(--bg);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px 20px;
  font-family: 'Fira Code', 'Source Code Pro', 'Courier New', monospace;
}

.gt-12__window {
  width: 100%;
  max-width: 520px;
  border-radius: 10px;
  overflow: hidden;
  box-shadow: 0 20px 60px rgba(0,0,0,0.6), 0 0 0 1px rgba(34,211,238,0.12);
}
/* macOS-style titlebar */

.gt-12__titlebar {
  background: #111c1f;
  padding: 10px 14px;
  display: flex;
  align-items: center;
  gap: 8px;
  border-bottom: 1px solid rgba(34,211,238,0.08);
}

.gt-12__dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
}

.gt-12__dot:nth-child(1) {
  background: #ff5f57;
}

.gt-12__dot:nth-child(2) {
  background: #febc2e;
}

.gt-12__dot:nth-child(3) {
  background: #28c840;
}

.gt-12__title-text {
  flex: 1;
  text-align: center;
  font-size: 11px;
  color: var(--muted);
  letter-spacing: 1px;
}
/* Terminal body */

.gt-12__body {
  background: var(--term-bg);
  padding: 20px 22px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.gt-12__line {
  font-size: 13px;
  color: var(--muted);
  line-height: 1.8;
  letter-spacing: 0.5px;
}

.gt-12__line--prompt {
  color: var(--cyan);
}

.gt-12__line--output {
  color: rgba(207,250,254,0.7);
}

.gt-12__line--warning {
  color: #fbbf24;
}

.gt-12__line--error {
  color: #f87171;
}
/* The glitchy highlight line */

.gt-12__line--glitch {
  position: relative;
  color: var(--text);
  text-shadow: 0 0 6px rgba(34,211,238,0.5);
  animation: gt-12-line-shift 3s steps(1) infinite;
}

.gt-12__line--glitch::before {
  content: attr(data-text);
  position: absolute;
  inset: 0;
  color: #f0f;
  animation: gt-12-ghost-before 3s steps(1) infinite;
}

.gt-12__line--glitch::after {
  content: attr(data-text);
  position: absolute;
  inset: 0;
  color: #0ff;
  animation: gt-12-ghost-after 3s steps(1) infinite;
}

@keyframes gt-12-line-shift {
  0%,
    85%,
    100% {
    transform: translateX(0);
  }

  87% {
    transform: translateX(-4px);
  }

  89% {
    transform: translateX(3px);
  }

  91% {
    transform: translateX(-1px);
  }

  93% {
    transform: translateX(0);
  }
}

@keyframes gt-12-ghost-before {
  0%,
    85%,
    93%,
    100% {
    opacity: 0;
    transform: translateX(0);
  }

  87% {
    opacity: 0.8;
    transform: translateX(-5px);
  }

  89% {
    opacity: 0.5;
    transform: translateX(3px);
  }

  91% {
    opacity: 0.3;
  }
}

@keyframes gt-12-ghost-after {
  0%,
    85%,
    93%,
    100% {
    opacity: 0;
    transform: translateX(0);
  }

  87% {
    opacity: 0.6;
    transform: translateX(5px);
  }

  89% {
    opacity: 0.4;
    transform: translateX(-3px);
  }

  91% {
    opacity: 0.2;
  }
}
/* blinking cursor */

.gt-12__cursor {
  display: inline-block;
  width: 8px;
  height: 13px;
  background: var(--cyan);
  margin-left: 2px;
  vertical-align: middle;
  animation: gt-12-cur 1s steps(1) infinite;
}

@keyframes gt-12-cur {
  0%,
    49% {
    opacity: 1;
  }

  50%,
    100% {
    opacity: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .gt-12__line--glitch,
    .gt-12__cursor {
    animation: none;
  }

  .gt-12__line--glitch::before,
    .gt-12__line--glitch::after {
    display: none;
  }
}
```

How this works

The terminal window uses semantic structure: a titlebar with three coloured dot elements and a centred title, followed by a body section containing a vertical stack of log lines. Only the .gt-12__line--glitch element carries an animation, keeping all other lines perfectly static. This precision targeting makes the effect read as a specific data-integrity failure rather than a full-system crash.

The glitch line pseudo-elements duplicate the line text via data-text in magenta and cyan. A steps(1) keyframe active only between 85% and 93% of a 3-second cycle fires three displacement steps for each channel with opposing translateX directions, then returns to opacity: 0. The host element itself gets a matching keyframe that moves the white base text in the same window, so all three layers appear to break apart simultaneously.

Make it yours

  • Add more glitch lines by giving additional .gt-12__line elements the gt-12__line--glitch class with data-text attributes; stagger them with different animation-delay values for cascading failure.
  • Change the terminal accent colour from cyan (#22d3ee) to purple (#a855f7) for a retro Amiga-shell aesthetic.
  • Swap the macOS-style dots for a Windows-style single bar titlebar by replacing the dot elements with a close button.
  • Increase the glitch burst frequency by reducing the animation duration from 3s to 1.5s and adjusting the 85% stop proportionally.
  • Animate the width of output lines from 0 to full over 0.3s each with staggered delays to simulate live terminal output being streamed before the error fires.

Gotchas — read before shipping

  • The data-text attribute and inner text must be identical; if inserting this snippet dynamically via JS, be careful with backticks and template-literal special characters.
  • Chrome font rendering for Fira Code may differ from Safari fallback Courier New; always put the monospace generic last in the font stack to ensure consistent character widths for glitch alignment.
  • If log lines are added dynamically and the container grows, the window may overflow on mobile; add max-height: 300px; overflow-y: auto to the body element for scrollable output.

Browser support

ChromeSafariFirefoxEdge
80+14+78+80+

Pure CSS with no experimental features; Fira Code requires the Google Fonts CDN or system installation.

Techniques used in this demo

Search CodeFronts

Loading…