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.
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