Skip to content
Sasha Boginsky edited this page Jun 26, 2019 · 12 revisions

About

This wiki serves as a step by step guide for using our workflow, which is based on the Material Design documentation page for creating SVG Sprites.

Most of our icons are from the Material Design library, but since we store individual icons locally, they are not limited to it. Feel free to source icons from any library, while preferring Material Design's when applicable for effortless consistency.

Adding an SVG Icon

1) Sourcing the Icons

The collection of Material Design icons can be found at https://material.io/tools/icons/?style=baseline and on their Github repository.

To use an icon, download it as SVG from their website or grab the corresponding SVG file from the production folder if you're using their Github repository. Presently, we keep our toolbar icons at 18px, so you should download the 24px version at 48dp. (You will find the options for this easily).

Once you have the file, drag it into the assets/icons/svg directory.

2) Minifying the SVG

We configured Grunt to minify the SVG files for the web using the grunt-svgmin plugin.

Once you add your icon to the svg folder, you'll want to have Grunt output a minified version to the assets/icons/svg-min directory by running:

$ grunt svgmin

Minifying not only makes our files smaller but also standardizes the final svg code we use, which tends to be different across various libraries.

3) Compiling the SVG

We also configured Grunt to compile our SVG Sprite using the grunt-svg-sprite plugin. Grunt grabs every *.svg in the assets/icons/svg-min folder, compiles them and outputs them as a sprite sheet found at assets/icons/symbol/sprite.symbol.svg.

Once your minified SVG is in the assets/icons/svg-min directory, all you have to do to recompile the SVG Sprite to include it is run:

$ grunt svg_sprite

Overview

Grunt will also recompile an example HTML file sprite.symbol.html found in the same directory as its corresponding sprite.symbol.svg sprite. If you open it in your browser, you will find a visual overview of the icons in it.

It also serves as a nicely formatted code overview of the icons in the sprite sheet:

<!-- one <symbol> for each icon in the sprite sheet -->
<svg width="0" height="0" style="position:absolute">
     <symbol viewBox="0 0 18 18" id="border_clear" xmlns="http://www.w3.org/2000/svg"><path fill="#0078A8" d="M5.25 3.75h1.5v-1.5h-1.5v1.5zm0 6h1.5v-1.5h-1.5v1.5zm0 6h1.5v-1.5h-1.5v1.5zm3-3h1.5v-1.5h-1.5v1.5zm0 3h1.5v-1.5h-1.5v1.5zm-6 0h1.5v-1.5h-1.5v1.5zm0-3h1.5v-1.5h-1.5v1.5zm0-3h1.5v-1.5h-1.5v1.5zm0-3h1.5v-1.5h-1.5v1.5zm0-3h1.5v-1.5h-1.5v1.5zm6 6h1.5v-1.5h-1.5v1.5zm6 3h1.5v-1.5h-1.5v1.5zm0-3h1.5v-1.5h-1.5v1.5zm0 6h1.5v-1.5h-1.5v1.5zm0-9h1.5v-1.5h-1.5v1.5zm-6 0h1.5v-1.5h-1.5v1.5zm6-4.5v1.5h1.5v-1.5h-1.5zm-6 1.5h1.5v-1.5h-1.5v1.5zm3 12h1.5v-1.5h-1.5v1.5zm0-6h1.5v-1.5h-1.5v1.5zm0-6h1.5v-1.5h-1.5v1.5z"/></symbol>
     <symbol viewBox="0 0 18 18" id="border_outer" xmlns="http://www.w3.org/2000/svg"><path fill="#0078A8" d="M9.75 5.25h-1.5v1.5h1.5v-1.5zm0 3h-1.5v1.5h1.5v-1.5zm3 0h-1.5v1.5h1.5v-1.5zm-10.5-6v13.5h13.5V2.25H2.25zm12 12H3.75V3.75h10.5v10.5zm-4.5-3h-1.5v1.5h1.5v-1.5zm-3-3h-1.5v1.5h1.5v-1.5z"/></symbol>
     <symbol ..... > <!-- and so on -->
</svg>

Rendering the Icon

Further down in sprite.symbol.html you will find the HTML that renders the icon, using <svg> and <use> blocks, by referencing the corresponding id from the <symbol> tag for it.

For ex: to render the border-clear icon in our tools file src/edit/DistortableImage.EditToolbar.js, we can just copy-paste the ex. HTML there and add the relative path to the sprite sheet onto the xlink:href attribute:

<svg class="svg-border_clear-dims">
  <use xlink:href="../assets/icons/symbol/sprite.symbol.svg#border_clear"></use>
</svg>

We further simplified the HTML by removing the class from the svg and setting our icons width / height in css using the broad svg selector:

<svg><use xlink:href="../assets/icons/symbol/sprite.symbol.svg#border_clear"></use></svg>
svg {
  width: 18px;
  height: 18px;
}

note on the xlink:href attribute:

  • As of svg2 it is deprecated in favor of just href, but you should use it for now as there is not full browser support for it even with the polyfill mentioned later in this wiki.

Styling

Another tool you will find in sprite.symbol.html is the css class you can use to set the individual width / height of an icon:

For ex: if we wanted to make just the border clear icon 16px we would use:

.svg-border_clear-dims { 
  width: 16px; 
  height: 16px; 
}

These classes are only good for styling the dimensions of the icon. To style other attributes, for ex. color (called the fill attribute for svg), you will need to add a class to the <use> tag and reference it.

Note that you cannot override any attributes present in the original svg file using CSS. For ex., in order to be able to set the fill of the border-clear icon to a different color in CSS, you need to remove the fill attribute from assets/icons/svg/border_clear.svg, re-minify, and recompile.

You can also just change the attribute directly in the svg file as we have done so far.


Browser Support

On the browser support front, we implement external sprite sheet support for Internet Explorer, Edge, and older Android and iOS browsers using the svgforeverybody polyfill.

To use it:

  1. Make sure <meta http-equiv="X-UA-Compatible" content="IE=Edge"/> is in your <head> with the other <meta> tags.

  2. Make sure these 2 script tags are anywhere in your <head>

<script src="https://rawgit.com/jonathantneal/svg4everybody/master/dist/svg4everybody.js"></script>
<script>svg4everybody();</script>
Clone this wiki locally