Possessed Overgrowth

Glitch & Distortion · Animated · pure CSS

Each letter sprouts scaled, ghostly copies of itself sprouting up and down — a static, per-letter overgrowth built from attr(data-text) pseudo-elements and stacked text-shadow echoes, warped by an SVG feTurbulence filter whose seed writhes forever. The solid base glyph stays legible while the corruption sprawls above and below it.

Possessed Overgrowth

How it works

Possessed Overgrowth is an animated glitch & distortion text effect rendered entirely in CSS. Each character is wrapped in its own span so it can animate independently — the HTML and JSX exports include that per-letter markup. It relies on an inline SVG <defs> block (filters, gradients or clip-paths), which the HTML export carries alongside the CSS.

Controls

Possessed Overgrowth exposes 5 dedicated controls — Overgrowth Height, Ghost Density, Ghost Opacity, Writhe Speed and Corruption Tint — on top of the shared type controls (font, weight, letter-spacing and case). Open it in the generator to tune every value live, then copy the updated CSS.

CSS

/* Possessed Overgrowth — made with TEXT-FX · https://text-fx.app
 * HTML: each character is wrapped in a <span> — see the HTML export; requires the inline <svg> filter defs — see the HTML export.
 * Font: 'Unbounded', sans-serif (load from Google Fonts).
 */

.text-effect {
  font-family: 'Unbounded', sans-serif;
  font-weight: 400;
  letter-spacing: 8px;
  text-transform: none;
}

.text-effect {
  position: relative;
  display: inline-flex;
  white-space: pre;
}
.text-effect .fx-ch {
  position: relative;
  display: inline-block;
  color: hsl(359 30% 94%);
  text-shadow: 0 calc(-1 * (11.11px + min(var(--i), 6) * 2.02px)) 0 hsl(359 60% 60% / 0.248),
    0 calc(10.1px + min(var(--i), 6) * 2.02px) 0 hsl(233 55% 55% / 0.211),
    0 calc(-1 * (23.23px + min(var(--i), 6) * 3.03px)) 0 hsl(359 60% 60% / 0.136),
    0 calc(21.21px + min(var(--i), 6) * 3.03px) 0 hsl(233 55% 55% / 0.116);
}
.text-effect .fx-ch::before,
.text-effect .fx-ch::after {
  content: attr(data-text);
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  pointer-events: none;
  filter: url(#text-effect-writhe);
}
.text-effect .fx-ch::before {
  color: hsl(359 68% 74%);
  transform-origin: 50% 100%;
  transform: scaleY(calc(1.152 + 0.061 * min(var(--i), 6))) translateY(calc(-1 * (8.08px + min(var(--i), 6) * 4.04px)));
  opacity: calc(0.174 + 0.022 * min(var(--i), 6));
}
.text-effect .fx-ch::after {
  color: hsl(233 45% 63%);
  transform-origin: 50% 0%;
  transform: scaleY(calc(1.202 + 0.051 * min(var(--i), 6))) translateY(calc(8.08px + min(var(--i), 6) * 4.04px));
  opacity: calc(0.149 + 0.02 * min(var(--i), 6));
}

HTML

This effect needs the markup below (per-letter spans, SVG defs, or a data-text attribute).

<!-- Made with TEXT-FX · https://text-fx.app -->

<style>
.text-effect {
  font-family: 'Unbounded', sans-serif;
  font-weight: 400;
  letter-spacing: 8px;
  text-transform: none;
}

.text-effect {
  position: relative;
  display: inline-flex;
  white-space: pre;
}
.text-effect .fx-ch {
  position: relative;
  display: inline-block;
  color: hsl(359 30% 94%);
  text-shadow: 0 calc(-1 * (11.11px + min(var(--i), 6) * 2.02px)) 0 hsl(359 60% 60% / 0.248),
    0 calc(10.1px + min(var(--i), 6) * 2.02px) 0 hsl(233 55% 55% / 0.211),
    0 calc(-1 * (23.23px + min(var(--i), 6) * 3.03px)) 0 hsl(359 60% 60% / 0.136),
    0 calc(21.21px + min(var(--i), 6) * 3.03px) 0 hsl(233 55% 55% / 0.116);
}
.text-effect .fx-ch::before,
.text-effect .fx-ch::after {
  content: attr(data-text);
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  pointer-events: none;
  filter: url(#text-effect-writhe);
}
.text-effect .fx-ch::before {
  color: hsl(359 68% 74%);
  transform-origin: 50% 100%;
  transform: scaleY(calc(1.152 + 0.061 * min(var(--i), 6))) translateY(calc(-1 * (8.08px + min(var(--i), 6) * 4.04px)));
  opacity: calc(0.174 + 0.022 * min(var(--i), 6));
}
.text-effect .fx-ch::after {
  color: hsl(233 45% 63%);
  transform-origin: 50% 0%;
  transform: scaleY(calc(1.202 + 0.051 * min(var(--i), 6))) translateY(calc(8.08px + min(var(--i), 6) * 4.04px));
  opacity: calc(0.149 + 0.02 * min(var(--i), 6));
}
</style>

<svg width="0" height="0" style="position:absolute" aria-hidden="true"><defs>
<filter id="text-effect-writhe" x="-60%" y="-60%" width="220%" height="220%">
  <feTurbulence type="fractalNoise" baseFrequency="0.03 0.09" numOctaves="2" seed="4" result="turb">
    <animate attributeName="baseFrequency" dur="15s" values="0.03 0.09;0.05 0.11;0.02 0.06;0.03 0.09" repeatCount="indefinite"/>
  </feTurbulence>
  <feDisplacementMap in="SourceGraphic" in2="turb" scale="12" xChannelSelector="R" yChannelSelector="G"/>
</filter>
</defs></svg>

<div class="text-effect"><span class="fx-ch" data-text="Y" style="--i:0;--n:9;--rev:8;--mid:4">Y</span><span class="fx-ch" data-text="o" style="--i:1;--n:9;--rev:7;--mid:4">o</span><span class="fx-ch" data-text="u" style="--i:2;--n:9;--rev:6;--mid:4">u</span><span class="fx-ch" data-text="r" style="--i:3;--n:9;--rev:5;--mid:4">r</span><span class="fx-ch" data-text=" " style="--i:4;--n:9;--rev:4;--mid:4"> </span><span class="fx-ch" data-text="t" style="--i:5;--n:9;--rev:3;--mid:4">t</span><span class="fx-ch" data-text="e" style="--i:6;--n:9;--rev:2;--mid:4">e</span><span class="fx-ch" data-text="x" style="--i:7;--n:9;--rev:1;--mid:4">x</span><span class="fx-ch" data-text="t" style="--i:8;--n:9;--rev:0;--mid:4">t</span></div>
Category
Glitch & Distortion
Type
Animated
Browser support
Per-letter attr(data-text) ghost copies warped by an SVG feTurbulence + feDisplacementMap filter (SMIL-animated)
Capabilities
perLetter, svgDefs

Related Glitch & Distortion effects