Inline SVGs without Trashing your Markup

inline svgs without trashing your markup

Blaze |

CSS |

Meteor |

SVGs |

SVGs are awesome, but if you want to get the most out of them, they should be used inline. Here’s one way to insert inline SVGs that’s not a huge hassle.

SVGs Are Great

We’re not going to spend a lot of time on the nitty-gritty details, but here’s a short, non-exhaustive list of the reasons we love SVG:

  • They scale without losing sharpness.
  • They’re tiny.
  • You can use CSS on them.

In our opinion, you should be using SVGs for any sort of vector art, rather than exporting to JPG, PNG, or the like. That said, there is one challenge with using SVGs: they’re really best if you inline them in your document, but that can make your markup a huge mess.

We’d like to offer one solution to this issue.

Starting Most Generally

The first thing we want to do is create a few SVGs. In this case, a circle and a triangle. In each case, we made them in Illustrator and exported them with the Export for Screens tool. Next, we stripped out some extraneous stuff like data-name and the element’s title. We also strip out any id or class attributes.

Here are the two SVGs we’re going to work with:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50">polygon points="24.9 0 0 50.5 49.8 50.5 24.9 0"</svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50">circle cx="25" cy="25" r="25"</svg>

Object Lesson

Next, we’re going to create a standalone Javascript file, cleverly called svgs.js and create an object to hold these SVGs. Then we’ll export that object for use in whatever file references it.

const svgs = {
    triangle: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50">polygon points="24.9 0 0 50.5 49.8 50.5 24.9 0"<svg>',
    circle: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50">circle cx="25" cy="25" r="25"<svg>'
}

export default svgs;

If you only have a couple SVGs, you could put this object in the same file as the function we’re about to write, but our assumption is that you’ll have lots of these things.

Now What?

Now we’re going to write a function that uses that object to spit out an SVG for us. For the purposes of customization, we want to also be able to assign a custom ID or class, so we’re going to do a little string manipulation, replacing the opening <svg with our custom id and class (if they exist).

import svgs from "svgs";

function insertSvg(type, svgId = "", svgClass = "") {
    const svg = svgs[type].replace("<svg", `<svg id="${svgId}" class="${svgClass}"`);
    return svg;
}

Now any time we want to insert an SVG, we can just use this handy function. Of course, this gets even easier if you build it straight into your templating system. Speaking of…

Blaze

These days, many of our project use Meteor and Meteor’s Blaze template library. In our use case, we’d create a global template helper that used the above function to return our SVG. Here’s what that would look like:

Template.registerHelper( 'svgHelper', ( type, svgId, svgClass ) => {
  return insertSvg(type, svgId, svgClass);
});

For the final step, any time we needed to insert an svg, we’d just do {{svgHelper "circle" "myCircle" "red"}} and we’d get the following in our page:

<svg id="myCircle" class="red" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50">polygon points="24.9 0 0 50.5 49.8 50.5 24.9 0"<svg>

Codepen

As usual, we’ve included a Codepen so you can see how it works in action. Thanks for reading!

See the Pen Inlining SVG by Adrian Bettridge-Wiese (@arbw) on CodePen.

For Further Reading

Interested in learning more about SVGs? Here are some great resources:

Share and enjoy!