-
Notifications
You must be signed in to change notification settings - Fork 287
SVG Icon System
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.
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.
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.
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
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>
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.
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.
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:
-
Make sure
<meta http-equiv="X-UA-Compatible" content="IE=Edge"/>
is in your<head>
with the other<meta>
tags. -
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>