Creating an animated SVG Neon light effect

Full Tutorial — From Illustrator to Sketch to SVG

Nils Binder
Jul 25, 2018 · 10 min read
Look here, to see the animation in action. And yeahh this one right here is a GIF… 1.5MB, I know, not a good solution :-)

We at 9elements organize an annual JavaScript conference called RuhrJS. The key visual shows a shaft tower and the conference name executed with a neon light effect. The main page features the full visual with flickering lights. This effect is created by using a video loop in the background. Our visual designer (Tommi Gutscher) also created some lovely images for all the sections on the website. So when the website was built, our frontend developer asked me to export some transparent .png files for her, so she can insert them in the header region.

I took a look at the files and saw that a lot of blur and shadow effects were used to create the neon light effect. To export a transparent file my first attempt was the good old:
cmd+shift+c copy merged
cmd+n create new file
cmd+v paste from clipboard
cmd+option+shift+s export for web
(pretty old school I know).

When exported as transparent png, filesize is about 80KB

The resulting image was about 80KB large and not crisp on my high-resolution MacBook. Also, 80KB are a hell lot of bytes, especially when you’re at the conference and want to look up the schedule on a poor data plan. Somehow while doing all this, I had a strange feeling. It all felt like being thrown back about ten years.

Switching to SVG

The original Vector Illustrations done for the Header images.

I don’t want to keep you on tenterhooks. The final result is about 10KB in file size, crisp on every resolution and on top of that, it’s also animated. To me, this seems much better and up do date.

Final Result

Step by step walktrough

If you’re a graphic designer and afraid of code (psssst… don’t be), it may still be interesting for you to at least read part one, because you will learn some things, your developer is going to love you for.

Part one: Graphic Design

1.1 From Illustrator to Sketch

1.2 Deleting unused clipping masks

1.3 Name and combine your layers

Now it’s time to think about the final image and you have to decide which elements will be animated. I chose to only animate the capital letters and the Ampersand. The other elements don’t necessarily have to be a single layer and can be combined to one shape. Again, this makes it easier when we export the file as SVG. In this example, I combined o, cation, i-dot, and n so that I have a single layer that can be named ocation. My preferred way to do the combining is by simply dragging one layer onto another.

Finally, you have a very organized and neatly named layer list, that impatiently waits for some glow effects. Mine looks like this. I could have gone further and also combine chedule and ocation into a single layer, but I kept them for better readability.

1.4 Adding some glow

Here, you can see the settings I used for the glow effect
Resize the Artboard to make sure, that the whole shadow is visible. I used a dark background to better see the effect in place, but make sure you don’t export it.

Now everything is ready to be exported as SVG. Select the Artboard, hit make exportable, choose SVG and click on export.

Hip hip hurray…part one is done. Now it’s time to leave Sketch and open your preferred text-editor.

Part Two: Frontend Development

2.1 Understanding the main SVG structure

So what is going on here? When you take a look at the <defs> area, you’ll see that there is a repeating pattern with a <path> and a <filter> element. Further down you’ll find another repeating pattern that contains a group (<g>) with two <use> Tags inside.

The elements inside the <defs> tag will not be rendered on the SVG-canvas. Paths and filters are defined in this section, so that they can be referenced from within the <use> tags.

In every <g> the same path is linked in both <use> tags (xlink:href="#path-1"). The first one is responsible for the glow. It is filled black and gets a filter attribute that links to a <filter> already specified in the <defs> section (filter="url(#filter-2)"). The second one is placed on top without any filter, but filled in white (fill="#FFFFFF"). Without it, you’d only see the blur but not the actual form. Maybe this sounds a little confusing, but I think when you look at the simplified code above, you will understand what is going on.

2.2 Getting comfortable with the filters

Every shadow we applied in Sketch is built with three SVG filters that are combined. First there is the offset <feOffset>, then the result gets blurred <feGaussianBlur> and finally the blurred result is given a color via <feColorMatrix>. In the end, the four shadows are merged — this happens in the <feMerge> section. If you are not completely happy with the final glow effect, you can try editing the shadows directly inside the SVG instead of going back to Sketch. The stdDeviation attribute, for example, handles the blur amount while dx and dy are responsible for the x and y offset. You can also try to change the values inside the ColorMatrix, but this one is not really self-explanatory 😅.

2.3 Optimizing your SVG

When you compare the defined filters, you’ll see, that they are 99% the same. So let’s try and see, what happens when we use the same filter on all <use> tags. Like this:

The image still looks the same, with the same filter applied to all paths. And this is exactly what we want.

Now all the other filters that are not used anymore can be deleted. And the <defs> section will look nicely structured:

<filter ...>
<path ...>
<path ...>
<path ...>
<path ...>
<path ...>

One final word on filters: When you export filters from Sketch, the width, height, x and y attributes of the filter get some values that don’t really make sense to me. First of all, we can change the filterUnits value from objectBoundingBox to userSpaceOnUse. The filter coordinates are now calculated from the top left of the whole SVG and not from the object that uses the filter. Now we can set the width and height to 100% and the starting x and y attributes to zero.

<filter id="glow" width="100%" height="100%" x="0" y="0" filterUnits="userSpaceOnUse">

In the end, I named the filter “glow” instead of “filter-2” to make it a bit more readable. You could also rename the paths, but having the IDs in the groups was enough for me. The only thing I did was correcting the numbers of the paths so that you have nice ascending numbers.

Of course, you can (and should) use something like SVGOMG to further reduce file size. But be careful and don’t use the Clean IDs option. This will rename all your IDs to single character names and then it will be very hard to read. With accessibility in mind I’d also recommend to leave the <title> in place and write something meaningful in there.

Here you can see the final code of the static SVG:

2.4 Adding animation

The keyframe animation is quite simple. All you have to do is switch the opacity from something like 0.4 to 1. We want to create the effect of an old neon sign, that flickers from time to time. To achieve this, simply insert a lot of steps from 0% to 10% and then a pause to 100%:

@keyframes flicker {
0% { opacity: 1; }
3% { opacity: 0.4; }
6% { opacity: 1; }
7% { opacity: 0.4; }
8% { opacity: 1; }
9% { opacity: 0.4; }
10% { opacity: 1; }
100% { opacity: 1; }

Once this is defined, you can use it on every element you want to animate. Let’s say we want to use the defined flicker animation, and we want it to have a duration of 6 seconds. The whole animation should be played in an infinite loop and in order to mimic a flickering neon light, we don’t want to ease between the steps, but “jump” directly from one state to the next. Sounds complicated, but it is actually just one line of CSS:

#L { 
animation: flicker 6s infinite step-end;

For the & I chose a duration of 5 seconds and added a delay of 2 seconds. With the two different duration timings, the whole animation looks a little more random and natural.

#et { 
animation: flicker 5s infinite 2s step-end;

Well and that’s it. Our animated neon sign SVG is ready. Here you can see the full code.

Over to you: I hope this tutorial has been useful and I’d certainly love to see some of your results.

If you’ve enjoyed this piece and would like to see more, you might want to check out our Website, follow us on Twitter or subscribe to our Newsletter.

Edit 07.Aug 2018

hoorahforsnakes improved my pen by adding another keyframe animation and applying it to the glow component inside the letter groups. The opacity in this animation is set to 0 and not only to 0.4. Looks a little more realistic, because there is no glow visible during the flickering.

Originally published at on July 25, 2018.


We craft digital products and services.