Confetti Burst

Entrance & Kinetic · Animated · pure CSS

A celebration entrance: the word pops in with a scale overshoot while dozens of tiny colored rectangles and dots explode radially from behind it, spinning and falling under fake gravity before they fade, topped with a quick expanding shockwave ring. Two counter-rotating pseudo-element layers carry the particles, settling to clean multi-hue lettering in a party palette derived from one base hue.

Confetti Burst

How it works

Confetti Burst is an animated entrance & kinetic text effect rendered entirely in CSS. It works on a single element — just add the .text-effect class, with no extra HTML.

Controls

Confetti Burst exposes 4 dedicated controls — Palette Hue, Burst Size, Pieces and Duration — 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

/* Confetti Burst — made with TEXT-FX · https://text-fx.app
 * HTML: just put the class on any element.
 * Font: 'Bungee', cursive (load from Google Fonts).
 */

.text-effect {
  font-family: 'Bungee', cursive;
  font-weight: 400;
  letter-spacing: 4px;
  text-transform: none;
}

.text-effect {
  position: relative;
  display: inline-block;
  z-index: 0;
}
.text-effect .fx-word {
  display: inline-block;
  position: relative;
  transform-origin: 50% 55%;
  background: linear-gradient(92deg, hsl(212 88% 62%), hsl(2 88% 62%), hsl(132 88% 62%), hsl(252 88% 62%));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  animation: text-effect-pop 0.66s cubic-bezier(0.2, 0.7, 0.3, 1) both;
}
.text-effect .fx-word::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 1em;
  height: 1em;
  margin: -0.5em 0 0 -0.5em;
  border-radius: 50%;
  border: 0.1em solid hsl(212 90% 72%);
  box-sizing: border-box;
  pointer-events: none;
  transform: scale(0);
  opacity: 0;
  animation: text-effect-ring 0.76s cubic-bezier(0.1, 0.7, 0.3, 1) both;
}
.text-effect::before,
.text-effect::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-repeat: no-repeat;
}
.text-effect::before {
  background-image:
    radial-gradient(circle at 50% 50%, hsl(212 88% 62%) 0 54%, transparent 58%),
    linear-gradient(hsl(2 88% 62%), hsl(2 88% 62%)),
    linear-gradient(hsl(132 88% 62%), hsl(132 88% 62%)),
    radial-gradient(circle at 50% 50%, hsl(212 88% 62%) 0 54%, transparent 58%),
    linear-gradient(hsl(2 88% 62%), hsl(2 88% 62%)),
    linear-gradient(hsl(132 88% 62%), hsl(132 88% 62%)),
    radial-gradient(circle at 50% 50%, hsl(212 88% 62%) 0 54%, transparent 58%),
    linear-gradient(hsl(2 88% 62%), hsl(2 88% 62%)),
    linear-gradient(hsl(132 88% 62%), hsl(132 88% 62%)),
    radial-gradient(circle at 50% 50%, hsl(212 88% 62%) 0 54%, transparent 58%),
    linear-gradient(hsl(2 88% 62%), hsl(2 88% 62%)),
    linear-gradient(hsl(132 88% 62%), hsl(132 88% 62%)),
    radial-gradient(circle at 50% 50%, hsl(212 88% 62%) 0 54%, transparent 58%);
  background-position: 66% 50%, 34.5% 64.2%, 52.3% 24.1%, 68.9% 74.6%, 14.6% 43.7%, 63.5% 41.4%, 44.5% 70.3%, 38% 26.9%, 79.1% 60.6%, 16.7% 63.7%, 56.8% 35.5%, 56.3% 70%, 27.5% 37%;
  background-size: 5px 5px, 7px 4px, 9px 5px, 8px 8px, 5px 4px, 7px 5px, 7px 7px, 11px 4px, 5px 5px, 6px 6px, 9px 4px, 11px 5px, 5px 5px;
  animation: text-effect-confa 1.06s cubic-bezier(0.15, 0.6, 0.35, 1) both;
}
.text-effect::after {
  background-image:
    radial-gradient(circle at 50% 50%, hsl(52 88% 62%) 0 54%, transparent 58%),
    linear-gradient(hsl(307 88% 62%), hsl(307 88% 62%)),
    linear-gradient(hsl(252 88% 62%), hsl(252 88% 62%)),
    radial-gradient(circle at 50% 50%, hsl(52 88% 62%) 0 54%, transparent 58%),
    linear-gradient(hsl(307 88% 62%), hsl(307 88% 62%)),
    linear-gradient(hsl(252 88% 62%), hsl(252 88% 62%)),
    radial-gradient(circle at 50% 50%, hsl(52 88% 62%) 0 54%, transparent 58%),
    linear-gradient(hsl(307 88% 62%), hsl(307 88% 62%)),
    linear-gradient(hsl(252 88% 62%), hsl(252 88% 62%)),
    radial-gradient(circle at 50% 50%, hsl(52 88% 62%) 0 54%, transparent 58%),
    linear-gradient(hsl(307 88% 62%), hsl(307 88% 62%)),
    linear-gradient(hsl(252 88% 62%), hsl(252 88% 62%)),
    radial-gradient(circle at 50% 50%, hsl(52 88% 62%) 0 54%, transparent 58%);
  background-position: 58% 63.9%, 30% 43.7%, 73.6% 39%, 38.1% 78.6%, 37.7% 16.2%, 64.2% 57.4%, 29.7% 55.4%, 64% 28.1%, 55.3% 80.5%, 21.5% 28%, 65.9% 48.6%, 35.8% 65.5%, 50% 24%;
  background-size: 5px 5px, 7px 4px, 9px 5px, 8px 8px, 5px 4px, 7px 5px, 7px 7px, 11px 4px, 5px 5px, 6px 6px, 9px 4px, 11px 5px, 5px 5px;
  animation: text-effect-confb 1.14s cubic-bezier(0.15, 0.6, 0.35, 1) both;
}
.text-effect:hover .fx-word {
  animation-name: text-effect-pop-r;
}
.text-effect:hover .fx-word::before {
  animation-name: text-effect-ring-r;
}
.text-effect:hover::before {
  animation-name: text-effect-confa-r;
}
.text-effect:hover::after {
  animation-name: text-effect-confb-r;
}

@keyframes text-effect-pop {
  0% { transform: scale(0.5); opacity: 0; }
  55% { transform: scale(1.12); opacity: 1; }
  72% { transform: scale(0.95); opacity: 1; }
  86% { transform: scale(1.03); }
  100% { transform: scale(1); opacity: 1; }
}

@keyframes text-effect-confa {
  0% { transform: translateY(0) scale(0.2) rotate(0deg); opacity: 0; }
  10% { opacity: 1; }
  40% { transform: translateY(-5%) scale(3.97) rotate(120deg); opacity: 1; }
  100% { transform: translateY(26%) scale(6.4) rotate(230deg); opacity: 0; }
}

@keyframes text-effect-confb {
  0% { transform: translateY(0) scale(0.2) rotate(0deg); opacity: 0; }
  16% { opacity: 1; }
  45% { transform: translateY(-3%) scale(3.15) rotate(-90deg); opacity: 1; }
  100% { transform: translateY(36%) scale(5.25) rotate(-280deg); opacity: 0; }
}

@keyframes text-effect-ring {
  0% { transform: scale(0); opacity: 0; }
  9% { opacity: 0.9; }
  55% { opacity: 0.45; }
  100% { transform: scale(5); opacity: 0; }
}

@keyframes text-effect-pop-r {
  0% { transform: scale(0.5); opacity: 0; }
  55% { transform: scale(1.12); opacity: 1; }
  72% { transform: scale(0.95); opacity: 1; }
  86% { transform: scale(1.03); }
  100% { transform: scale(1); opacity: 1; }
}

@keyframes text-effect-confa-r {
  0% { transform: translateY(0) scale(0.2) rotate(0deg); opacity: 0; }
  10% { opacity: 1; }
  40% { transform: translateY(-5%) scale(3.97) rotate(120deg); opacity: 1; }
  100% { transform: translateY(26%) scale(6.4) rotate(230deg); opacity: 0; }
}

@keyframes text-effect-confb-r {
  0% { transform: translateY(0) scale(0.2) rotate(0deg); opacity: 0; }
  16% { opacity: 1; }
  45% { transform: translateY(-3%) scale(3.15) rotate(-90deg); opacity: 1; }
  100% { transform: translateY(36%) scale(5.25) rotate(-280deg); opacity: 0; }
}

@keyframes text-effect-ring-r {
  0% { transform: scale(0); opacity: 0; }
  9% { opacity: 0.9; }
  55% { opacity: 0.45; }
  100% { transform: scale(5); opacity: 0; }
}

Pure CSS — just add the .text-effect class to any element.

Category
Entrance & Kinetic
Type
Animated
Browser support
Layered gradient particles + background-clip:text (all modern browsers)
Capabilities
pure

Related Entrance & Kinetic effects