Icon System with SVG Sprites | CSS-Tricks (2024)

I’ve been a big proponent of icon fonts. Lots of sites really need a system for icons, and icon fonts offer a damn fine system. However, I think assuming you’re good with IE 9+, using inline SVG and the <use> element to reference an icon is a superior system.

First let’s cover how it works.

A nice way to handle your icons is to have a folder full of .svg files.

Icon System with SVG Sprites | CSS-Tricks (1)

They can be colored, not colored, multiple shapes, sizes, whatever.

Icon System with SVG Sprites | CSS-Tricks (2)

You can let Illustrator (or whatever) save it however, with all the cruft that comes along for the ride:

<?xml version="1.0" encoding="utf-8"?><!-- Generator: Adobe Illustrator 16.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) --><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="100px" height="100px" viewBox="0 0 100 100" enable-background="new 0 0 100 100" xml:space="preserve"><g><path d="M50.049,0.3c14.18,0.332,25.969,5.307,35.366,14.923S99.675,36.9,100,51.409c-0.195,11.445-3.415,21.494-9.658,30.146 - yadda yadda yadda"/></g></svg>

Combine the .svg files

You can manually do this if you want. I’ve done it. You don’t even have to look at the final file. Just call it svg-defs.svg or something.

It should just be an <svg> tag, with a <defs> tag (which just means you are defining stuff to use later), and then a bunch of <g> (group) tags. Each <g> tag will have a unique ID, and will wrap all the paths and whatnot for each icon.

<svg> <defs> <g id="shape-icon-1"> <!-- all the paths and shapes and whatnot for this icon --> <g> <g id="shape-icon-2"> <!-- all the paths and shapes and whatnot for this icon --> <g> <!-- etc --> </defs></svg>

Turns out <symbol> is probably a better choice than <g>. Read all about it!

Again you can do that by hand, but of course that’s a bit laborious. Fabrice Weinberg has created a Grunt plugin called grunt-svgstore that automates this.

If you’ve never used Grunt, you can do it. Here’s a screencast to get you started.

You can install it with:

npm install grunt-svgstore --save-dev

Make sure the task is available with:

grunt.loadNpmTasks('grunt-svgstore');

And then in the config:

svgstore: { options: { prefix : 'shape-', // This will prefix each <g> ID }, default : { files: { 'dest/svg-defs.svg': ['svgs/*.svg'], } } }},

In the output file, svg-defs.svg, each icon (whatever paths and stuff from the source .svg file) will be wrapped up in a <g> tag with a unique, prefixed ID, and the file name (minus the .svg). Like:

<g id="shape-codepen">

Inject that SVG at the top of the document

Literally include it, like:

<!DOCTYPE html><html lang="en"><head> ...</head><body> <?php include_once("processed/svg-defs.svg"); ?>

Or however you want to do that.

It’s gotta be at the top, sadly, as there is a Chrome bug in which this isn’t going to work if defined later. Although… there is more to this story because as I type these words, the theme this very site is using has the icons defined at the bottom of the document and it works. Ughkgh confusing.

Use the icons wherever

Now you can use them wherever! Like:

<svg viewBox="0 0 100 100" class="icon shape-codepen"> <use xlink:href="#shape-codepen"></use></svg>

Note that grunt-svgstore is now using <symbol> so you don’t even need to use the viewBox!

Make sure you use those class names on the svg to size it.

/* Do whatever makes sense here. Just know that the svg will be an enormous 100% wide if you don't reign in the width. */.icon { display: inline-block; width: 25px; height: 25px;}

Yay: you can style them (and their parts) with CSS

One of the reasons we loved icon fonts is the ability to style them with CSS. This technique one-ups that in that we do everything we could there, and more, because:

  1. We can style all the separate parts
  2. SVG has even more things you can control, like special filters and strokes

The svg is (kinda) in the DOM, so JavaScript too. Here’s some styling possibilities and a demo of this all at work:

See the Pen EBHlD by Chris Coyier (@chriscoyier) on CodePen.

Another way: IcoMoon

IcoMoon, which is known for producing icon fonts, actually does a fantastic job of producing SVG sprites as well. After selecting all the fonts you want, click the SVG button on the bottom and you’ll get that output, including a demo page with the inline SVG method.

Icon System with SVG Sprites | CSS-Tricks (3)

Browser Support

On the browser support front, the danger zones are IE 8 and down, Safari 5 and down, iOS 4.3 and down, and Android 2.3 and down. But if your policy is “the last two major versions” – you’re looking at pretty much 100% support.

Remember that icons can be used as a supporting role only, like always accompanied by a word. If that’s the case, support isn’t too big of a deal. If these are stand-alone, and non-display would make the site unusable, that’s a big deal.

I probably would go for icon fonts, as the support there is much deeper. Just make sure you do it up right.

This is going to get a lot better

Ideally we’d be able to do this:

<svg viewBox="0 0 100 100" class="icon shape-codepen"> <use xlink:href="/images/svg-defs.svg#shape-codepen"></use></svg>

This does work in some browsers, meaning you could skip the include at the top of the document. Doing it this way means an extra HTTP request, but that means you can utilize caching more efficiently (not bloat document caching). In testing, Jonathan Neal discovered you need to have the xmlns attribute on the <svg> for it to work:

<svg xmlns="http://www.w3.org/2000/svg">

But even then, no support in any IE. Unless you wanted to swap out the whole <svg><use> with an <object>, which does work. Jonathan Neal again figured this out:

/MSIE|Trident/.test(navigator.userAgent) && document.addEventListener('DOMContentLoaded', function () { [].forEach.call(document.querySelectorAll('svg'), function (svg) { var use = svg.querySelector('use'); if (use) { var object = document.createElement('object'); object.data = use.getAttribute('xlink:href'); object.className = svg.getAttribute('class'); svg.parentNode.replaceChild(object, svg); } });});

His demo now also has a method which makes an Ajax request for the contents and injects that, which allows the fills to work in IE 9. Not as efficient, but more like a polyfill.

I imagine someday straight up <svg><use> linking right to the .svg will be the way to go. Or even perhaps <img> working with URL fragment identifiers on the SVG.

Browsers treat <use> like the shadow DOM:

Icon System with SVG Sprites | CSS-Tricks (4)

Right now, we can target, say, an individual <path> with CSS, like:

.targetting-a-path { fill: red;}

But that will affect all instances of that path. You’d think you could do:

svg.shape-version-2 .targetting-a-path { fill: red;}

But that doesn’t work. It crosses that shadow DOM boundary. Ideally you’d use the “hat” selector to break that:

svg.shape-version-2 ^ .targetting-a-path { fill: red;}

But that’s not supported yet either and it’s not entirely clear if that’s exactly how that will work or not.

“Versus” icon fonts

Vector-based: tie

Style with CSS: slight edge to SVG sprites (targeting parts, SVG specific styling like strokes)

Weird failures: SVG seems to just work (when supported). Icon fonts seem to fail in weird ways. For instance, you map the characters to normal letters, then the font loading fails and you get random characters abound. Or you map to “Private Use Area” and some browsers decide to re-map them to really weird characters like roses, but it’s hard to replicate. Or you want to host the @font-face files on a CDN, but that’s cross-origin and Firefox hates that, so you need your server to serve the right cross-origin headers, but your Nginx setup isn’t picking that up right, SIGH. SVG wins this one.

Semantics: Not a huge deal, but I think an <svg> makes a bit more sense for an image than a <span>.

Accessibility: Maybe someone can tell me? Can we/should we give the <svg> a title attribute or something? Or a <text> element inside that we visually hide? Update: the <title> element might do. Or perhaps the <desc> element as used in this SVG access spec.

Ease of use: Tools like Fontello and IcoMoon are pretty good for an icon font workflow, but the folder-full-of-SVGs with Grunt squishing them together for you is even easier, I think.

Ian Feather posted an article about why they switched away from icon fonts as well and I agree with every single point.

Icon System with SVG Sprites | CSS-Tricks (2024)

FAQs

Which is better SVG or font icons? ›

Accessibility

One major advantage of SVG icons over Icon fonts is their superior accessibility. SVGs are armed with built in semantic elements – like < title > and < desc > that makes it accessible to screen reader and text browsers. Unlike icon fonts, SVGs are treated as an image and not as a text.

What is SVG sprite? ›

SVG allows us to create icons in a file format that is resolution independent, which is awesome, but due to the limitations of the HTTP protocol we don't want to make another file request for every icon in our website. This will soon be changing with the HTTP/2 protocol.

What is an icon sprite? ›

A sprite is a single image that contains all the icons included in a style. By combining a lot of small images into a single image (the sprite), you can reduce the number of requests needed to fetch all the images, which improves performance and makes your map load more quickly.

How do I use an SVG icon? ›

Create a new file or open an existing one, and drag the SVG into the artboard where you would like it placed.
  1. A duotone icon's .svg file open in Figma. ...
  2. A duotone icon with a new color applied to the primary layer in Figma.
  3. A duotone icon with a new color applied to the secondary layer in Figma.

Should I use SVG for icons? ›

With inline SVGs, they are vectors with no anti-aliasing issues even at small sizes, and they look crisper on retina displays. Winner: If you don't mind the icon fonts being anti-aliased, the icon fonts are the way to go. But if you really want icons to be sharp, the SVG icons are a better choice.

What is an SVG icon? ›

What is SVG? SVG stands for Scalable Vector Graphics. SVG is used to define vector-based graphics for the Web. SVG defines the graphics in XML format. Every element and every attribute in SVG files can be animated.

What are sprites used for? ›

In computer graphics, a sprite is a two-dimensional bitmap that is part of a larger scene (e.g., a 2D video game). Sprites can be static images or animated graphics. Sprites were the standard way to integrate graphics into video games in the 1980s and 1990s.

How use sprite SVG in react? ›

Transform the plain SVG to JSX (google html to jsx) Create a new pure react component and simply return the transformed JSX in render() method. Import and include the created react sprite component. Now use the sprite symbol via <use><svg href="#symbolnameorid"></svg></use> You can use it without the file prefix now.

How use SVG icons in HTML CSS? ›

SVG images can be written directly into the HTML document using the <svg> </svg> tag. To do this, open the SVG image in VS code or your preferred IDE, copy the code, and paste it inside the <body> element in your HTML document.

Are SVG vector files? ›

What is an SVG file? Scalable Vector Graphics (SVG) is a web-friendly vector file format. As opposed to pixel-based raster files like JPEGs, vector files store images via mathematical formulas based on points and lines on a grid.

How do I use an image as a sprite tag? ›

You create a defined area with a <a> with display:block; or <div> and use overflow hidden; to hide overflow and position:relative; . Then you place your <img> image sprite inside absolutely positioned, which is possible since you positioned the parent. Then use :hover on the image to change position.

Are CSS Sprites still used? ›

Weekly tips on front-end & UX. Trusted by 200,000+ folks. CSS Sprites are not new. In fact, they are a rather well-established technique and have managed to become common practice in Web development.

How do I create an icon SVG? ›

There are two ways to create SVG icons: by hand or using a tool. The latter is the easier option that involves practically no code. When you're using a vector image program, you draw your icons on a virtual drawing board using different shapes, colors, and path manipulation. Then you export your .

What is SVG vs PNG? ›

SVG and PNG both are a type of image format to store images. SVG is a vector based image format where an image is represented by set of mathematical figures and PNG is a binary image format and it uses lossless compression algorithm to represent image as pixels.

Is SVG high resolution? ›

If you're working with high-quality digital logos and graphics, you might consider saving your files as PNG or SVG. Both are versatile formats with high resolutions, even at a large scale.

Should icons be SVG or PNG? ›

SVGs offer better image quality as they're vector images, and can scale to any size. PNGs, however, are supported by more browsers. A simple rule of thumb is to use PNGs if you have to support Internet Explorer 8 or older, and to use SVGs if you do not have to support these browsers.

Are SVGs responsive? ›

For our purposes, the most important aspect is the removal of the width and height attributes that most applications include automatically. This makes the SVG fully responsive in modern browsers.

How does SVG work? ›

SVG or Scalable Vector Graphics is a web standard for defining vector-based graphics in web pages. Based on XML the SVG standard provides markup to describe paths, shapes, and text within a viewport. The markup can be embedded directly into HTML for display or saved to a . svg file and inserted like any other image.

How do I SVG an image? ›

Convert your image to an SVG for free.
  1. Select. Choose an image from your photo library that is less than 2GB in size.
  2. Convert. Upload your image to automatically convert it to SVG format.
  3. Download. Your new image will download as an SVG file. Save it, share it, or keep editing it to make it your own.

When should I use SVG? ›

SVG files contain enough information to display vectors at any scale, whereas bitmaps require larger files for scaled-up versions of images — more pixels use up more file space. This is good for websites because smaller files load faster on browsers, so SVGs can increase overall page performance.

Should you use icon fonts? ›

Icon fonts are notoriously bad for accessibility and can lead to some frustrating experiences for those who rely on assistive technologies. Treated like text — The browser treats fonts like text because that is what fonts are supposed to be.

Are fonts svgs? ›

An SVG font is a new version of the OpenType format, with SVG standing for Scalable Vector Graphics. The SVG glyph format allows the characters to be displayed in multiple colors and different transparencies, and some may even be animated.

Can you use an SVG as a favicon? ›

Icon used by browsers to identify a webpage or site. While all browsers support the . ico format, the SVG format can be preferable to more easily support higher resolutions or larger icons.

Why we use Font Awesome icons instead of images? ›

Using icon fonts will be more and more relevant as more high resolution/density displays become available.

Top Articles
Latest Posts
Article information

Author: Carlyn Walter

Last Updated:

Views: 5766

Rating: 5 / 5 (70 voted)

Reviews: 85% of readers found this page helpful

Author information

Name: Carlyn Walter

Birthday: 1996-01-03

Address: Suite 452 40815 Denyse Extensions, Sengermouth, OR 42374

Phone: +8501809515404

Job: Manufacturing Technician

Hobby: Table tennis, Archery, Vacation, Metal detecting, Yo-yoing, Crocheting, Creative writing

Introduction: My name is Carlyn Walter, I am a lively, glamorous, healthy, clean, powerful, calm, combative person who loves writing and wants to share my knowledge and understanding with you.