Create a Realistic Candle Animation with HTML CSS

Want to light up your web design with a unique visual element? In this tutorial, you’ll learn how to create a realistic candle animation using HTML and CSS only — no JavaScript, no images and no libraries.

This component is perfect if you’re working on:

  • Creative web pages
  • Halloween themes
  • Ambient loading screens
  • Custom UI decoration elements

We’ll build the candle from scratch, applying CSS animations, gradients, pseudo-elements and keyframes to simulate a flickering flame, glow and wax.

By the end, you’ll have a fully responsive candle animation that adds a warm, dynamic visual to any modern website.

HTML Structure of the Candle Animation

The candle consists of several stacked divs, each representing a specific part of the flame or wax structure.

<div class="main-container">
    <div class="candle">
        <div class="top">
            <div class="glow"></div>
            <div class="flame"></div>
            <div class="blue-part"></div>
            <div class="thread"></div>
        </div>
        <div class="wax"></div>
        <div class="candle-bottom"></div>
    </div>
</div>
  • .main-container: Centers the candle on screen.
  • .candle: The main candle body.
  • .top: Contains all elements that make up the flame area.
  • .glow, .flame, .blue-part, .thread: Different flame components.
  • .wax: The main candle body.
  • .candle-bottom: Decorative candle base.

Styling the Candle with CSS

We apply gradients, positioning and animation to bring each part of the candle to life.

.main-container {
    display: flex;
    min-height: 100vh;
    min-width: 250px;
    align-items: center;
    justify-content: center;
}

.candle {
    width: 120px;
    height: 385px;
    position: relative;
    display: grid;
}

.top {
    display: flex;
    height: 120px;
    position: relative;
    justify-content: center;
}

.top div{
    position: absolute;   
}

.glow {
    border-radius: 100%;
    width: 70px;
    filter: blur(35px);
    background: #ff6000;
    height: 130px;
    bottom: 0;
    z-index: 2;
    animation: flicker_animation .1s infinite;
}

.flame {
    bottom: 10px;
    z-index: 3;
    width: 18px;
    transform-origin: bottom;
    border-radius: 50% 50% 20% 20%;
    box-shadow: 0px -5px 7px 0px orange;
    background: linear-gradient(white 70%, transparent);
    animation: flame_animation 4s linear infinite, grow_flame 4s linear infinite;
}

.blue-part {
    width: 20px;
    height: 45px;
    background: rgba(0, 133, 255, .7);
    z-index: 2;
    bottom: 5px;
    border-radius: 50% 50% 40% 40%;
}

.thread::after,
.blue-part::after,
.wax::before {
    content: '';
    display: block;
}

.blue-part::after {
    width: 75%;
    border-radius: 50%;
    background: rgb(0 0 0 / 39%);
    position: relative;
    height: 70%;
    margin: 0 auto;
    top: 30%;
}

.thread {
    width: 5px;
    height: 25px;
    margin: 0 auto;
    border-radius: 40% 40% 0 0;
    background: linear-gradient(#ff7800, black 40%);
    bottom: 0;
    z-index: 2;
}

.thread::after {
    width: 100%;
    height: 30%;
    top: 70%;
    position: absolute;
    background: linear-gradient(0deg, #898989, #000000);
}

.wax {
    width: 100%;
    bottom: 15px;
    height: 250px;
    z-index: 1;
    position: absolute;
    background: linear-gradient(180deg, #a7a2a2, #212121);
    box-shadow: inset 20px -30px 50px 0 rgba(0, 0, 0, 0.4), inset -20px 0px 50px 0 rgba(0, 0, 0, 0.4);
}

.wax::before {
    width: 100%;
    height: 10%;
    bottom: 95%;
    position: absolute;
    border-radius: 50%;
    background: radial-gradient(#d1c3ac, #6f6f6f 46%, #817e7c 67%);
}

.candle-bottom {
    bottom: 0;
    position: absolute;
    justify-self: center;
    height: 30px;
    width: 150px;
    border-radius: 50%;
    background: radial-gradient(#121212, #101010);
}

@keyframes flicker_animation {
    50% {
        opacity: 0.8;
    }
}

@keyframes flame_animation {

    0%,
    100% {
        transform: rotate(-2deg);
    }

    50% {
        transform: rotate(2deg);

    }
}

@keyframes grow_flame {

    0%,
    100% {
        height: 85%;
    }

    50% {
        height: 100%;
    }

}

This is where things get exciting. We use @keyframes to mimic the natural flicker and movement of a flame.

  • flicker_animation: Simulates subtle light flickering.
  • flame_animation: Tilts the flame left and right.
  • grow_flame: Slightly varies flame height to mimic real fire behavior.

These three animations combined produce a visually realistic flickering candle flame, making this one of the most unique CSS-only animations you can embed.

This animated candle is not just a fun UI trick — it’s a great example of advanced CSS animation techniques, including:

  • Layering with pseudo-elements
  • Animating shape and opacity
  • Crafting glow effects with blur and gradients

Customization Tips

Want to modify the look?

  • Change flame color: Adjust background and box-shadow in .flame and .glow.
  • Speed up the flicker: Tweak the duration in flicker_animation.
  • Resize the candle: Update .candle width/height and scale other elements.
  • Make it a frozen candle: Replace warm gradients with icy blues!

Conclusion

In this post, you learned how to create a candle animation using only HTML and CSS. With the clever use of gradients, blur effects and keyframe animations, you can simulate a glowing, flickering flame that looks remarkably real.

This component not only adds creative visual interest but also showcases how powerful and flexible CSS can be for building animated UI elements.

Feel free to tweak the styles, add new elements like melted wax drips or smoke trails or integrate this flame into your existing UI kit.

No JavaScript. No dependencies. Just pure CSS creativity.

Happy coding and keep your UI glowing!

Leave a Comment

Scroll to Top