Grunticon: A Grunt.js plugin for managing and delivering sharp icons to all devices

Posted by Scott on 08/31/2012

Note: Grunticon was formerly named Unicon. The name was changed on September 19, 2012.

Creating sharp-looking icons and background images in our client work has always been more complicated than we want it to be, and with the growing popularity of higher-definition screens, it's only getting harder. CSS sprites have traditionally worked alright, but they can be a pain to manage, are often difficult to use in CSS layouts, and require generating and serving multiple fixed-pixel sizes. Icon fonts are a nice too, but they cause problems in some of the popular mobile environments we need to support, they aren't easy to manage for custom-designed icons, and they're limited to a single color.

What we really want is a way to efficiently manage and serve vector icons so they'll be crisp on displays of all resolutions, while delivering them in a way that is fast and non-blocking (for performance), and with appropriate fallbacks for older devices. So we built one!

Grunticon: A mystical CSS icon solution

         /'
        //
    .  //
    |\//7
   /' " \
  .   . .
  | (    \
  |  '._  '
  /    \'-'

Grunticon is a Grunt.js task that efficiently manages icons and background images for delivery to a variety of browsers and devices. It takes a folder of SVG files (typically, icons that you've drawn in an application like Adobe Illustrator), and outputs them to 3 CSS files containing CSS for the icons with class names that match the file that generated them. The CSS files contain the icons in the following formats:

  1. All of the icons inline in the CSS as vector SVG data URLs,
  2. All of the icons inline in the CSS as PNG data URLs,
  3. All of the icons referenced externally as PNG images, which are automatically generated from the source SVG and placed in a directory alongside the CSS files.

The 3 files are necessary to support different browsers, and only one of the formats is intended to be served to a particular device, based on a browser's capabilities for SVG, data URLs. Basically, most modern browsers like Chrome, Firefox, Opera, Safari, and IE9+ can handle the SVG icons. IE8 and Android 2.x browsers can handle the PNG data URLs, but not SVG, so stylesheet #2 is intended for them. Lastly, browsers like IE7 and older, and those without JavaScript enabled, receive the fallback external image requests.

Figuring out which CSS file to serve based on these support divisions is complicated, so Grunticon generates a small snippet of JavaScript and CSS that you can drop into your page, which asynchronously (*read: in a way that does not block the page from rendering immediately) loads the appropriate CSS file depending on a browser's capabilities. Lastly, Grunticon also creates a preview HTML file so you can use the icons and their classnames as a reference during development.

Output Samples

You can see an example of the files that Grunticon uses and creates by browsing the Grunticon project's example folder. The source directory contains the SVG icon source files, and the output folder contains the files that Grunticon creates.

You can also view a demo of the icon output, with the Grunticon loader in-place, here: Grunticon Output Preview

Getting started with Grunticon

Grunticon is a Grunt.js task, and it also uses PhantomJS, a headless WebKit browser, for rendering the SVG files into various formats. Both of these are open-source command-line tools that can be installed following the instructions on the Grunt.js documentation. Once you have Grunt installed, you can get Grunticon via NPM, the Node.js package management utility.

Once installed and configured with Grunt.js, Grunticon will run alongside your other Grunt tasks whenever you run Grunt itself. Its configuration is fairly simple, requiring a src directory, containing your SVG files, and a dest directory that you'd like Grunticon to export the icons to.

For installation steps, check out the Grunticon readme.

Future plans and contributing

We chose to write Grunticon as a Grunt.js task because we've found Grunt to be incredibly helpful in our production process and wanted our icon tool to work alongside our other CSS and JavaScript tasks. That said, we understand that this dependency presents a significant barrier and learning curve to use the tool. In the coming weeks, we're going to consider how else the tool might be made useful, such as perhaps an application that would allow you to upload a zip file and download the same output that Grunticon currently creates.

If you have ideas or thoughts on the tool, the direction of the project, or would like to help contribute, just drop us a note here or in the issue tracker. Enjoy!

Comments

Hello, I’m really interested in your tool, but I’m not a js guy ; ) , so the dependency with grunt is a barrier for me.

I’ve tried to create the same tool with php and ImageMagick, and it works.

Maybe it could help some people (ImageMagick is on my shared hosting, should not be a problem)

I’d like to show you the result to be sure that there are no problems with my ouputs (maybe the png rasterisation quality ?)

If you are interested, send me an e-mail (with some icons you didn’t provide in the github directory maybe) and I’ll send you the link to my online script for testing.

Thanks,

Pascal

Comment by Pascal @eQRoeil on 08/31  at  07:35 PM