J Scott Smith

Drop Sprites or Icon Fonts and Just Use SVG

Articles - January 22nd, 2015

Introduction

If you haven’t heard about SVGs yet than I’m not sure where you’ve been because it seems like their popularity exploded last year. And for good reason as they solve a number of huge problems. First and for most they are vector and not raster. This was my attraction to them; when you’re browsing the web on a retina/hi-res monitor you tend to get annoyed with pixelated images very quickly. Spriting with compass was a good solution, but then you had to start building multiple sprite sheets to serve 2x images. Bleh. So being able to use vector images was extremely appealing to me which lead me to work with icon fonts for a short period of time. But using them feels cumbersome even when using very convenient tools like icomoon.io. So I struggled to find a convenient way to implement SVGs into my workflow for awhile. Tried inlining them by hand, using them as background images, and linking actual svg files in an img element. After I discovered grunt-svgstore I was completely sold as it offers the quickest and most robust workflow to using svg.

SVG Workflow

1. Creating the SVGs

I create all my web/ui design in illustrator (I have no idea why Photoshop is the standard tool for web, to me it makes absolutely no sense but that’s a whole other story) so it has a feature to save SVGs. Usually, I create a single document with all the elements I’ll need, isolate them to individual artboards, then choose the “Save As” command with the file type SVG selected and the “Use Artboards” option ticked. This allows you to save each artboard as an individual SVG file quickly. You’ll end up with “filename-01”, “filename-02”, “filename-03” … and so on, so you’ll have to rename them to something meaningful after you export them.

2. Setting Up Grunt and svg-store

I use Grunt, but svgstore is also available as a Gulp plugin. I setup two tasks within my Gruntfile to handle the SVGs. One to task to watch for changes to the folder containing the SVG source, then the other to create the combined SVG file.

You’ll need to include the folowing two packages in your package.json file. One for grunt-contrib-watch and the other for grunt-svgstore.

{
  "devDependencies": {
    "grunt": "~0.4.1",
    "grunt-contrib-watch": "~0.5.3",
    "grunt-svgstore": "~0.4.1"
  }
}

After that you can install these packages with npm install on the command line.

Setting up the tasks is next. Set up a task for grunt-svgstore first and register the task with grunt.registerTask('svg', ['svgstore']); This will allow you to run the task directly from the command line via grunt svg. But I don’t wan’t to have to run the task each time a file changes or a new SVG is added so I’m using the watch task to poll for changes within my project SVG folder. Here’s the whole deal:

module.exports = function(grunt) {
  'use strict';
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    watch: {
      svgs: {
        files: 'img/svg/**/*.svg',
        tasks: ['svg']
      }
    },
    svgstore: {
      options: {
        cleanup: true,
        prefix : 'svg-',
        svg: {
          id: 'svg-defs',
          class: 'svg-hide',
          xmlns: 'http://www.w3.org/2000/svg'
        }
      },
      build: {
        files: {
          'img/svg/built/svg-defs.svg': ['img/svg/*.svg']
        }
      }
    }
  });
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-svgstore');
  grunt.registerTask('svg', ['svgstore']);
};

3. Including the Built Svg-defs file

Last thing to do is to include the built svg-defs.svg file on every page where you’d like to include an SVG. A simple php include will do the trick:

<?php include("/img/svg/built/svg-defs.svg"); ?>

Once you have the built SVG included you can reference each and every SVG that has been combined into the file by referencing the id as a <use> element like so:

<svg class="svg-file-name">
  <use xlink:href="#svg-file-name"></use>
</svg>

Some styling can now be applied to size the SVG as you see fit.

More Later

Yay! You now have a good workflow for developing with SVGs. I’ve just barely scratched the surface of the benefits of using SVG so perhaps I’ll add to this later with some of those and some of the great resources I’ve gathered regarding SVGs.

Comments

blog comments powered by Disqus