SVG Sprite Workflow That Works
Update (08 Sep 2017):
I found that sometimes SVG icons don’t appear on IE11 even if the SVG code looks good. One of the examples is:
and the icon should look:
The solution on IE11 is to remove the
.st# classes in the
<path> 😮 and define the color with CSS explained below.
So the above SVG code may should look like:
Update (23 Sep 2016):
One of my colleagues (Michal Prazuch) noted me that xlink:href is not working on Safari. I have contacted SVG gurus, Sara Soueidan and Amelia, and they suggested to keep using xlink:href for now as it will work in all browsers, old & new.
And the Safari issue has been logged here early this year:
I will keep an eye on it and keep you all updated.
The code below has been re-updated to reflect back this update.
Updates (14 Sep 2016):
xlink:href has been deprecated since SVG 2 so instead use href. The code below has been updated to reflect this update.
Updates (30 Apr 2016):
This article has been listed in Codrop Collective #217.
Follow me on Twitter (@iamryanyu)
This SVG Sprite Workflow has been designed and developed in order to improve the current workflow when creating a CSS spritesheet at Squiz.
A lot of resources have been researched and studied from the various places and some of them are listed below:
In addition, I had a great chance to attend the Web Directions - Respond 16 in Sydney (thanks a lot to my company, Squiz, for the ticket) and Sara Soueidan, who I am a big fan of, had spoken about SVG <use>. I am really happy that what she said during her speak was exactly same as how I designed this workflow, even the two polyfills.
In this article, when I say “We”, they are not only myself and the front end developers at Squiz, but also anyone using the old CSS sprite method.
At the moment, when we need to display icons, we usually create a CSS spritesheet with SVG and PNG (as a fallback) format. To display the icons, normally, we use CSS properties like:
Problem 1: Extra Work
My biggest concern always has been to open the Illustrator when new icon is introduced. This is the extra work I have definitely and always wanted to get rid of and gives the front end developers more time to focus on coding.
Problem 2: No Change on Icon Color
Another problem is we cannot change the color of icons with CSS. If you wanted to change the icon color on hover, we had to add two identical icons but in different colors. I always thought there must be a way to use only one icon and change the color with CSS, but I had no luck.
Problem 3: No Change on Icon Element Color
This is not a usual case but sometimes we want to change the color of only one part of the icon with CSS, something like below:
To resolve those problems above, what we are going to use is SVG <use>. It will save the front end developers a lot of time by:
- No needing to work on the Illustrator anymore
- Using CSS to change colors instead of from Illustrator
This Workflow is designed based on Squiz Boilerplate (Gulp version) but I am sure it will work great with your own Boilerplate.
Workflow 1 — Install Plugins/Polyfills
To start with, we will install 1 Gulp plugin and 2 polyfills.
- gulp-svg-sprite: this plugin will do all the heavy-lifting for us. It will combine all the SVG files and generate one SVG Sprite.
And this is the configuration for Gulp:
- svgxuse: this polyfill will be used on IE 10 - Edge 12.
- SVG for Everybody: this polyfill will be used on IE 9 and below.
Workflow 2 — Boilerplate
- Create new folder in source/svg-sprite (change the path appropriate for your own structure). When gulp-ing, new file will be created in dist/styles/mysource_files/sprite.svg (or depending on how you set it up in Gulp configuration.
- Include svgxuse and SVG for Everybody in the foot in HTML like below:
Please note that SVG for Everybody will be only used on IE 9.
Workflow 3 — Prepare SVG Icons
Note: ask designers to provide you individual icons in SVG format.
With this workflow, we only need to deal with each SVG file individually.
- Let’s get an icon (or icons) from designers (or yourself). Please ask the designer to set the path color in black when they create icons.
- Go to SVGOMG and open the icon. In the right menus, keep the options as they are, but except the ‘Merge paths’. Disable it and download.
- Open the SVG file you just downloaded in a text editor. Search for an attribute ‘fill’ and remove them. Save the file.
- Give the appropriate name when you save. The file name will be the ID of the SVG icon and we will use it later.
- Put the SVG files in the source/svg-sprite.
Workflow 4 — Add SVG Icons in HTML
Now this is the fun part. Let’s start with the basic markup and explore 2 scenarios.
1. The Basic
To display the SVG icon, we are going to add <use> element. If you want to know more about <use>, please refer to the resources listed above.
The very basic markup looks like:
Using href, you can reference to the external file with the ID which is same as the SVG file name.
2. Scenario 1 — OOCSS with SVG Icon
Now let’s say you want to style the SVG icons with reset, size and color. To do that, you can simply add classes to <svg> and style them in CSS.
3. Scenario 2 — Change Icon Color of Each Element
This is a bit more complex and requires extra updates in the SVG file.
Firstly, you need to go to the individual SVG file and add fill=”currentColor” in the path you want to keep the original color.
And now let’s create OOCSS for the different color in HTML.
To apply two different colors, you need to apply the fill propery so the path with fill=”currentColor” will be filled with the fill property and the path without it will be filled by the color property.
There is another occasion like you want to apply multiple colors more than two colors to the SVG icons, but we will ignore that scenario in this article. If you want to know how to do it, please let me know.
Workflow 4 — Accessibility with 3 Scenarios
1. Link with Title
Add the title along with <svg> in <a>. Also you don’t want the screen reader keep reading the icons, so add aria-hidden to <svg>.
2. Link without Title
Sometimes you don’t want the screen readers to read the title of the link. In that case, remove the title and add aria-label to <a>.
3. No Link
When this is not a link and you want the screen reader to read out, add <title> inside <svg>. And remove aria-hiddne from <svg>.
Why 2 Polyfills?
As svgxuse performs better than SVG for Everybody, we will use svgxuse for the main polyfill. Please read more details from svgxuse GitHub page.
However, it requires to add SVG sprite as inline (inside HTML right below opening <body>) for IE 9 and it is out of the scope for this workflow at the moment. Even though there are some benefits with inline SVG sprite, our main focus on this workflow is to host our SVG sprite in the external file.
To resolve this issue, we will call svg4everybody.js only for IE 9.
When JS is Disabled?
As those polyfills are JS based, when JS is disabled, the icons won’t appear. However, as the purpose of those icons are decorative, it is ok if the icons are not appearing (with additional CSS to style so it still look ok without the icons) unless clients insist to have them displayed when JS is disabled. In that case, we will have to provide the fallback with PNG.
If you have any questions, feedback, comments or recommendations, please feel free to let me know.