30 CSS Keyframe Animations 15 / 30

CSS Fire Animation Pure CSS

Pure CSS fire: flickering candle with wick and wax, campfire with log base and IGNITE flame text — radial gradient bodies animated with scale and blur keyframes.

Pure CSS MIT licensed
Live Demo Open in tab

This is a full-page demo — interact inside the frame above, or open it in the playground for the full-screen experience.

Open in playground

The code

<div class="kf-15">
  <div class="kf-15__text">IGNITE</div>
  <div class="kf-15__row">
    <div>
      <div class="kf-15__candle">
        <div class="kf-15__flame-wrap">
          <div class="kf-15__flame kf-15__f1"></div>
          <div class="kf-15__flame kf-15__f2"></div>
          <div class="kf-15__flame kf-15__f3"></div>
          <div class="kf-15__glow"></div>
        </div>
        <div class="kf-15__wick"></div>
        <div class="kf-15__wax"></div>
      </div>
      <div class="kf-15__label">Candle</div>
    </div>
    <div>
      <div class="kf-15__camp">
        <div class="kf-15__camp-flame">
          <div class="kf-15__cf kf-15__cf--5"></div>
          <div class="kf-15__cf kf-15__cf--4"></div>
          <div class="kf-15__cf kf-15__cf--1"></div>
          <div class="kf-15__cf kf-15__cf--2"></div>
          <div class="kf-15__cf kf-15__cf--3"></div>
        </div>
        <div class="kf-15__logs">
          <div class="kf-15__log"></div>
          <div class="kf-15__log"></div>
          <div class="kf-15__log"></div>
        </div>
      </div>
      <div class="kf-15__label">Campfire</div>
    </div>
  </div>
</div>
@import url('https://fonts.googleapis.com/css2?family=Black+Ops+One&family=Roboto+Mono:wght@500&display=swap');
.kf-15,.kf-15 *,.kf-15 *::before,.kf-15 *::after{box-sizing:border-box;margin:0;padding:0}
.kf-15 ::selection{background:#ff4500;color:#fff}
.kf-15{
  --bg:#0d0800;
  --flame1:#ff4500;
  --flame2:#ff8c00;
  --flame3:#ffd700;
  --flame4:#fff5c0;
  font-family:'Black Ops One',sans-serif;
  background:radial-gradient(circle at 50% 80%,#1a0800 0%,#0d0800 60%);
  min-height:100vh;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  padding:60px 24px;gap:60px;
  overflow:hidden;
  position:relative;
  color:#ffd700;
}
/* ember particles */
.kf-15::before{
  content:'';position:absolute;inset:0;pointer-events:none;
  background-image:
    radial-gradient(1px 1px at 20% 40%,rgba(255,69,0,.8),transparent),
    radial-gradient(1px 1px at 60% 20%,rgba(255,140,0,.6),transparent),
    radial-gradient(1.5px 1.5px at 80% 50%,rgba(255,215,0,.5),transparent);
  animation:kf-15-ember 3s linear infinite;
}
@keyframes kf-15-ember{to{background-position:0 -200px;opacity:0}}

/* ——— Candle flame ——— */
.kf-15__candle{display:flex;flex-direction:column;align-items:center;gap:0}
.kf-15__flame-wrap{position:relative;width:60px;height:100px;display:flex;justify-content:center;align-items:flex-end}
.kf-15__flame{
  position:absolute;bottom:0;
  border-radius:50% 50% 20% 20%/60% 60% 40% 40%;
  filter:blur(1px);
  transform-origin:50% 100%;
}
.kf-15__f1{width:28px;height:80px;background:linear-gradient(180deg,var(--flame4) 0%,var(--flame3) 30%,var(--flame2) 65%,var(--flame1) 100%);animation:kf-15-flicker 0.8s ease-in-out infinite}
.kf-15__f2{width:22px;height:64px;background:linear-gradient(180deg,#fff 0%,var(--flame4) 30%,var(--flame3) 70%,transparent 100%);animation:kf-15-flicker 0.6s ease-in-out infinite reverse}
.kf-15__f3{width:14px;height:48px;background:linear-gradient(180deg,#fff 0%,rgba(255,245,192,.8) 50%,transparent 100%);animation:kf-15-flicker 0.9s ease-in-out infinite 0.2s}
@keyframes kf-15-flicker{
  0%,100%{transform:scaleX(1) scaleY(1) rotate(-2deg)}
  25%{transform:scaleX(0.88) scaleY(1.06) rotate(2deg)}
  50%{transform:scaleX(1.05) scaleY(0.96) rotate(-1deg)}
  75%{transform:scaleX(0.92) scaleY(1.04) rotate(1.5deg)}
}
.kf-15__wick{width:3px;height:14px;background:linear-gradient(180deg,#333,#888);margin-top:0;z-index:2;position:relative}
.kf-15__wax{width:50px;height:100px;background:linear-gradient(90deg,#f0ebe0,#e8e0d0 50%,#d8d0c0);border-radius:4px;position:relative;display:flex;justify-content:center}
.kf-15__wax::before{content:'';position:absolute;top:0;left:50%;transform:translateX(-50%);width:30px;height:8px;border-radius:50%;background:rgba(255,220,180,.4);animation:kf-15-melt 3s ease-in-out infinite}
@keyframes kf-15-melt{50%{transform:translateX(-50%) scaleX(1.1);background:rgba(255,200,150,.3)}}
.kf-15__glow{position:absolute;bottom:0;left:50%;transform:translateX(-50%);width:80px;height:40px;background:radial-gradient(ellipse,rgba(255,140,0,.3),transparent);filter:blur(8px);animation:kf-15-glow 0.8s ease-in-out infinite alternate}
@keyframes kf-15-glow{to{opacity:.6;transform:translateX(-50%) scale(1.2)}}

/* ——— Campfire ——— */
.kf-15__camp{display:flex;flex-direction:column;align-items:center;gap:0}
.kf-15__logs{width:120px;height:24px;position:relative}
.kf-15__log{position:absolute;width:80px;height:12px;border-radius:6px;background:linear-gradient(180deg,#5a3a1a,#3a2010)}
.kf-15__log:nth-child(1){bottom:0;left:20px}
.kf-15__log:nth-child(2){bottom:0;left:20px;transform:rotate(40deg);transform-origin:40% 50%}
.kf-15__log:nth-child(3){bottom:0;left:20px;transform:rotate(-40deg);transform-origin:60% 50%}
.kf-15__camp-flame{position:relative;width:120px;height:120px;display:flex;justify-content:center;align-items:flex-end}
.kf-15__cf{
  position:absolute;bottom:0;
  border-radius:50% 50% 20% 20%/60% 60% 40% 40%;
  transform-origin:50% 100%;
  filter:blur(2px);
}
.kf-15__cf--1{width:60px;height:100px;background:linear-gradient(180deg,var(--flame4),var(--flame3) 30%,var(--flame2) 65%,var(--flame1));animation:kf-15-flicker 1.1s ease-in-out infinite}
.kf-15__cf--2{width:44px;height:82px;background:linear-gradient(180deg,#fff,var(--flame4) 30%,var(--flame3) 70%,transparent);animation:kf-15-flicker 0.7s ease-in-out infinite 0.1s}
.kf-15__cf--3{width:28px;height:60px;background:linear-gradient(180deg,#fff,rgba(255,245,192,.9),transparent);animation:kf-15-flicker 0.9s ease-in-out infinite 0.3s}
.kf-15__cf--4{width:70px;height:60px;left:0;right:0;margin:0 auto;background:linear-gradient(180deg,transparent,var(--flame1) 50%,transparent);animation:kf-15-flicker 1.3s ease-in-out infinite;filter:blur(3px)}
.kf-15__cf--5{width:50px;height:40px;left:0;right:0;margin:0 auto;background:var(--flame2);border-radius:50%;bottom:0;animation:kf-15-flicker 0.6s ease-in-out infinite 0.4s;filter:blur(4px)}

/* ——— Torch text ——— */
.kf-15__text{
  font-size:clamp(2.5rem,10vw,5rem);
  letter-spacing:.1em;
  color:var(--flame2);
  text-shadow:
    0 0 10px var(--flame1),
    0 0 30px var(--flame2),
    0 0 60px rgba(255,140,0,.4);
  animation:kf-15-text 2s ease-in-out infinite alternate;
  position:relative;
}
@keyframes kf-15-text{
  from{text-shadow:0 0 10px var(--flame1),0 0 30px var(--flame2),0 0 60px rgba(255,140,0,.4)}
  to{text-shadow:0 0 15px var(--flame3),0 0 40px var(--flame3),0 0 80px rgba(255,200,0,.5),0 0 120px rgba(255,140,0,.3)}
}

.kf-15__row{display:flex;gap:60px;flex-wrap:wrap;justify-content:center;align-items:flex-end}
.kf-15__label{font-family:'Roboto Mono';font-size:.7rem;letter-spacing:.15em;text-transform:uppercase;color:rgba(255,140,0,.4);text-align:center;margin-top:12px}

@media(prefers-reduced-motion:reduce){.kf-15 *{animation:none!important}}

How this works

The candle flame stacks three nested divs with border-radius: 50% 50% 20% 20% / 60% 60% 40% 40% — that flame-drop shape — gradiated from white-hot tip to deep red base. Each layer runs kf-15-flicker at slightly different durations (0.6s, 0.8s, 0.9s) with offset delays, so they never sync and the flame appears to writhe organically. A 1px filter: blur softens the edges.

The flicker keyframe combines scaleX, scaleY, and small rotate at four stops to mimic combustion turbulence. The IGNITE headline uses layered text-shadow with ease-in-out alternate on a 2s cycle, swelling the glow without flickering. Embers in the background are radial-gradient dots inside ::before, animated via background-position shift for a slow upward drift.

Customize

  • Recolour the flame palette via --flame1 (red base) through --flame4 (white tip) custom properties.
  • Slow the flicker by changing kf-15-flicker duration from 0.8s to 1.4s for a calmer flame.
  • Adjust the campfire scale by editing the widths and heights of .kf-15__cf--1 through --5 in proportion.
  • Soften flame edges further with filter: blur(2px) instead of 1px for a hazier look.
  • Modify the ember density by adding more radial-gradient stops in the .kf-15::before background-image.

Watch out for

  • Multiple filter: blur() layers stack on the GPU — the campfire's five flame elements with blur can drop frames on mid-tier laptops.
  • transform-origin: 50% 100% is critical on the flame layers; without it the scale animation pivots from center and the flame appears to detach from the wick.
  • The ember background-position animation is decorative — older Safari sometimes pauses background animations when the parent is off-screen.

Browser support

ChromeSafariFirefoxEdge
60+ 12+ 60+ 60+

Search CodeFronts

Loading…