Drawing a flame with CSS

I accomplished an initial version of this flame in round half-hour and shared it on-line. Then I uploaded it to Instagram, and one thing caught my consideration. Normally, I do not apply filters when sharing CSS artwork (it will be dishonest), however one thing took me to the filters this time. I attempted a number of and located one which made the picture look much less brilliant and extra lifelike, so I modified the preliminary model and up to date the colours to match the filtered model. The end result:

On this article, I’ll describe the method of drawing a flame just like that one with a single HTML aspect. It does not should be the identical (like snowflakes, no two flames are alike.) It’s extra of a log of what I did. In case you draw it, you possibly can change the values and make it completely different and your individual.

Additionally, the article is a bit lengthy as a result of I clarify the completely different properties used and why. Simply copy the code and see it stay if you wish to draw one thing quick.

Preliminary form

To begin with, we’d like the one HTML aspect:

<div class="flame"></div>
Enter fullscreen mode

Exit fullscreen mode

Then we have to make it appear like a flame. I opted for a drop form. It is probably not good, nevertheless it made for an simply completely different form. One thing that folks affiliate with a flame.

To create a drop, I drew a sq., utilized a border-radius of 0 on one nook and 100% on the remainder, after which tilted the aspect accordingly utilizing a transform with rotate():

.flame {
  /* set the scale of the flame aspect */
  width: 40vmin;
  /* make it sq. */
  aspect-ratio: 1;
  /* give it a drop/tear form */
  border-radius: 2% 87% 45% 85%;
  /* place it on the middle of the display */
  place: absolute;
  prime: 50%;
  left: 50%;
  /* actually within the middle + tilt clockwise*/
  remodel: translate(-50%, -50%) rotate(45deg);
  /* non permanent for demo, so the form is seen */
  background: crimson;
Enter fullscreen mode

Exit fullscreen mode

You may play with the border-radius values to keep away from making it too symmetrical. Be happy to vary them to one thing that you just like higher. For instance, I modified it to 2% 87% 45% 85% (and much more after I added an animation.)

Additionally, let’s add a bit bit of favor to the physique, so it is not all white. Only a darkish background. You could possibly make it black. I favor to do one thing barely softer, so the drawing will likely be smoother later:

physique {
  background: #251c27;
Enter fullscreen mode

Exit fullscreen mode

The gradients

You have got seen a flame or a burning match earlier than, and you recognize that it isn’t how most individuals draw them. It isn’t a flat coloration factor or a mixture of three completely different colours yellow, orange, and crimson.

Actual flames aren’t yellow.

It’s a transition of colours from white to orange to black, with some blue across the edges. And transitions like that imply gradients. Both by utilizing the precise gradients as backgrounds or utilizing box shadows.

In CSS, the gradients are “prioritized” from prime to backside. Which means the primary one on the record will likely be on the prime of all of the others. I added 4 gradients and a brand new base coloration (gentle yellow):

  • A radial gradient backside to prime, from a slightly-transparent darkish coloration (nearly black) to totally clear.
  • One other radial gradient from the underside, from a slightly-transparent darkish coloration to totally clear.
  • One more radial gradient from the underside, this time from yellow to orange to a semi-transparent yellow.
  • A linear gradient that goes from white to semi-transparent yellow will function the flame base.

It’s possible you’ll ask: why three radial gradients for nearly the identical factor? The trick is altering their sizes, positioning, and percentages barely, so combining the three creates one thing utterly completely different that would not be achievable with only a single radial gradient. I used three, however I may have completed many extra to make it extra lifelike. Or, to make the drawing extra cartoony, restrict it to at least one gradient and have sharper edges.

Keep in mind: the flame is tilted 45 levels! Which means the underside of the flame is the underside proper nook of the HTML aspect!

I picked mushy colours after wanting on the picture instructed by the Instagram filter. Initially, I had more vibrant colors. However you possibly can give you whichever colours you need: make your drawing distinctive! Yellow flame? Inexperienced flame? Blue flame? All of them sound good.

Let’s substitute the non permanent background that we added within the earlier step with these gradients:

.flame {
  /* ... */
    radial-gradient(100% 100% at 90% 90%, #251c27, #251c2733 20%, #251c2700 50%),
    radial-gradient(farthest-side at 110% 120%, #251c27, #631, #cb6c3b88, #0000),
    radial-gradient(at 100% 100%, #fc08, #cb6c3b, #eebd7600 60%),
    linear-gradient(135deg, #fff0 20%, #ff0),
Enter fullscreen mode

Exit fullscreen mode

The shadows

At this level, we’ve one thing that resembles a flame, nevertheless it appears too sharp. In case you have a look at the photographs from the screenshot above, you may discover that fireside even have a mushy glow. We are able to add it utilizing the box-shadow property.

We may have extra shadows than gradients as a result of we’re going to apply them each inside and outdoors the flame. Inside to provide some tone, Outdoors to create a glowing impact.

As with the gradients, we have to take into account that shadows are stacked from prime to backside: the primary shadow will likely be on prime and will disguise elements of the box-shadow beneath. Utilizing semi-transparent colors, we will create some distinctive experiences for the flame.

The shadows that I added are:

  • On the within:
    • orange/crimson shadow from the highest (to make it softer and extra lifelike.)
    • blue shadow from the underside (to make it extra lifelike.)
    • orange/yellow shadows surrounding the true flame (to provide it extra “glow.”)
  • On the skin:
    • a yellow/orange shadow surrounds the flame however tends to go up (to make it blurrier.)
    • a darkish semi-transparent shadow round the entire flame (to make it extra lifelike.)
    • An enormous orange-yellowish shadow (which would be the flame’s gentle.)

Once more, I used a bunch of shadows for this (see the code beneath), however you should utilize as little as none or as many as you need till you obtain the outcomes you need.

.flame {
  /* ... */
    inset 2vmin 2vmin 2vmin -1.5vmin #f808,
    inset  -1vmin -1vmin 5vmin -3vmin #00f7,
    inset  0vmin  -1vmin 5vmin -3vmin #00f8,
    inset  -1vmin -1vmin 2vmin -2vmin #251c27,
    inset  -1vmin -1vmin 3vmin -1vmin #251c27,
    inset  -1vmin -1vmin 2vmin #fc08,
    -0.5vmin -0.5vmin 1vmin #ff08,
    -1vmin -1vmin 2vmin #ce8c47,
    -2vmin -2vmin 10vmin 1vmin #251c27,
    -6vmin -6vmin 35vmin 3vmin #fa06
Enter fullscreen mode

Exit fullscreen mode

Keep in mind: the flame is tilted! The underside of the flame is the underside proper nook of the HTML aspect. Take that into consideration when including the shadows!


For this drawing, I simply added a easy blur filter to contribute to the flame glow and make the picture much less sharp general:

.flame {
  /* ... */
  filter: blur(0.1vmin);
Enter fullscreen mode

Exit fullscreen mode

It’s only a tiny blur as a result of it’ll affect the pseudo-elements too. And whereas we would like the flame to look barely blurry, we won’t say the identical factor about the remainder, as I clarify within the following part.

The pseudo-elements

I used the pseudo-elements ::before and ::after to attract the match in itself, with ::before, I did the match stick (a rectangle), and with ::after, I did the match head.

Initially, I had the scale and place of those pseudo-elements in percentages, however that become an issue after I animated the flame (as a result of I animated the width and top, after which the match modified dimension and form.) So I set a static width and place for the weather to keep away from this downside. In consequence, the match appears to remain in the identical place whereas the hearth strikes with the animation.

Then, I added some shadows and gradients to the match itself. That approach, I may make it look a bit extra lifelike or extra lifelike for a cartoon.

The ::earlier than pseudo-element is the picket stick of the match. One thing simple and easy: a rectangle that begins lighter in coloration on prime and goes darker because it will get away from the flame. Nothing particularly fancy right here:

.flame::earlier than {
  content material: "";
  show: block;
  width: 20vmin;
  top: 3vmin;
  background: linear-gradient(to proper, #d605, #321, #251c27);
  prime: 37vmin;
  left: 37vmin;
  place: absolute;
  remodel: translate(-50%, -50%) rotate(45deg);
  box-shadow: 0 0 5vmin 3vmin #251c27aa, inset -1vmin 0 1.5vmin #251c27aa
Enter fullscreen mode

Exit fullscreen mode

Keep in mind: as with the flame gradients, we should keep in mind that the HTML aspect is tilted 45 levels, so we have to take into account this when positioning and remodeling the pseudo-elements.

The ::after is the match’s head. It’s trickier to attract (however not a lot): rounded on prime and flatter on the backside. It is going to even have completely different colours: yellow/white nearer to the flame and crimson phosphorus on the backside.

Plus, this pseudo-element will help with the flames coloration. Keep in mind that it’s darker/black on the middle of the flame… which occurs to be on the match head. A box-shadow will assist with that:

.flame::after {
  content material: "";
  show: block;
  width: 6vmin;
  top: 5vmin;
    linear-gradient(45deg, #f002, #fff0),
    linear-gradient(to proper, #d68356, #e5653e 3%, #d0363b 20%, #251c27);
  prime: 32vmin;
  left: 32vmin;
  border-radius: 100% / 120% 80% 80% 120%;
  place: absolute;
  remodel: translate(-50%, -50%) rotate(45deg);
  box-shadow: 0 0 5vmin 3vmin #251c27aa, inset -1vmin 0 1.5vmin #251c27;
Enter fullscreen mode

Exit fullscreen mode

Animating the flame

An essential message earlier than we begin animating the flame: this isn’t a performant kind of animation. It adjustments values just like the border-radius, width, or top, which aren’t good properties to animate and will make the pc battle a bit.

As soon as that is mentioned, the animation goes to include:

  • altering the border-radius values
  • updating the width of the flame

These adjustments will give the flame a flickering sensation that we may enhance by updating colours or the worth of the blur.

@keyframes burn {
  0%, 100% { border-radius: 5% 87% 45% 85%; width: 30vmin; }
  10% { border-radius: 5% 85% 49% 82%; }
  20% { border-radius: 0% 85% 45% 87%; width: 31vmin; }
  30%, 90% { border-radius: 5% 85% 49% 82%; }
  40% { border-radius: 0% 85% 45% 87%; width: 32vmin; }
  50% { border-radius: 2% 87% 42% 90%; }
  60% { border-radius: 5% 97% 45% 88%; }
  70% { border-radius: 2% 87% 42% 90%; width: 31vmin}
  80% { border-radius: 5% 97% 45% 88%; }

.flame {
  /* ... */
  animation: burn 4s infinite;
Enter fullscreen mode

Exit fullscreen mode


Final however not least, let’s do one thing to enhance accessibility. We’ve got a drawing of a flame, and it appears nice, however would not or not it’s even better if it was extra accessible to everyone?

We are able to do it by making use of a few easy adjustments to the HTML:

  • Including a position that may assist announce the drawing as an image to display readers.
  • Including an aria-label describing our drawing.
<div class="flame" position="img" aria-label="Cartoon of a flame coded in CSS"></div>
Enter fullscreen mode

Exit fullscreen mode

With these two adjustments, when a display reader reaches our flame, it’ll announce one thing like “Cartoon of a flame coded in CSS. Picture.” which will likely be useful for display reader customers to grasp what’s on the display. Additionally, it could be one thing to contemplate if you happen to do CSS artwork (more about Accessibility in CSS Art in this other article.)


This publish just isn’t too sensible from an internet growth perspective (as some folks will rapidly level out within the remark part and on Twitter, most likely with out studying the entire article and this paragraph.) But it surely may have a excessive instructional worth.

It helps get acquainted with gradients (at the very least two: linear and radial), box-shadows, some filters and transforms, and many others., combining every part with completely different colours and transparencies.

As talked about above, not two flames are alike, after which you may get to play with the values of gradients, shadows, and filters to get your distinctive model of the flame.

Add a Comment

Your email address will not be published. Required fields are marked *