Punk Slash
Retro & Themed · Animated · pure CSS
Jagged red, black and white slats clip to torn-paper polygons and slide in from alternating sides, stacking into a punk-flyer collage behind the word. The letters then pop up over the top with a fixed alternating tilt and a thin ink stroke, and every third one flips to the accent color on a skewed paper chip — a one-shot entrance that tears back together on hover.
How it works
Punk Slash is an animated retro & themed 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.
Controls
Punk Slash exposes 5 dedicated controls — Accent Hue, Slats, Jaggedness, Letter Tilt and Speed — 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
/* Punk Slash — made with TEXT-FX · https://text-fx.app
* HTML: each character is wrapped in a <span> — see the HTML export.
* Font: 'Bungee', cursive (load from Google Fonts).
*/
.text-effect {
font-family: 'Bungee', cursive;
font-weight: 700;
letter-spacing: 0px;
text-transform: none;
}
.text-effect {
display: inline-block;
position: relative;
isolation: isolate;
padding: 0.5em 0.85em;
font-style: italic;
}
.text-effect .fx-slat {
position: absolute;
left: 50%;
top: 50%;
z-index: 0;
will-change: transform;
box-shadow: 3px 3px 0 hsl(0 0% 0% / 0.32), 0 0 0 1px hsl(0 0% 100% / 0.1);
transform: translate(-50%, -50%) translateX(var(--rest, 0%)) rotate(var(--rot, 0deg)) scale(var(--scl, 1));
}
.text-effect .fx-s0 {
width: 132%;
height: 40%;
background: hsl(350 88% 53%);
clip-path: polygon(0% 30%, 92% 0%, 100% 55%, 8% 100%);
--rot: -8deg;
--rest: -6%;
--scl: 1;
--dly: 0ms;
opacity: 1;
}
.text-effect .fx-s1 {
width: 122%;
height: 30%;
background: hsl(350 14% 8%);
clip-path: polygon(0% 0%, 100% 22%, 97.3% 78%, 2.7% 100%);
--rot: 6deg;
--rest: 10%;
--scl: 1;
--dly: 90ms;
opacity: 1;
}
.text-effect .fx-s2 {
width: 58%;
height: 74%;
background: hsl(350 14% 8%);
clip-path: polygon(50% 0%, 60.6% 39.4%, 100% 50%, 60.6% 60.6%, 50% 100%, 39.4% 60.6%, 0% 50%, 39.4% 39.4%);
--rot: 14deg;
--rest: 24%;
--scl: 0.9;
--dly: 50ms;
opacity: 0.92;
}
.text-effect .fx-s3 {
width: 120%;
height: 16%;
background: hsl(40 26% 95%);
clip-path: polygon(0% 20%, 96% 0%, 100% 80%, 4% 100%);
--rot: -3deg;
--rest: 2%;
--scl: 1;
--dly: 170ms;
opacity: 1;
}
.text-effect .fx-l {
animation: text-effect-slfromL 0.86s cubic-bezier(.16,.9,.2,1) 1 both;
animation-delay: var(--dly, 0ms);
}
.text-effect .fx-r {
animation: text-effect-slfromRt 0.86s cubic-bezier(.16,.9,.2,1) 1 both;
animation-delay: var(--dly, 0ms);
}
.text-effect .fx-title {
position: relative;
z-index: 5;
display: inline-block;
white-space: pre;
line-height: 1;
}
.text-effect .fx-ch {
display: inline-block;
color: hsl(40 26% 95%);
-webkit-text-stroke: 2px hsl(350 14% 8%);
paint-order: stroke fill;
text-shadow: 3px 3px 0 hsl(0 0% 0% / 0.45);
opacity: 1;
transform: rotate(var(--r, 0deg)) translateY(var(--y, 0));
animation: text-effect-pop 0.86s cubic-bezier(.2,1.45,.3,1) 1 both;
animation-delay: calc(0.43s + var(--i, 0) * 50ms);
}
.text-effect .fx-ch.fx-sp {
width: 0.35em;
animation: none;
text-shadow: none;
-webkit-text-stroke: 0;
}
.text-effect .fx-ch.fx-chip {
color: hsl(350 88% 53%);
z-index: 6;
}
.text-effect .fx-ch.fx-chip::before {
content: "";
position: absolute;
inset: -8% -14%;
z-index: -1;
background: hsl(40 26% 95%);
clip-path: polygon(6% 8%, 100% 0%, 94% 92%, 0% 100%);
transform: skewX(-8deg) rotate(calc(var(--r, 0deg) * -1));
box-shadow: 3px 3px 0 hsl(350 14% 8%);
}
.text-effect:hover .fx-l {
animation-name: text-effect-slfromL-r;
}
.text-effect:hover .fx-r {
animation-name: text-effect-slfromRt-r;
}
.text-effect:hover .fx-ch {
animation-name: text-effect-pop-r;
}
@keyframes text-effect-slfromL {
0% { transform: translate(-50%, -50%) translateX(-175%) rotate(var(--rot, 0deg)) scale(var(--scl, 1)); }
60%, 100% { transform: translate(-50%, -50%) translateX(var(--rest, 0%)) rotate(var(--rot, 0deg)) scale(var(--scl, 1)); }
}
@keyframes text-effect-slfromRt {
0% { transform: translate(-50%, -50%) translateX(185%) rotate(var(--rot, 0deg)) scale(var(--scl, 1)); }
60%, 100% { transform: translate(-50%, -50%) translateX(var(--rest, 0%)) rotate(var(--rot, 0deg)) scale(var(--scl, 1)); }
}
@keyframes text-effect-pop {
0% { opacity: 0; transform: rotate(var(--r, 0deg)) translateY(calc(var(--y, 0px) - 40px)) scale(0.4); }
55% { opacity: 1; }
70% { transform: rotate(var(--r, 0deg)) translateY(var(--y, 0)) scale(1.14); }
84% { transform: rotate(var(--r, 0deg)) translateY(var(--y, 0)) scale(0.96); }
100% { opacity: 1; transform: rotate(var(--r, 0deg)) translateY(var(--y, 0)) scale(1); }
}
@keyframes text-effect-slfromL-r {
0% { transform: translate(-50%, -50%) translateX(-175%) rotate(var(--rot, 0deg)) scale(var(--scl, 1)); }
60%, 100% { transform: translate(-50%, -50%) translateX(var(--rest, 0%)) rotate(var(--rot, 0deg)) scale(var(--scl, 1)); }
}
@keyframes text-effect-slfromRt-r {
0% { transform: translate(-50%, -50%) translateX(185%) rotate(var(--rot, 0deg)) scale(var(--scl, 1)); }
60%, 100% { transform: translate(-50%, -50%) translateX(var(--rest, 0%)) rotate(var(--rot, 0deg)) scale(var(--scl, 1)); }
}
@keyframes text-effect-pop-r {
0% { opacity: 0; transform: rotate(var(--r, 0deg)) translateY(calc(var(--y, 0px) - 40px)) scale(0.4); }
55% { opacity: 1; }
70% { transform: rotate(var(--r, 0deg)) translateY(var(--y, 0)) scale(1.14); }
84% { transform: rotate(var(--r, 0deg)) translateY(var(--y, 0)) scale(0.96); }
100% { opacity: 1; transform: rotate(var(--r, 0deg)) translateY(var(--y, 0)) scale(1); }
}
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: 'Bungee', cursive;
font-weight: 700;
letter-spacing: 0px;
text-transform: none;
}
.text-effect {
display: inline-block;
position: relative;
isolation: isolate;
padding: 0.5em 0.85em;
font-style: italic;
}
.text-effect .fx-slat {
position: absolute;
left: 50%;
top: 50%;
z-index: 0;
will-change: transform;
box-shadow: 3px 3px 0 hsl(0 0% 0% / 0.32), 0 0 0 1px hsl(0 0% 100% / 0.1);
transform: translate(-50%, -50%) translateX(var(--rest, 0%)) rotate(var(--rot, 0deg)) scale(var(--scl, 1));
}
.text-effect .fx-s0 {
width: 132%;
height: 40%;
background: hsl(350 88% 53%);
clip-path: polygon(0% 30%, 92% 0%, 100% 55%, 8% 100%);
--rot: -8deg;
--rest: -6%;
--scl: 1;
--dly: 0ms;
opacity: 1;
}
.text-effect .fx-s1 {
width: 122%;
height: 30%;
background: hsl(350 14% 8%);
clip-path: polygon(0% 0%, 100% 22%, 97.3% 78%, 2.7% 100%);
--rot: 6deg;
--rest: 10%;
--scl: 1;
--dly: 90ms;
opacity: 1;
}
.text-effect .fx-s2 {
width: 58%;
height: 74%;
background: hsl(350 14% 8%);
clip-path: polygon(50% 0%, 60.6% 39.4%, 100% 50%, 60.6% 60.6%, 50% 100%, 39.4% 60.6%, 0% 50%, 39.4% 39.4%);
--rot: 14deg;
--rest: 24%;
--scl: 0.9;
--dly: 50ms;
opacity: 0.92;
}
.text-effect .fx-s3 {
width: 120%;
height: 16%;
background: hsl(40 26% 95%);
clip-path: polygon(0% 20%, 96% 0%, 100% 80%, 4% 100%);
--rot: -3deg;
--rest: 2%;
--scl: 1;
--dly: 170ms;
opacity: 1;
}
.text-effect .fx-l {
animation: text-effect-slfromL 0.86s cubic-bezier(.16,.9,.2,1) 1 both;
animation-delay: var(--dly, 0ms);
}
.text-effect .fx-r {
animation: text-effect-slfromRt 0.86s cubic-bezier(.16,.9,.2,1) 1 both;
animation-delay: var(--dly, 0ms);
}
.text-effect .fx-title {
position: relative;
z-index: 5;
display: inline-block;
white-space: pre;
line-height: 1;
}
.text-effect .fx-ch {
display: inline-block;
color: hsl(40 26% 95%);
-webkit-text-stroke: 2px hsl(350 14% 8%);
paint-order: stroke fill;
text-shadow: 3px 3px 0 hsl(0 0% 0% / 0.45);
opacity: 1;
transform: rotate(var(--r, 0deg)) translateY(var(--y, 0));
animation: text-effect-pop 0.86s cubic-bezier(.2,1.45,.3,1) 1 both;
animation-delay: calc(0.43s + var(--i, 0) * 50ms);
}
.text-effect .fx-ch.fx-sp {
width: 0.35em;
animation: none;
text-shadow: none;
-webkit-text-stroke: 0;
}
.text-effect .fx-ch.fx-chip {
color: hsl(350 88% 53%);
z-index: 6;
}
.text-effect .fx-ch.fx-chip::before {
content: "";
position: absolute;
inset: -8% -14%;
z-index: -1;
background: hsl(40 26% 95%);
clip-path: polygon(6% 8%, 100% 0%, 94% 92%, 0% 100%);
transform: skewX(-8deg) rotate(calc(var(--r, 0deg) * -1));
box-shadow: 3px 3px 0 hsl(350 14% 8%);
}
.text-effect:hover .fx-l {
animation-name: text-effect-slfromL-r;
}
.text-effect:hover .fx-r {
animation-name: text-effect-slfromRt-r;
}
.text-effect:hover .fx-ch {
animation-name: text-effect-pop-r;
}
@keyframes text-effect-slfromL {
0% { transform: translate(-50%, -50%) translateX(-175%) rotate(var(--rot, 0deg)) scale(var(--scl, 1)); }
60%, 100% { transform: translate(-50%, -50%) translateX(var(--rest, 0%)) rotate(var(--rot, 0deg)) scale(var(--scl, 1)); }
}
@keyframes text-effect-slfromRt {
0% { transform: translate(-50%, -50%) translateX(185%) rotate(var(--rot, 0deg)) scale(var(--scl, 1)); }
60%, 100% { transform: translate(-50%, -50%) translateX(var(--rest, 0%)) rotate(var(--rot, 0deg)) scale(var(--scl, 1)); }
}
@keyframes text-effect-pop {
0% { opacity: 0; transform: rotate(var(--r, 0deg)) translateY(calc(var(--y, 0px) - 40px)) scale(0.4); }
55% { opacity: 1; }
70% { transform: rotate(var(--r, 0deg)) translateY(var(--y, 0)) scale(1.14); }
84% { transform: rotate(var(--r, 0deg)) translateY(var(--y, 0)) scale(0.96); }
100% { opacity: 1; transform: rotate(var(--r, 0deg)) translateY(var(--y, 0)) scale(1); }
}
@keyframes text-effect-slfromL-r {
0% { transform: translate(-50%, -50%) translateX(-175%) rotate(var(--rot, 0deg)) scale(var(--scl, 1)); }
60%, 100% { transform: translate(-50%, -50%) translateX(var(--rest, 0%)) rotate(var(--rot, 0deg)) scale(var(--scl, 1)); }
}
@keyframes text-effect-slfromRt-r {
0% { transform: translate(-50%, -50%) translateX(185%) rotate(var(--rot, 0deg)) scale(var(--scl, 1)); }
60%, 100% { transform: translate(-50%, -50%) translateX(var(--rest, 0%)) rotate(var(--rot, 0deg)) scale(var(--scl, 1)); }
}
@keyframes text-effect-pop-r {
0% { opacity: 0; transform: rotate(var(--r, 0deg)) translateY(calc(var(--y, 0px) - 40px)) scale(0.4); }
55% { opacity: 1; }
70% { transform: rotate(var(--r, 0deg)) translateY(var(--y, 0)) scale(1.14); }
84% { transform: rotate(var(--r, 0deg)) translateY(var(--y, 0)) scale(0.96); }
100% { opacity: 1; transform: rotate(var(--r, 0deg)) translateY(var(--y, 0)) scale(1); }
}
</style>
<div class="text-effect"><span class="fx-slat fx-l fx-s0"></span><span class="fx-slat fx-r fx-s1"></span><span class="fx-slat fx-r fx-s2"></span><span class="fx-slat fx-l fx-s3"></span><div class="fx-title"><span class="fx-ch" style="--i:0;--r:-5deg;--y:2px">Y</span><span class="fx-ch" style="--i:1;--r:5deg;--y:-4px">o</span><span class="fx-ch fx-chip" style="--i:2;--r:-5deg;--y:3px">u</span><span class="fx-ch" style="--i:3;--r:5deg;--y:-2px">r</span><span class="fx-ch fx-sp"> </span><span class="fx-ch" style="--i:4;--r:-5deg;--y:4px">t</span><span class="fx-ch fx-chip" style="--i:5;--r:5deg;--y:-3px">e</span><span class="fx-ch" style="--i:6;--r:-5deg;--y:2px">x</span><span class="fx-ch" style="--i:7;--r:5deg;--y:-4px">t</span></div></div>
- Category
- Retro & Themed
- Type
- Animated
- Browser support
- All modern browsers
- Capabilities
- perLetter