31 CSS Hero Sections29 / 31

Pure CSSMIT licensed

Glitch Text Hero

VHS-glitch hero — RGB-channel offsets create a tape-static glitch effect. VHS red and tape blue against a static-gray background, the analogue cyberpunk treatment.

Published

Live Demo
Try it

The code

<section class="hs-29" aria-label="Hero">
  <span class="hs-29__static" aria-hidden="true"></span>
  <span class="hs-29__scan" aria-hidden="true"></span>
  <div class="hs-29__inner">
    <span class="hs-29__eye">REC ● 00:42:18</span>
    <h2 data-text="LOST &amp; FOUND" class="hs-29__h">LOST &amp; FOUND</h2>
    <p>
      A search engine for VHS-era ephemera. Public-access TV, mall demos, regional news. The
      forgotten internet of the 80s.
    </p>
    <a class="hs-29__cta" href="#search">Search the tapes →</a>
  </div>
</section>
.hs-29 {
  position: relative;
  overflow: hidden;
  display: grid;
  place-items: center;
  width: 100%;
  min-height: 100vh;
  padding: clamp(28px, 5vw, 64px) clamp(20px, 5vw, 56px);
  background: #1a1818;
  font-family: 'JetBrains Mono', monospace;
  color: #d8d4c8;
  box-sizing: border-box;
  contain: layout paint;
}

.hs-29__static {
  position: absolute;
  inset: 0;
  background-image: radial-gradient(rgba(255,255,255,0.04) 1px, transparent 1px), radial-gradient(rgba(255,255,255,0.03) 1px, transparent 1px);
  background-size: 3px 3px, 5px 5px;
  background-position: 0 0, 1px 1px;
  pointer-events: none;
  animation: hs-29-jit 0.2s steps(2) infinite;
}

.hs-29__scan {
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(180deg, transparent 0 2px, rgba(0,0,0,0.18) 2px 3px);
  pointer-events: none;
}

@keyframes hs-29-jit {
  0% {
    transform: translate(0,0);
  }

  50% {
    transform: translate(-1px,1px);
  }

  100% {
    transform: translate(1px,-1px);
  }
}

.hs-29__inner {
  position: relative;
  z-index: 1;
  max-width: 640px;
  text-align: center;
}

.hs-29__eye {
  display: inline-block;
  padding: 4px 10px;
  background: #d63838;
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.18em;
  margin-bottom: 22px;
  animation: hs-29-blink 1.4s steps(2) infinite;
}

@keyframes hs-29-blink {
  to {
    opacity: 0.5;
  }
}

.hs-29__h {
  position: relative;
  margin: 0 0 18px;
  font-family: 'Inter', sans-serif;
  font-size: clamp(48px, 9vw, 100px);
  font-weight: 900;
  letter-spacing: -0.04em;
  line-height: 0.92;
  color: #f0eee0;
}

.hs-29__h::before,
.hs-29__h::after {
  content: attr(data-text);
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  pointer-events: none;
  text-align: center;
}

.hs-29__h::before {
  color: #d63838;
  transform: translate(-3px,0);
  clip-path: polygon(0 12%, 100% 12%, 100% 38%, 0 38%);
  animation: hs-29-rgb 2.4s ease-in-out infinite;
}

.hs-29__h::after {
  color: #38b8d6;
  transform: translate(3px,0);
  clip-path: polygon(0 56%, 100% 56%, 100% 88%, 0 88%);
  animation: hs-29-rgb 2.4s ease-in-out infinite reverse;
}

@keyframes hs-29-rgb {
  0%,
    100% {
    transform: translate(-3px,0);
  }

  50% {
    transform: translate(3px,2px);
  }
}

.hs-29 p {
  margin: 0 auto 24px;
  font-size: 14px;
  line-height: 1.6;
  color: #98948c;
  max-width: 460px;
}

.hs-29__cta {
  display: inline-block;
  padding: 12px 22px;
  background: #38b8d6;
  color: #1a1818;
  border-radius: 0;
  text-decoration: none;
  font-weight: 800;
  font-size: 13px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  transition: background 0.15s, color 0.15s;
}

.hs-29__cta:hover {
  background: #d63838;
  color: #fff;
}

@media (prefers-reduced-motion: reduce) {
  .hs-29__static,
    .hs-29__eye,
    .hs-29__h::before,
    .hs-29__h::after {
    animation: none;
  }

  .hs-29__cta {
    transition: 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 Hero Section 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: Glitch Text Hero
Source: https://codefronts.com/layouts/css-hero-sections/glitch-text-hero/

VHS-glitch hero — RGB-channel offsets create a tape-static glitch effect. VHS red and tape blue against a static-gray background, the analogue cyberpunk treatment.
## HTML
```html
<section class="hs-29" aria-label="Hero">
  <span class="hs-29__static" aria-hidden="true"></span>
  <span class="hs-29__scan" aria-hidden="true"></span>
  <div class="hs-29__inner">
    <span class="hs-29__eye">REC ● 00:42:18</span>
    <h2 data-text="LOST &amp; FOUND" class="hs-29__h">LOST &amp; FOUND</h2>
    <p>
      A search engine for VHS-era ephemera. Public-access TV, mall demos, regional news. The
      forgotten internet of the 80s.
    </p>
    <a class="hs-29__cta" href="#search">Search the tapes →</a>
  </div>
</section>
```
## CSS
```css
.hs-29 {
  position: relative;
  overflow: hidden;
  display: grid;
  place-items: center;
  width: 100%;
  min-height: 100vh;
  padding: clamp(28px, 5vw, 64px) clamp(20px, 5vw, 56px);
  background: #1a1818;
  font-family: 'JetBrains Mono', monospace;
  color: #d8d4c8;
  box-sizing: border-box;
  contain: layout paint;
}

.hs-29__static {
  position: absolute;
  inset: 0;
  background-image: radial-gradient(rgba(255,255,255,0.04) 1px, transparent 1px), radial-gradient(rgba(255,255,255,0.03) 1px, transparent 1px);
  background-size: 3px 3px, 5px 5px;
  background-position: 0 0, 1px 1px;
  pointer-events: none;
  animation: hs-29-jit 0.2s steps(2) infinite;
}

.hs-29__scan {
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(180deg, transparent 0 2px, rgba(0,0,0,0.18) 2px 3px);
  pointer-events: none;
}

@keyframes hs-29-jit {
  0% {
    transform: translate(0,0);
  }

  50% {
    transform: translate(-1px,1px);
  }

  100% {
    transform: translate(1px,-1px);
  }
}

.hs-29__inner {
  position: relative;
  z-index: 1;
  max-width: 640px;
  text-align: center;
}

.hs-29__eye {
  display: inline-block;
  padding: 4px 10px;
  background: #d63838;
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.18em;
  margin-bottom: 22px;
  animation: hs-29-blink 1.4s steps(2) infinite;
}

@keyframes hs-29-blink {
  to {
    opacity: 0.5;
  }
}

.hs-29__h {
  position: relative;
  margin: 0 0 18px;
  font-family: 'Inter', sans-serif;
  font-size: clamp(48px, 9vw, 100px);
  font-weight: 900;
  letter-spacing: -0.04em;
  line-height: 0.92;
  color: #f0eee0;
}

.hs-29__h::before,
.hs-29__h::after {
  content: attr(data-text);
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  pointer-events: none;
  text-align: center;
}

.hs-29__h::before {
  color: #d63838;
  transform: translate(-3px,0);
  clip-path: polygon(0 12%, 100% 12%, 100% 38%, 0 38%);
  animation: hs-29-rgb 2.4s ease-in-out infinite;
}

.hs-29__h::after {
  color: #38b8d6;
  transform: translate(3px,0);
  clip-path: polygon(0 56%, 100% 56%, 100% 88%, 0 88%);
  animation: hs-29-rgb 2.4s ease-in-out infinite reverse;
}

@keyframes hs-29-rgb {
  0%,
    100% {
    transform: translate(-3px,0);
  }

  50% {
    transform: translate(3px,2px);
  }
}

.hs-29 p {
  margin: 0 auto 24px;
  font-size: 14px;
  line-height: 1.6;
  color: #98948c;
  max-width: 460px;
}

.hs-29__cta {
  display: inline-block;
  padding: 12px 22px;
  background: #38b8d6;
  color: #1a1818;
  border-radius: 0;
  text-decoration: none;
  font-weight: 800;
  font-size: 13px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  transition: background 0.15s, color 0.15s;
}

.hs-29__cta:hover {
  background: #d63838;
  color: #fff;
}

@media (prefers-reduced-motion: reduce) {
  .hs-29__static,
    .hs-29__eye,
    .hs-29__h::before,
    .hs-29__h::after {
    animation: none;
  }

  .hs-29__cta {
    transition: none;
  }
}
```

How this works

This glitch text hero section builds the RGB-shift effect from a single <h2 data-text="LOST & FOUND"> plus two pseudo-elements that read the same text via content: attr(data-text). The ::before layer renders in VHS red (#d63838) with transform: translate(-3px, 0) and clips to the upper band (clip-path: polygon(0 12%, 100% 12%, 100% 38%, 0 38%)). The ::after layer renders in tape blue (#38b8d6) with the opposite offset and clips to a lower band (56%-88%). Both animate the hs-29-rgb keyframe (2.4s ease-in-out, one running reverse) so the channels drift out of sync — the classic Cyberpunk-2077 / Chromatic-Aberration signature.

Two absolutely-positioned overlays sit on top of the whole section: .hs-29__static paints two stacked radial-gradient dot patterns (3px × 3px and 5px × 5px grids) and animates the hs-29-jit keyframe (steps(2) jitter at 0.2s intervals — no interpolation, pure snap) so the noise reads as VHS tape grain. .hs-29__scan paints a repeating-linear-gradient of 2-3px horizontal bands at 18% black to add scanlines. Background is static gray (#1a1818) not black — a critical detail; pure black kills the tape-noise contrast. The REC ● 00:42:18 eyebrow uses hs-29-blink (opacity 1 → 0.5 on steps(2)) so it flashes like a recording indicator.

Why it converts: glitch signals "cutting edge" for tech-adjacent audiences — the same visual language as Cyberpunk 2077, Web3 mint pages, and creative-coding portfolios. The RGB-shift specifically taps nostalgia for VHS-era media, which is the fastest-growing aesthetic in Gen Z / millennial creative markets. Single tape-blue CTA against the red RGB channel is the highest-contrast conversion path.

Make it yours

  • Recolor to your brand by editing three values: VHS red (#d63838), tape blue (#38b8d6), and static gray (#1a1818). For Web3 mint → red to #7b3ff2 purple, blue to #00f0ff cyan. For hacker aesthetic → red to #ff003c, blue to #00ff88. Keep the RGB offset direction opposite — that's the chromatic aberration signature.
  • Swap the display sans: Inter 900 reads as "modern glitch." For pure cyberpunk → 'Space Grotesk' or 'Anton'. For Web3 → 'Syne' 800. For retro-VHS → 'VT323' monospace (matches the aesthetic but sacrifices the sharp glitch band). Keep the font-weight: 900 — thin weights lose the RGB-shift readability.
  • Change the CTA: border-radius: 0 is the brutalist / VHS-tape button standard. Bump to border-radius: 4px for retro-gaming warmth. Add box-shadow: 4px 4px 0 #d63838 for a stamped-poster effect that layers the two accent colors. For maximum tension, animate the CTA background between red/blue on hover to mirror the RGB shift.
  • For light mode: this pattern doesn't invert cleanly — RGB-shift needs a dark backdrop. If you must ship a light variant, swap to #f0e8dc paper base with #8a1a1a deep-red and #1a5a6a teal channels, and dial the noise opacity from 0.04 down to 0.02. The result reads as "risograph print," not glitch.
  • For Tailwind: relative overflow-hidden grid place-items-center bg-[#1a1818] font-mono contain-[layout_paint] on section, font-sans text-6xl md:text-8xl font-black tracking-tighter leading-[0.92] on h2. The ::before / ::after layers need a custom plugin — Tailwind can't handle content: attr(data-text). Ship as a scoped CSS module.

Gotchas — read before shipping

  • NEVER animate the clip-path polygon values on the pseudo-elements — that triggers full paint on every keyframe and INP catapults past 500ms on mid-tier mobile. Animate only transform as this demo does; keep the clip-path static. The steps(2) jitter on hs-29-jit is safe because it toggles between two composited positions with no interpolation.
  • The hs-29-blink on the REC eyebrow flashes at 1.4s intervals — that's ABOVE the WCAG 2.3.1 seizure threshold (3 flashes per second), so this is safe. But if you speed it up to <0.35s, you cross into flash territory and fail 2.3.1. Verify with the PEAT (Photosensitive Epilepsy Analysis Tool) before shipping anything faster.
  • The static-noise overlay .hs-29__static uses rgba(255,255,255,0.04) — that's near-imperceptible on #1a1818 (~1.05:1 contrast) but adds ~30% GPU paint cost on the animated jitter. If your INP budget is tight (targeting sub-150ms for Core Web Vitals green), drop the second radial-gradient layer and keep only the 3px grid — visually 90% identical.
  • The tape-blue CTA #38b8d6 on gray #1a1818 contrast is ~6.4:1 — passes WCAG AA (1.4.3) for normal text but not AAA. The button text is #1a1818 on #38b8d6, same 6.4:1. If your CTA copy is small caps below 13px, deepen the button color to #2a95b0 or use pure white text — the current pairing is right at the AA limit.
  • In Safari 16 and older, data-text attribute reading via content: attr(data-text) does NOT respect emoji or CJK characters in the attribute — the pseudo-element renders empty. Restrict the glitch text to Latin-1 characters, or shim with a <span aria-hidden="true"> duplicate for non-Latin scripts.
  • The prefers-reduced-motion guard disables the static, blink, and RGB-shift animations — but leaves the scanline overlay static, which is correct (constant patterns don't trigger vestibular response). WCAG 2.3.3 compliance is intact. However, if you add mouse-tracking glitch amplification (a common upgrade), guard THAT via matchMedia or you fail vestibular safety.

Techniques used in this demo

Search CodeFronts

Loading…