AI CSS Animations

Rising Embers Background

Glowing embers climb from an unseen fire, flickering and zigzagging as they cool and fade halfway up a dark backdrop. The climb, the zigzag and the flicker are three separate animations.

Also known as: fire sparks background css, embers animation css, floating sparks css.

HTML

<div class="bgx-rising-embers" aria-hidden="true"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></div>

CSS

.bgx-rising-embers {
  --c: var(--bgx-color, #3b82f6);
  font-size: var(--bgx-size, 16px);
  position: absolute;
  inset: 0;
  overflow: hidden;
  --ember: color-mix(in oklab, var(--c) 15%, #ff8a3d);
  background: linear-gradient(to bottom, #070509, #150a08 65%, #2a1109);}
.bgx-rising-embers::after {
  content: "";
  position: absolute;
  inset: auto -10% 0;
  height: 55%;
  background: radial-gradient(ellipse 60% 100% at 50% 100%, color-mix(in srgb, var(--ember) 50%, transparent), transparent 75%);
  transform-origin: 50% 100%;
  animation: bgx-rising-embers-fire 1.8s ease-in-out infinite alternate;
}
.bgx-rising-embers span {
  position: absolute;
  top: 0;
  left: var(--x);
  height: 100%;
  animation: bgx-rising-embers-climb var(--dur) linear var(--delay) infinite;
}
.bgx-rising-embers span::before {
  content: "";
  position: absolute;
  bottom: 0;
  left: 0;
  width: var(--s);
  height: var(--s);
  border-radius: 50%;
  background: color-mix(in srgb, var(--ember), #fff 45%);
  box-shadow: 0 0 calc(var(--s) * 1.6) calc(var(--s) * 0.4) var(--ember);
  opacity: 0;
  animation:
    bgx-rising-embers-zigzag var(--zig) ease-in-out var(--delay) infinite alternate,
    bgx-rising-embers-cool var(--dur) linear var(--delay) infinite;
}
.bgx-rising-embers span:nth-child(1) { --x: 29.3%; --s: 0.17em; --dur: 5.74s; --delay: -1.72s; --zig: 1.37s; }
.bgx-rising-embers span:nth-child(2) { --x: 74.9%; --s: 0.27em; --dur: 3.81s; --delay: -5.65s; --zig: 1.36s; }
.bgx-rising-embers span:nth-child(3) { --x: 62.6%; --s: 0.33em; --dur: 4.15s; --delay: -6.16s; --zig: 1.46s; }
.bgx-rising-embers span:nth-child(4) { --x: 21.3%; --s: 0.16em; --dur: 4.97s; --delay: -3.37s; --zig: 1s; }
.bgx-rising-embers span:nth-child(5) { --x: 6.2%; --s: 0.29em; --dur: 5.29s; --delay: -2.93s; --zig: 1.74s; }
.bgx-rising-embers span:nth-child(6) { --x: 67.4%; --s: 0.24em; --dur: 4.85s; --delay: -6.2s; --zig: 1.07s; }
.bgx-rising-embers span:nth-child(7) { --x: 47.1%; --s: 0.24em; --dur: 5.19s; --delay: -1.36s; --zig: 1.67s; }
.bgx-rising-embers span:nth-child(8) { --x: 70.3%; --s: 0.27em; --dur: 4.19s; --delay: -0.38s; --zig: 1.74s; }
.bgx-rising-embers span:nth-child(9) { --x: 35.5%; --s: 0.35em; --dur: 5.83s; --delay: -0.25s; --zig: 1.69s; }
.bgx-rising-embers span:nth-child(10) { --x: 25.4%; --s: 0.35em; --dur: 4.86s; --delay: -1.72s; --zig: 1.11s; }
.bgx-rising-embers span:nth-child(11) { --x: 93.8%; --s: 0.26em; --dur: 4.91s; --delay: -2.51s; --zig: 1.18s; }
.bgx-rising-embers span:nth-child(12) { --x: 79%; --s: 0.3em; --dur: 5.4s; --delay: -4.27s; --zig: 1.63s; }
.bgx-rising-embers span:nth-child(13) { --x: 43.3%; --s: 0.28em; --dur: 3.86s; --delay: -5.69s; --zig: 1.28s; }
.bgx-rising-embers span:nth-child(14) { --x: 17%; --s: 0.19em; --dur: 4.65s; --delay: -3.51s; --zig: 1.17s; }
.bgx-rising-embers span:nth-child(15) { --x: 56.4%; --s: 0.23em; --dur: 5.62s; --delay: -4.38s; --zig: 0.93s; }
.bgx-rising-embers span:nth-child(16) { --x: 50.7%; --s: 0.19em; --dur: 5.81s; --delay: -5.44s; --zig: 1s; }
.bgx-rising-embers span:nth-child(17) { --x: 83.8%; --s: 0.31em; --dur: 5.21s; --delay: -2.53s; --zig: 0.95s; }
.bgx-rising-embers span:nth-child(18) { --x: 41.1%; --s: 0.23em; --dur: 6.5s; --delay: -6.36s; --zig: 0.89s; }
.bgx-rising-embers span:nth-child(19) { --x: 33.6%; --s: 0.28em; --dur: 5.66s; --delay: -4.35s; --zig: 1.67s; }
.bgx-rising-embers span:nth-child(20) { --x: 60.5%; --s: 0.34em; --dur: 5.56s; --delay: -5.68s; --zig: 0.95s; }
.bgx-rising-embers span:nth-child(21) { --x: 9.7%; --s: 0.32em; --dur: 6.32s; --delay: -2.76s; --zig: 1.52s; }
.bgx-rising-embers span:nth-child(22) { --x: 85.5%; --s: 0.22em; --dur: 4.78s; --delay: -0.18s; --zig: 1.15s; }
.bgx-rising-embers span:nth-child(23) { --x: 91.2%; --s: 0.25em; --dur: 5.86s; --delay: -3.03s; --zig: 1.44s; }
.bgx-rising-embers span:nth-child(24) { --x: 97.1%; --s: 0.32em; --dur: 4.57s; --delay: -6.02s; --zig: 0.98s; }
.bgx-rising-embers span:nth-child(25) { --x: 13.8%; --s: 0.26em; --dur: 4.59s; --delay: -4.79s; --zig: 1.67s; }
.bgx-rising-embers span:nth-child(26) { --x: 1.3%; --s: 0.18em; --dur: 6.08s; --delay: -4.84s; --zig: 0.91s; }
@keyframes bgx-rising-embers-climb {
  from { transform: translateY(0.5em); }
  to   { transform: translateY(-100%); }
}
@keyframes bgx-rising-embers-zigzag {
  from { translate: -0.9em 0; }
  to   { translate: 0.9em 0; }
}
@keyframes bgx-rising-embers-cool {
  0%   { opacity: 0; }
  6%   { opacity: 1; }
  22%  { opacity: 0.6; }
  30%  { opacity: 1; }
  48%  { opacity: 0.7; }
  70%  { opacity: 0; }
  100% { opacity: 0; }
}
@keyframes bgx-rising-embers-fire {
  from { opacity: 0.7; transform: scaleY(0.92); }
  to   { opacity: 1; transform: scaleY(1.06); }
}

@media (prefers-reduced-motion: reduce) {
  .bgx-rising-embers, .bgx-rising-embers *, .bgx-rising-embers::before, .bgx-rising-embers::after, .bgx-rising-embers *::before, .bgx-rising-embers *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

Customizing this snippet

  • Color: set --bgx-color on the element or a parent. Currently previewing #3b82f6.
  • Pattern scale: set --bgx-size. Every other dimension is in em, so the whole thing scales together. Currently previewing 16px.
  • Speed: change the duration on the transition or animation shorthand. Staggered delays are relative, so they keep their rhythm.
  • Reduced motion: the rule at the end of the CSS turns the motion off for people who asked their OS for less of it. Keep it.

Similar animated backgrounds