{"id":1981,"date":"2016-03-30T17:14:22","date_gmt":"2016-03-31T00:14:22","guid":{"rendered":"https:\/\/hellbach.us\/blog\/?p=1981"},"modified":"2023-01-26T18:47:26","modified_gmt":"2023-01-27T02:47:26","slug":"work-svg-icons","status":"publish","type":"post","link":"https:\/\/hellbach.us\/blog\/tech\/dev\/work-svg-icons\/","title":{"rendered":"How to work with SVG icons"},"content":{"rendered":"<div class='__iawmlf-post-loop-links' style='display:none;' data-iawmlf-post-links='[{&quot;id&quot;:589,&quot;href&quot;:&quot;http:\\\/\\\/fvsch.com\\\/code\\\/svg-icons\\\/how-to&quot;,&quot;archived_href&quot;:&quot;http:\\\/\\\/web-wp.archive.org\\\/web\\\/20161014171951\\\/http:\\\/\\\/fvsch.com\\\/code\\\/svg-icons\\\/how-to\\\/&quot;,&quot;redirect_href&quot;:&quot;&quot;,&quot;checks&quot;:[{&quot;date&quot;:&quot;2025-11-18 20:28:21&quot;,&quot;http_code&quot;:200},{&quot;date&quot;:&quot;2026-02-11 01:17:12&quot;,&quot;http_code&quot;:503}],&quot;broken&quot;:false,&quot;last_checked&quot;:{&quot;date&quot;:&quot;2026-02-11 01:17:12&quot;,&quot;http_code&quot;:503},&quot;process&quot;:&quot;done&quot;},{&quot;id&quot;:590,&quot;href&quot;:&quot;http:\\\/\\\/www.kaliop.com&quot;,&quot;archived_href&quot;:&quot;http:\\\/\\\/web-wp.archive.org\\\/web\\\/20190923041259\\\/https:\\\/\\\/www.kaliop.com\\\/&quot;,&quot;redirect_href&quot;:&quot;&quot;,&quot;checks&quot;:[{&quot;date&quot;:&quot;2025-11-18 20:28:52&quot;,&quot;http_code&quot;:200},{&quot;date&quot;:&quot;2026-02-11 01:17:08&quot;,&quot;http_code&quot;:503}],&quot;broken&quot;:false,&quot;last_checked&quot;:{&quot;date&quot;:&quot;2026-02-11 01:17:08&quot;,&quot;http_code&quot;:503},&quot;process&quot;:&quot;done&quot;},{&quot;id&quot;:591,&quot;href&quot;:&quot;https:\\\/\\\/jakearchibald.github.io\\\/svgomg&quot;,&quot;archived_href&quot;:&quot;http:\\\/\\\/web-wp.archive.org\\\/web\\\/20251011235516\\\/https:\\\/\\\/jakearchibald.github.io\\\/svgomg\\\/&quot;,&quot;redirect_href&quot;:&quot;&quot;,&quot;checks&quot;:[{&quot;date&quot;:&quot;2025-11-18 20:28:53&quot;,&quot;http_code&quot;:206}],&quot;broken&quot;:false,&quot;last_checked&quot;:{&quot;date&quot;:&quot;2025-11-18 20:28:53&quot;,&quot;http_code&quot;:206},&quot;process&quot;:&quot;done&quot;},{&quot;id&quot;:592,&quot;href&quot;:&quot;https:\\\/\\\/en.wikipedia.org\\\/wiki\\\/Sprite_%28computer_graphics%29&quot;,&quot;archived_href&quot;:&quot;http:\\\/\\\/web-wp.archive.org\\\/web\\\/20251008091813\\\/https:\\\/\\\/en.wikipedia.org\\\/wiki\\\/Sprite_%28computer_graphics%29&quot;,&quot;redirect_href&quot;:&quot;&quot;,&quot;checks&quot;:[{&quot;date&quot;:&quot;2025-11-18 20:28:54&quot;,&quot;http_code&quot;:200}],&quot;broken&quot;:false,&quot;last_checked&quot;:{&quot;date&quot;:&quot;2025-11-18 20:28:54&quot;,&quot;http_code&quot;:200},&quot;process&quot;:&quot;done&quot;},{&quot;id&quot;:593,&quot;href&quot;:&quot;https:\\\/\\\/github.com\\\/jkphl\\\/gulp-svg-sprite&quot;,&quot;archived_href&quot;:&quot;http:\\\/\\\/web-wp.archive.org\\\/web\\\/20210220230434\\\/https:\\\/\\\/github.com\\\/jkphl\\\/gulp-svg-sprite&quot;,&quot;redirect_href&quot;:&quot;&quot;,&quot;checks&quot;:[{&quot;date&quot;:&quot;2025-11-18 20:28:56&quot;,&quot;http_code&quot;:206}],&quot;broken&quot;:false,&quot;last_checked&quot;:{&quot;date&quot;:&quot;2025-11-18 20:28:56&quot;,&quot;http_code&quot;:206},&quot;process&quot;:&quot;done&quot;},{&quot;id&quot;:594,&quot;href&quot;:&quot;https:\\\/\\\/icomoon.io&quot;,&quot;archived_href&quot;:&quot;http:\\\/\\\/web-wp.archive.org\\\/web\\\/20251111232009\\\/https:\\\/\\\/icomoon.io\\\/&quot;,&quot;redirect_href&quot;:&quot;&quot;,&quot;checks&quot;:[{&quot;date&quot;:&quot;2025-11-18 20:28:57&quot;,&quot;http_code&quot;:200}],&quot;broken&quot;:false,&quot;last_checked&quot;:{&quot;date&quot;:&quot;2025-11-18 20:28:57&quot;,&quot;http_code&quot;:200},&quot;process&quot;:&quot;done&quot;},{&quot;id&quot;:595,&quot;href&quot;:&quot;https:\\\/\\\/github.com\\\/jonathantneal\\\/svg4everybody&quot;,&quot;archived_href&quot;:&quot;http:\\\/\\\/web-wp.archive.org\\\/web\\\/20250916165535\\\/https:\\\/\\\/github.com\\\/jonathantneal\\\/svg4everybody&quot;,&quot;redirect_href&quot;:&quot;&quot;,&quot;checks&quot;:[{&quot;date&quot;:&quot;2025-11-18 20:28:59&quot;,&quot;http_code&quot;:206}],&quot;broken&quot;:false,&quot;last_checked&quot;:{&quot;date&quot;:&quot;2025-11-18 20:28:59&quot;,&quot;http_code&quot;:206},&quot;process&quot;:&quot;done&quot;},{&quot;id&quot;:596,&quot;href&quot;:&quot;https:\\\/\\\/github.com\\\/Keyamoon\\\/svgxuse&quot;,&quot;archived_href&quot;:&quot;http:\\\/\\\/web-wp.archive.org\\\/web\\\/20251012123023\\\/https:\\\/\\\/github.com\\\/Keyamoon\\\/svgxuse&quot;,&quot;redirect_href&quot;:&quot;&quot;,&quot;checks&quot;:[{&quot;date&quot;:&quot;2025-11-18 20:29:01&quot;,&quot;http_code&quot;:206}],&quot;broken&quot;:false,&quot;last_checked&quot;:{&quot;date&quot;:&quot;2025-11-18 20:29:01&quot;,&quot;http_code&quot;:206},&quot;process&quot;:&quot;done&quot;},{&quot;id&quot;:597,&quot;href&quot;:&quot;https:\\\/\\\/bugs.chromium.org\\\/p\\\/chromium\\\/issues\\\/detail?id=470601&quot;,&quot;archived_href&quot;:&quot;http:\\\/\\\/web-wp.archive.org\\\/web\\\/20250829205608\\\/https:\\\/\\\/bugs.chromium.org\\\/p\\\/chromium\\\/issues\\\/detail?id=470601&quot;,&quot;redirect_href&quot;:&quot;&quot;,&quot;checks&quot;:[{&quot;date&quot;:&quot;2025-11-18 20:29:03&quot;,&quot;http_code&quot;:200}],&quot;broken&quot;:false,&quot;last_checked&quot;:{&quot;date&quot;:&quot;2025-11-18 20:29:03&quot;,&quot;http_code&quot;:200},&quot;process&quot;:&quot;done&quot;},{&quot;id&quot;:598,&quot;href&quot;:&quot;http:\\\/\\\/andydavies.me\\\/blog\\\/2013\\\/10\\\/22\\\/how-the-browser-pre-loader-makes-pages-load-faster&quot;,&quot;archived_href&quot;:&quot;http:\\\/\\\/web-wp.archive.org\\\/web\\\/20250501104810\\\/https:\\\/\\\/andydavies.me\\\/blog\\\/2013\\\/10\\\/22\\\/how-the-browser-pre-loader-makes-pages-load-faster\\\/&quot;,&quot;redirect_href&quot;:&quot;&quot;,&quot;checks&quot;:[{&quot;date&quot;:&quot;2025-11-18 20:29:05&quot;,&quot;http_code&quot;:206}],&quot;broken&quot;:false,&quot;last_checked&quot;:{&quot;date&quot;:&quot;2025-11-18 20:29:05&quot;,&quot;http_code&quot;:206},&quot;process&quot;:&quot;done&quot;},{&quot;id&quot;:599,&quot;href&quot;:&quot;https:\\\/\\\/github.com\\\/suitcss\\\/suit\\\/blob\\\/master\\\/doc\\\/naming-conventions.md&quot;,&quot;archived_href&quot;:&quot;http:\\\/\\\/web-wp.archive.org\\\/web\\\/20250928014618\\\/https:\\\/\\\/github.com\\\/suitcss\\\/suit\\\/blob\\\/master\\\/doc\\\/naming-conventions.md&quot;,&quot;redirect_href&quot;:&quot;&quot;,&quot;checks&quot;:[{&quot;date&quot;:&quot;2025-11-18 20:29:06&quot;,&quot;http_code&quot;:206}],&quot;broken&quot;:false,&quot;last_checked&quot;:{&quot;date&quot;:&quot;2025-11-18 20:29:06&quot;,&quot;http_code&quot;:206},&quot;process&quot;:&quot;done&quot;},{&quot;id&quot;:600,&quot;href&quot;:&quot;https:\\\/\\\/svgwg.org\\\/svg2-draft\\\/coords.html#Units&quot;,&quot;archived_href&quot;:&quot;http:\\\/\\\/web-wp.archive.org\\\/web\\\/20251001020202\\\/https:\\\/\\\/svgwg.org\\\/svg2-draft\\\/coords.html&quot;,&quot;redirect_href&quot;:&quot;&quot;,&quot;checks&quot;:[{&quot;date&quot;:&quot;2025-11-18 20:29:08&quot;,&quot;http_code&quot;:200}],&quot;broken&quot;:false,&quot;last_checked&quot;:{&quot;date&quot;:&quot;2025-11-18 20:29:08&quot;,&quot;http_code&quot;:200},&quot;process&quot;:&quot;done&quot;},{&quot;id&quot;:601,&quot;href&quot;:&quot;https:\\\/\\\/www.smashingmagazine.com\\\/2016\\\/02\\\/preload-what-is-it-good-for&quot;,&quot;archived_href&quot;:&quot;http:\\\/\\\/web-wp.archive.org\\\/web\\\/20251118204012\\\/https:\\\/\\\/www.smashingmagazine.com\\\/2016\\\/02\\\/preload-what-is-it-good-for\\\/&quot;,&quot;redirect_href&quot;:&quot;https:\\\/\\\/www.smashingmagazine.com\\\/2016\\\/02\\\/preload-what-is-it-good-for\\\/&quot;,&quot;checks&quot;:[],&quot;broken&quot;:false,&quot;last_checked&quot;:null,&quot;process&quot;:&quot;done&quot;},{&quot;id&quot;:602,&quot;href&quot;:&quot;https:\\\/\\\/developer.mozilla.org\\\/en-US\\\/docs\\\/Web\\\/CSS\\\/Using_CSS_variables&quot;,&quot;archived_href&quot;:&quot;http:\\\/\\\/web-wp.archive.org\\\/web\\\/20190309102759\\\/https:\\\/\\\/developer.mozilla.org\\\/en-US\\\/docs\\\/Web\\\/CSS\\\/Using_CSS_variables&quot;,&quot;redirect_href&quot;:&quot;&quot;,&quot;checks&quot;:[{&quot;date&quot;:&quot;2025-11-18 20:29:54&quot;,&quot;http_code&quot;:206}],&quot;broken&quot;:false,&quot;last_checked&quot;:{&quot;date&quot;:&quot;2025-11-18 20:29:54&quot;,&quot;http_code&quot;:206},&quot;process&quot;:&quot;done&quot;},{&quot;id&quot;:603,&quot;href&quot;:&quot;http:\\\/\\\/caniuse.com\\\/#feat=css-variables&quot;,&quot;archived_href&quot;:&quot;http:\\\/\\\/web-wp.archive.org\\\/web\\\/20251118122928\\\/https:\\\/\\\/caniuse.com\\\/&quot;,&quot;redirect_href&quot;:&quot;&quot;,&quot;checks&quot;:[{&quot;date&quot;:&quot;2025-11-18 20:29:56&quot;,&quot;http_code&quot;:200}],&quot;broken&quot;:false,&quot;last_checked&quot;:{&quot;date&quot;:&quot;2025-11-18 20:29:56&quot;,&quot;http_code&quot;:200},&quot;process&quot;:&quot;done&quot;}]'><\/div>\n<blockquote><p>check <a href=\"http:\/\/fvsch.com\/code\/svg-icons\/how-to\/\" target=\"_blank\" rel=\"nofollow noopener\">source<\/a> as stupid wordpress erase svg<\/p><\/blockquote>\n<p>There are many ways to use SVG icons in HTML and CSS, and I haven\u2019t tried them all. This is how we do it in our small front-end team at <a href=\"http:\/\/www.kaliop.com\/\" target=\"_blank\" rel=\"nofollow noopener\">Kaliop<\/a>. It works well for our needs, which include:<\/p>\n<ul>\n<li>Content and communication websites, often based on big CMSes, rather than full-JS web apps.<\/li>\n<li>Icons, which are often simple, single-color icons (each potentially used in several different colors depending on context and user interactions). Two-color icons are possible too.<\/li>\n<li>IE9+ support.<\/li>\n<\/ul>\n<p><em>Table of contents<\/em><\/p>\n<ol>\n<li><a href=\"#section-preparing\">Preparing your icons<\/a><\/li>\n<li><a href=\"#section-sprite\">Making an SVG sprite<\/a><\/li>\n<li><a href=\"#section-adding\">Adding icons to your pages<\/a><\/li>\n<li><a href=\"#section-styling\">Styling icons with CSS<\/a><\/li>\n<li><a href=\"#section-advanced\">Advanced topics<\/a><\/li>\n<\/ol>\n<h2 id=\"section-preparing\">Preparing your icons<\/h2>\n<p>When you get an SVG icon from a designer or from a graphics tool you use (Illustrator, Adobe Assets, Sketch, Inkscape, etc.), it\u2019s tempting to just throw it into your project. Yet I find that reworking it a little bit in your favorite tool to make sure it\u2019s <em>just right<\/em> can save you some headaches and improve the result.<\/p>\n<figure class=\"full\"><img decoding=\"async\" src=\"http:\/\/fvsch.com\/code\/svg-icons\/how-to\/example-1.png\" alt=\"\" \/><figcaption>The simple icons on an artboard in Illustrator (left) and Sketch (right)<\/figcaption><\/figure>\n<h3>Work with a new document or artboard<\/h3>\n<p>Create a new document or new artboard in your favorite tool, and copy-paste your icon in the center. It\u2019s a great way to make sure your icon is clean and doesn\u2019t have a ton of hidden paths lying around.<\/p>\n<h3>Square is easier<\/h3>\n<p>Your icon <em>doesn\u2019t have to be square<\/em>, but square icons are easier to work with (unless your icon or graphic is really wide or really tall).<\/p>\n<p>Exact dimensions only matter if you want to micromanage pixel fitting (to get the sharpest possible results on low dpi screens). For example, if all your icons can fit on a 15 by 15 pixel grid, and are mostly used with those exact dimensions, go ahead and work with 15\u00d715 artboards or documents. When I\u2019m not sure, I like setting stuff on a 20\u00d720 artboard.<\/p>\n<h3>Breezy on the sides<\/h3>\n<p>Leave a little bit of space near the edges, especially for round shapes. Browsers use anti-aliasing when rendering SVG shapes, but sometimes the extra pixels from the anti-aliasing are rendered outside of the <code>viewBox<\/code> and they\u2019re cut off.<\/p>\n<figure class=\"full\"><img decoding=\"async\" src=\"http:\/\/fvsch.com\/code\/svg-icons\/how-to\/example-2.png\" alt=\"Screenshot of an round icon in Illustrator, touching the limits of the artboard\" \/><figcaption>We didn\u2019t leave any space around the icon, so there\u2019s a risk that it will be rendered with squarish sides. And if the browser doesn\u2019t render the SVG perfectly, it can get worse.<\/figcaption><\/figure>\n<p>As a rule of thumb, in a 16px or 20px icon, leave 0.5px or 1px of empty space on each side. Also, remember to export the whole artboard, not the selected paths at the center, or you will lose that white space in the export.<\/p>\n<h3>Export to SVG<\/h3>\n<ul>\n<li>In Illustrator I just use \u201cSave As\u201d and pick \u201cSVG\u201d for the format.<\/li>\n<li>In Inkscape you can \u201cSave As\u201d and pick \u201cOptimized SVG\u201d.<\/li>\n<li>In Sketch you can select an artboard, click \u201cMake Exportable\u201d on the bottom right, and pick \u201cSVG\u201d for the format.<\/li>\n<\/ul>\n<h3>Learn some SVG<\/h3>\n<p>You definitely should learn some SVG basics, and be able to read and understand the structure of simple SVG files. At the very least you should know about these:<\/p>\n<ul>\n<li>Elements: <code>&lt;svg&gt;<\/code>, <code>&lt;symbol&gt;<\/code>, <code>&lt;g&gt;<\/code>, <code>&lt;path&gt;<\/code>.<\/li>\n<li>Attributes: <code>d<\/code>, <code>fill<\/code>, <code>stroke<\/code>, <code>stroke-width<\/code>.<\/li>\n<\/ul>\n<p>Note that when you export SVG from a design tool, it will often have a little bit or a lot of unnecessary markups, metadata, and such. It can also have excessively precise path data (in the <code>d<\/code> attribute). Try using a tool such as <a href=\"https:\/\/jakearchibald.github.io\/svgomg\/\" target=\"_blank\" rel=\"nofollow noopener\">SVGOMG<\/a> and compare the before and after code to see what gets removed or simplified.<\/p>\n<h3>Remove color data<\/h3>\n<p>For single-color icons, make sure that:<\/p>\n<ol>\n<li>In your source file, the paths are black (<code>#000000<\/code>).<\/li>\n<li>In the exported code, there are no <code>fill<\/code> attributes.<\/li>\n<\/ol>\n<p>If we have hardcoded fills in the SVG source, we won\u2019t be able to change those colors from our CSS code. So, it\u2019s generally best to remove them, at least for single-color icons.<\/p>\n<p>Illustrator doesn\u2019t output <code>fill<\/code> attributes for paths that are fully black (<code>#000000<\/code>). Sketch does, so you may have to open the exported SVG code and manually remove the <code>fill=\"#000000\"<\/code> attributes.<\/p>\n<h2 id=\"section-sprite\">Making an SVG sprite<\/h2>\n<p>This part has a lot of code, but it\u2019s actually not complex at all. We want to create a SVG document containing <code>&lt;symbol&gt;<\/code> elements. Each <code>&lt;symbol&gt;<\/code> must have an <code>id<\/code> attribute, a <code>viewBox<\/code> attribute, and will contain the icon\u2019s <code>&lt;path\/&gt;<\/code> elements (or other graphical elements).<\/p>\n<p>I\u2019m calling this SVG document a sprite (in reference to <a href=\"https:\/\/en.wikipedia.org\/wiki\/Sprite_%28computer_graphics%29\" target=\"_blank\" rel=\"nofollow noopener\">sprites in computer games<\/a> and CSS), but it may also be called a sprite sheet, or a symbol store.<\/p>\n<p>Here\u2019s a sprite with just one icon:<\/p>\n<pre><code class=\"language-markup\">&lt;svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\"&gt;\n  &lt;symbol id=\"cross\" viewBox=\"0 0 20 20\"&gt;\n    &lt;path d=\"M17.1 5.2l-2.6-2.6-4.6 4.7-4.7-4.7-2.5 2.6 4.7 4.7-4.7 4.7 2.5 2.5 4.7-4.7 4.6 4.7 2.6-2.5-4.7-4.7\"\/&gt;\n  &lt;\/symbol&gt;\n&lt;\/svg&gt;<\/code><\/pre>\n<h3>Adding an icon to our sprite<\/h3>\n<p>Say that Illustrator gave us this code for the icon shown above:<\/p>\n<pre><code class=\"language-markup\">&lt;?xml version=\"1.0\" encoding=\"utf-8\"?&gt;\n&lt;!-- Generator: Adobe Illustrator 19.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  --&gt;\n&lt;svg version=\"1.1\" id=\"Layer_1\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" xmlns:xlink=\"http:\/\/www.w3.org\/1999\/xlink\" x=\"0px\" y=\"0px\"\n  viewBox=\"0 0 15 15\" style=\"enable-background:new 0 0 15 15;\" xml:space=\"preserve\"&gt;\n  &lt;path id=\"ARROW\" d=\"M7.5,0.5c3.9,0,7,3.1,7,7c0,3.9-3.1,7-7,7c-3.9,0-7-3.1-7-7l0,0C0.5,3.6,3.6,0.5,7.5,0.5 C7.5,0.5,7.5,0.5,7.5,0.5L7.5,0.5L7.5,0.5z M6.1,4.7v5.6l4.2-2.8L6.1,4.7z\"\/&gt;\n&lt;\/svg&gt;<\/code><\/pre>\n<p>We can simplify it quite a bit (manually or using <a href=\"https:\/\/jakearchibald.github.io\/svgomg\/\" target=\"_blank\" rel=\"nofollow noopener\">SVGOMG<\/a>), only keeping the <code>viewBox<\/code> attribute and essential data:<\/p>\n<pre><code class=\"language-markup\">&lt;svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 15 15\"&gt;\n  &lt;path d=\"M7.5,0.5c3.9,0,7,3.1,7,7c0,3.9-3.1,7-7,7c-3.9,0-7-3.1-7-7l0,0C0.5,3.6,3.6,0.5,7.5,0.5 C7.5,0.5,7.5,0.5,7.5,0.5L7.5,0.5L7.5,0.5z M6.1,4.7v5.6l4.2-2.8L6.1,4.7z\"\/&gt;\n&lt;\/svg&gt;<\/code><\/pre>\n<p>Now we can copy-paste it in our sprite. We need to transform the <code>&lt;svg viewBox=\"\u2026\"&gt;<\/code> element into a <code>&lt;symbol id=\"\u2026\" viewBox=\"\u2026\"&gt;<\/code> element and inserted it manually into our sprite:<\/p>\n<pre><code class=\"language-markup\">&lt;svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\"&gt;\n  &lt;symbol id=\"cross\" viewBox=\"0 0 20 20\"&gt;\n    &lt;path d=\"M17.1 5.2l-2.6-2.6-4.6 4.7-4.7-4.7-2.5 2.6 4.7 4.7-4.7 4.7 2.5 2.5 4.7-4.7 4.6 4.7 2.6-2.5-4.7-4.7\"\/&gt;\n  &lt;\/symbol&gt;\n  &lt;symbol id=\"play\" viewBox=\"0 0 15 15\"&gt;\n    &lt;path d=\"M7.5,0.5c3.9,0,7,3.1,7,7c0,3.9-3.1,7-7,7c-3.9,0-7-3.1-7-7l0,0C0.5,3.6,3.6,0.5,7.5,0.5 C7.5,0.5,7.5,0.5,7.5,0.5L7.5,0.5L7.5,0.5z M6.1,4.7v5.6l4.2-2.8L6.1,4.7z\"\/&gt;\n  &lt;\/symbol&gt;\n&lt;\/svg&gt;<\/code><\/pre>\n<p>You can do this manually for all your icons, but there are tools that automate the process. We use <a href=\"https:\/\/github.com\/jkphl\/gulp-svg-sprite\" target=\"_blank\" rel=\"nofollow noopener\">gulp-svg-sprite<\/a> (here\u2019s an <a href=\"https:\/\/web.archive.org\/web\/20170313062017\/https:\/\/gist.github.com\/fvsch\/8a407c04156093c5f661\" target=\"_blank\" rel=\"nofollow noopener\">example gulpfile.js<\/a> that we use, if you\u2019re curious), but there are several graphical and command-line tools that export SVG symbol sprites, including <a href=\"https:\/\/icomoon.io\/\" target=\"_blank\" rel=\"nofollow noopener\">Icomoon<\/a>.<\/p>\n<h3>Pro tip: Keep a folder with your source icons<\/h3>\n<p>If you make your sprite manually, I recommend keeping a folder with individual SVG icons:<\/p>\n<pre><code>assets\/\n    icons\/\n        cross.svg\n        play.svg\n        search.svg\n        ...\npublic\/\n    sprite\/\n        icons.svg<\/code><\/pre>\n<p>Then if you need to rebuild the <code>icons.svg<\/code> or change an individual icon, you have the right sources to work with. Be careful to not let your sprite and your source folder get out of sync.<\/p>\n<p>Of course if you use a build process (with Grunt or Gulp or something else), you can feed it your source folder and let it build the sprite directly.<\/p>\n<h2 id=\"section-adding\">Adding icons to your pages<\/h2>\n<p>The bad news is that in order to use our SVG icons, we have to put them in the HTML. No CSS backgrounds, no <code>::before<\/code> pseudo-elements. The good news is that it\u2019s not too verbose:<\/p>\n<pre><code class=\"language-markup\">&lt;svg&gt;&lt;use xlink:href=\"\/path\/to\/icons.svg#play\"&gt;&lt;\/use&gt;&lt;\/svg&gt;<\/code><\/pre>\n<figure><\/figure>\n<h3>Providing alt text for your icons<\/h3>\n<p>There are a few possible solutions for adding accessible text to an icon. Based on our own screen reader tests, this is what we use.<\/p>\n<p>First, if we don\u2019t want to add any alt text (often because there\u2019s already relevant text in context), we use <code>aria-hidden=\"true\"<\/code> to make sure screen readers don\u2019t try reading the icon out loud:<\/p>\n<pre><code class=\"language-markup\">&lt;a href=\"\/news\/\"&gt;\n  &lt;svg aria-hidden=\"true\"&gt;\n    &lt;use xlink:href=\"\/path\/to\/icons.svg#newspaper\"&gt;&lt;\/use&gt;\n  &lt;\/svg&gt;\n  Latest News\n&lt;\/a&gt;<\/code><\/pre>\n<p>The second use case we have a lot is: there\u2019s a link or a button whose only content is an icon. That\u2019s when we use <code>aria-label<\/code>, preferably on the <code>&lt;a&gt;<\/code> or <code>&lt;button&gt;<\/code> element:<\/p>\n<pre><code class=\"language-markup\">&lt;a href=\"\/news\/\" aria-label=\"Latest News\"&gt;\n  &lt;svg aria-hidden=\"true\"&gt;\n    &lt;use xlink:href=\"\/path\/to\/icons.svg#newspaper\"&gt;&lt;\/use&gt;\n  &lt;\/svg&gt;\n&lt;\/a&gt;<\/code><\/pre>\n<p>Another option is using the <code>&lt;title&gt;<\/code> element. It\u2019s especially useful outside of interactive elements (where <code>aria-label<\/code> might not be read by some screen readers). For instance, if you show yes\/no markers in a table column, you could have:<\/p>\n<pre><code class=\"language-markup\">&lt;tr&gt;\n  &lt;svg&gt;\n    &lt;title&gt;Yes&lt;\/title&gt;\n    &lt;use xlink:href=\"\/path\/to\/icons.svg#tick\"&gt;&lt;\/use&gt;\n  &lt;\/svg&gt;\n&lt;\/tr&gt;<\/code><\/pre>\n<p>Finally, remember that:<\/p>\n<ul>\n<li>Your accessible text <em>may<\/em> change depending on context. (A \u201cmagnifying glass\u201d icon can mean \u201cShow the search form\u201d in one context, and \u201cSubmit my search query\u201d in a second context.)<\/li>\n<li>Your accessible text <em>must<\/em> change when the page\u2019s language changes.<\/li>\n<\/ul>\n<p>This is why your alt text must live <em>in the HTML where your icon is inserted<\/em>. Some articles recommend putting <code>&lt;title&gt;<\/code> elements inside your sprites, but that doesn\u2019t work in practice (also, most screen readers ignore it anyway).<\/p>\n<h3>External and inline sprites<\/h3>\n<p>Up until now, we\u2019ve shown examples of an <em>external<\/em> sprite. But some older browsers \u2014 namely, older WebKits and any version of Internet Explorer (before Edge 13) \u2014 only support <em>inline<\/em> references for <code>&lt;use xlink:href=\"#some-id\"\/&gt;<\/code>.<\/p>\n<p>This can be polyfilled with some JavaScript (<a href=\"https:\/\/github.com\/jonathantneal\/svg4everybody\" target=\"_blank\" rel=\"nofollow noopener\">svg4everybody<\/a>, <a href=\"https:\/\/github.com\/Keyamoon\/svgxuse\" target=\"_blank\" rel=\"nofollow noopener\">svgxuse<\/a>). Or you can decide to include your sprite <em>in the HTML code of every page<\/em>.<\/p>\n<pre><code class=\"language-markup\">&lt;body&gt;\n  &lt;!-- Hidden icon data --&gt;\n  &lt;svg aria-hidden=\"true\" style=\"display:none\"&gt;\n    &lt;symbol id=\"icon-play\"&gt;\u2026&lt;\/symbol&gt;\n    &lt;symbol id=\"icon-cross\"&gt;\u2026&lt;\/symbol&gt;\n    &lt;symbol id=\"icon-search\"&gt;\u2026&lt;\/symbol&gt;\n  &lt;\/svg&gt;\n\n  &lt;!-- A visible icon: --&gt;\n  &lt;button aria-label=\"Start playback\"&gt;\n    &lt;svg aria-hidden=\"true\"&gt;&lt;use xlink:href=\"#icon-play\"\/&gt;&lt;\/svg&gt;\n  &lt;\/button&gt;\n&lt;\/body&gt;<\/code><\/pre>\n<p>Each method has its pros and cons.<\/p>\n<figure class=\"full\">\n<table>\n<thead class=\"resp-remove\">\n<tr>\n<th width=\"10%\"><\/th>\n<th scope=\"col\" width=\"45%\">Inline sprite<\/th>\n<th scope=\"col\" width=\"45%\">External sprite<\/th>\n<\/tr>\n<\/thead>\n<tbody class=\"resp-linear\">\n<tr>\n<th scope=\"row\">Browser support<\/th>\n<td style=\"background: #def;\" data-label=\"Inline sprite\">Native support in IE9+.<\/p>\n<p>Older Safari\/WebKit <a href=\"https:\/\/hellbach.us\/blog\/tech\/dev\/work-svg-icons\/\" target=\"_blank\" rel=\"nofollow noopener\">needs the sprite at the beginning of the page<\/a> (before any reference).<\/td>\n<td data-label=\"External sprite\">Native support in Edge 13+, Safari 9+.<\/p>\n<p>IE and older Safari\/WebKit need a JS polyfill such as <a href=\"https:\/\/github.com\/jonathantneal\/svg4everybody\" target=\"_blank\" rel=\"nofollow noopener\">svg4everybody<\/a> or <a href=\"https:\/\/github.com\/Keyamoon\/svgxuse\" target=\"_blank\" rel=\"nofollow noopener\">svgxuse<\/a>.<\/p>\n<p>Loading an external sprite from a different domain doesn\u2019t work for now (even with CORS, see <a href=\"https:\/\/bugs.chromium.org\/p\/chromium\/issues\/detail?id=470601\" target=\"_blank\" rel=\"nofollow noopener\">Chromium bug<\/a> for instance). This can be polyfilled with JS using svgxuse.<\/td>\n<\/tr>\n<tr>\n<th scope=\"row\">Caching<\/th>\n<td data-label=\"Inline sprite\">No caching.<\/p>\n<p>The weight of your sprite (5KB, 15KB, 50KB\u2026) is added to every page.<\/td>\n<td style=\"background: #def;\" data-label=\"External sprite\">Sprite is a separate file and can be cached by the browser.<\/p>\n<p>Also it does not bloat your server-side HTTP cache.<\/td>\n<\/tr>\n<tr>\n<th scope=\"row\">Rendering speed<\/th>\n<td style=\"background: #def;\" data-label=\"Inline sprite\">Icons are rendered instantly.<\/p>\n<p>On slow networks, rendering of the page structure and content may be delayed if you have a heavy SVG sprite inserted before your content.<\/td>\n<td data-label=\"External sprite\">Possible FONSI! (Flash of No SVG Icons, but frankly I\u2019m making an acronym as a joke so don\u2019t reuse it okay?)<\/p>\n<p>Icons can be shown a bit late because a) they require a separate HTTP request and b) the browser did not prioritize loading this SVG file (using its <a href=\"http:\/\/andydavies.me\/blog\/2013\/10\/22\/how-the-browser-pre-loader-makes-pages-load-faster\/\" target=\"_blank\" rel=\"nofollow noopener\">look-ahead pre-parser<\/a>).<\/td>\n<\/tr>\n<tr>\n<th scope=\"row\">Updating<\/th>\n<td data-label=\"Inline sprite\">When you need to update your sprite, you need to make sure it\u2019s added to every single page. This regenerates all HTML pages if you use a static generator, or invalidate all caches.<\/td>\n<td style=\"background: #def;\" data-label=\"External sprite\">Only one public file is changed, so managing updates and server-side caching is a bit easier.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/figure>\n<p>I like mixing both methods, building two sprites:<\/p>\n<ol>\n<li>A small one with essential icons (e.g. main icons used in the page header), to be inlined on each page. Target size: 5KB or less.<\/li>\n<li>A bigger one, with all the project\u2019s icons, kept as an external file. Target size: 50KB or less.<\/li>\n<\/ol>\n<p>On bigger projects, we might add more external sprites when some icons can be grouped together and are only used in one part of the site or for a specific feature.<\/p>\n<h2 id=\"section-styling\">Styling icons with CSS<\/h2>\n<p>Okay now we have a SVG icons and a SVG sprite and we know how to add icons to our HTML and <strong>it took an awful lot of work<\/strong>, can we finally style our icons or what?<\/p>\n<h3>Sure, let me add some classes real quick<\/h3>\n<p>You could select all <code>&lt;svg&gt;<\/code> elements in CSS but that\u2019s not great if you use SVG for more than just icons. Also there\u2019s a Firefox bug that could bite us in the ass if we do that (<a href=\"#fx-use-selector-bug\">details below<\/a>), so let\u2019s not.<\/p>\n<p>Instead, I recommend adding two classes for each icon: a generic one, and one with the symbol\u2019s name.<\/p>\n<pre><code class=\"language-markup\">&lt;svg class=\"Icon Icon--arrow\" aria-hidden=\"true\"&gt;\n  &lt;use xlink:href=\"\/path\/to\/icons.svg#arrow\"&gt;&lt;\/use&gt;\n&lt;\/svg&gt;<\/code><\/pre>\n<p>We\u2019re using <a href=\"https:\/\/github.com\/suitcss\/suit\/blob\/master\/doc\/naming-conventions.md\" target=\"_blank\" rel=\"nofollow noopener\">SUIT CSS naming conventions<\/a>, but you can use a different style if you want (for instance <code>class=\"icon-arrow\"<\/code> is shorter, and can be targeted with a selector such as <code>svg[class*=\"icon-\"]<\/code>).<\/p>\n<h3>Default icon style<\/h3>\n<p>I recommend this default style for your icons:<\/p>\n<pre><code class=\"language-css\">.Icon {\n  \/* Allows sizing by changing the icon\u2019s font-size *\/\n  width: 1em; height: 1em;\n  \/* Nice visual alignment for icons alongside text *\/\n  vertical-align: -0.15em;\n  \/* Default path fill = value of the color property *\/\n  fill: currentColor;\n  \/* Paths and strokes that overflow the viewBox can show in IE.\n     If you use normalize.css, it already sets this. *\/\n  overflow: hidden;\n}<\/code><\/pre>\n<figure>\n<div><\/div>\n<div style=\"font-size: 500%; color: green; line-height: 1.2;\"><\/div><figcaption>Icons with our default style. The only change between the top and bottom rows is the font-size and color of the container.<\/figcaption><\/figure>\n<p>Then if you want to customize an icon in a specific context, you can have styles that look like:<\/p>\n<pre><code class=\"language-css\">.MyComponent-button .Icon {\n  \/* Change the width and height *\/\n  font-size: 40px;\n  \/* Change the fill color *\/\n  color: purple;\n  \/* Change the vertical-align if you need more precision\n     (sometimes needed for pixel-perfect rendering) *\/\n  vertical-align: top;\n}<\/code><\/pre>\n<p>With that code, by default, your SVG icons should be small and use the parent\u2019s text color.<\/p>\n<p>If the icon\u2019s shapes do not inherit the parent\u2019s text color (<code>currentColor<\/code>), check that you don\u2019t have hardcoded <code>fill<\/code> attributes in your icon\u2019s code.<\/p>\n<h3>Inherited SVG styles<\/h3>\n<p>Many SVG style properties are inherited. For instance, when we set the <code>fill<\/code> CSS property on our containing <code>&lt;svg&gt;<\/code> element, it trickles down to our <code>&lt;path&gt;<\/code>, <code>&lt;circle&gt;<\/code> and other graphic elements.<\/p>\n<p>We can use this technique for other SVG CSS properties as well. For instance, the stroke properties:<\/p>\n<pre><code class=\"language-css\">.Icon--goldstar {\n  fill: gold;\n  stroke: coral;\n  stroke-width: 5%;\n  stroke-linejoin: round;\n}<\/code><\/pre>\n<figure>\n<div style=\"font-size: 800%; line-height: 1;\"><\/div><figcaption>Star icon with default and custom styling<\/figcaption><\/figure>\n<p>Most of the time we\u2019re not going to change a lot of stuff: only the <code>fill<\/code> property for the main color, and sometimes we\u2019ll add or tweak a <code>stroke<\/code> (kinda like a border).<\/p>\n<h3>Two fill colors per icon<\/h3>\n<p>There\u2019s a fairly simple technique that allows an icon to have two sets of paths with two different <code>fill<\/code> values (aka two colors).<\/p>\n<pre><code class=\"language-markup\">&lt;symbol id=\"check\" viewBox=\"0 0 20 20\"&gt;\n  &lt;!-- Will inherit the value of the fill CSS property --&gt;\n  &lt;path d=\"\u2026\" \/&gt;\n  &lt;!-- Will inherit the value of the color CSS property --&gt;\n  &lt;path fill=\"currentColor\" d=\"\u2026\" \/&gt;\n&lt;\/symbol&gt;<\/code><\/pre>\n<pre><code class=\"language-css\">.Icon--twoColors {\n  fill: rebeccapurple;\n  color: mediumturquoise;\n}<\/code><\/pre>\n<figure>\n<div style=\"font-size: 800%; line-height: 1;\"><\/div><figcaption>Two color icon<\/figcaption><\/figure>\n<h3>Leave some room for strokes<\/h3>\n<p>Remember when we said to leave some room around your shapes? It\u2019s especially important if you plan to use strokes.<\/p>\n<pre><code class=\"language-css\">.Icon--strokespace {\n  fill: none;\n  stroke: currentColor;\n  stroke-width: 5%;\n}<\/code><\/pre>\n<p>In SVG, strokes are always painted on both sides of the path. If your path touches the limits of the viewport, half the stroke will be cut off.<\/p>\n<figure class=\"wide\">\n<div style=\"font-size: 750%; line-height: 1;\"><\/div><figcaption>In this example, the first icon has no reserved blank space on the sides, and the second icon has a small one (0.5px, for a 15px viewport).<\/figcaption><\/figure>\n<h3>Beware the <code>stroke-width<\/code><\/h3>\n<p>Giving the right size to a stroke can be challenging. Look at these two examples where we set <code>stroke-width:1px<\/code> on the <code>&lt;svg&gt;<\/code> element:<\/p>\n<figure class=\"wide\">\n<div style=\"font-size: 800%; line-height: 1; color: hotpink; stroke-width: 1px;\"><\/div>\n<\/figure>\n<p>What\u2019s happening? The <code>stroke-width<\/code> property takes a \u201clength\u201d value, but that value is relative to the <em>local coordinates<\/em> of your icon. In the examples above:<\/p>\n<ol>\n<li>The first icon has a 20px by 20px <code>viewBox<\/code>. So a 1px stroke is 1\/20th of the icon\u2019s size, big but not too big.<\/li>\n<li>The second icon has a 500px by 500px <code>viewBox<\/code>. So, a 1px stroke is 1\/500th of the icon\u2019s size, and that is really small.<\/li>\n<\/ol>\n<p>If all your icons use a similar <code>viewBox<\/code>, that\u2019s not a problem. But if they can differ wildly, using pixel or unitless values (<code>stroke-width:1<\/code>) is out. What should we do?<\/p>\n<p>Percentages can be good. Same example, with <code>stroke-width:5%<\/code>:<\/p>\n<figure class=\"wide\">\n<div style=\"font-size: 800%; line-height: 1; color: darkturquoise; stroke-width: 5%;\"><\/div>\n<\/figure>\n<p>Now that\u2019s better, but what does the percentage correspond to? Is it the width, the height of the icon? Turns out it\u2019s relative to the diagonal, but with a <a href=\"https:\/\/svgwg.org\/svg2-draft\/coords.html#Units\" target=\"_blank\" rel=\"nofollow noopener\">funky formula (spec)<\/a> (diagonal length divided by the square root of 2, which is close to 1.4).<\/p>\n<p>What does it mean? Well for square icons the result of that formula is the side of the square. So <code>1%<\/code> means \u201cone percent of the width or one percent of the height\u201d. Nice and simple.<\/p>\n<p>For wider or taller icons, though, the result can change a bit:<\/p>\n<figure class=\"wide\">\n<div style=\"font-size: 800%; line-height: 1; stroke-width: 5%;\"><\/div><figcaption>In the second icon (aspect ratio of 2:1, shown with the same height and twice as large), the <code>stroke-width:5%<\/code> gives us a stroke that is roughly: 7.91% of the height and 3.95% of the width.<\/figcaption><\/figure>\n<p>All things considered, I recommend using percentage values for <code>stroke-width<\/code>. If you stick to a square or sharish icon, you can use percent values with the understanding that they mean, roughly, \u201cpercentage of the width of the icon\u201d.<\/p>\n<h3>Can I style the <code>&lt;svg&gt;<\/code> container?<\/h3>\n<p>If you want a background color, borders, padding, etc., you should try to style the element containing the icon, and not the <code>&lt;svg&gt;<\/code> element itself. Although it seems to work well in the latest browsers, there are known rendering issues in older WebKit browsers, so I recommend styling a wrapping element (<code>&lt;span&gt;<\/code>, <code>&lt;button&gt;<\/code>, <code>&lt;a&gt;<\/code>, etc.).<\/p>\n<figure>\n<div style=\"font-size: 700%; line-height: 1;\"><span class=\"purpleIconBox\">\u00a0<\/span><\/div><figcaption>Box styles applied on the <code>&lt;svg&gt;<\/code> element directly or on a wrapper element. Most browsers should render the elements identically, but slightly older WebKit versions will take offense.<\/figcaption><\/figure>\n<h3>Not everything is an icon<\/h3>\n<p>Just because something is SVG, it doesn\u2019t mean it should go inside your SVG sprite. For instance:<\/p>\n<ul>\n<li>Illustrations that you don\u2019t need to style: consider using the <code>&lt;img&gt;<\/code> element.<\/li>\n<li>Illustrations that you want to animate: consider inlining the whole <code>&lt;svg&gt;<\/code> in your page, so you can select and style specific groups or paths or shapes, animate some parts, etc.<\/li>\n<\/ul>\n<p>As a rule of thumb, if it\u2019s a big illustration that you need to show at 100px by 100px or much bigger, or if it contains dozens of elements, it might not be an \u201cicon\u201d.<\/p>\n<h2 id=\"section-advanced\">Advanced topics<\/h2>\n<p>With the previous sections, you should have everything you need to know to use SVG icons. This next section adds some more advanced information, with perhaps fewer real-world applications.<\/p>\n<h3>Preloading external sprites<\/h3>\n<p>In the \u201cAdding icons to your pages\u201d section we said that icons from an external sprite can show up a bit late, partly because of the browser\u2019s pre-load scanner (or look-ahead pre-parser or whatever) not picking up that <code>&lt;use xlink:href=\"\/path\/to\/icons.svg#something\"&gt;&lt;\/use&gt;<\/code> means there is an important file to load early.<\/p>\n<p>What can we do about this?<\/p>\n<ul>\n<li>Standard and future solution: add <code>&lt;link rel=\"preload\" href=\"\/path\/to\/icons.svg\" as=\"image\"&gt;<\/code> in the <code>&lt;head&gt;<\/code> of the page (<a href=\"https:\/\/www.smashingmagazine.com\/2016\/02\/preload-what-is-it-good-for\/\" target=\"_blank\" rel=\"nofollow noopener\">details on preload<\/a>, support coming to a Chrome near you and hopefully in more browsers in the future).<\/li>\n<li>Old school solution: add <code>&lt;img style=\"display:none\" alt=\"\" src=\"\/path\/to\/icons.svg\"&gt;<\/code> at the start of the <code>&lt;body&gt;<\/code>.<\/li>\n<\/ul>\n<p>I haven\u2019t actually tested those solutions, generally the \u201cinline + external\u201d compromise gives good enough performance that we don\u2019t have to rely on preloading. But it\u2019s worth investigating.<\/p>\n<h3>More than two colors with CSS Custom Properties<\/h3>\n<p>So, we can easily change the colors of our SVG icons from CSS, for single-color icons (easy) and two-color icons (takes some preparation). Is there a way we could have multicolor icons with <em>more than two customizable colors<\/em>?<\/p>\n<p>We might be able to do that with <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/CSS\/Using_CSS_variables\" target=\"_blank\" rel=\"nofollow noopener\">CSS Custom Properties<\/a> (aka CSS Variables). This requires a lot of preparation on the SVG side:<\/p>\n<pre><code class=\"language-markup\">&lt;symbol id=\"iconic-aperture\" viewBox=\"0 0 128 128\"&gt;\n  &lt;path fill=\"var(--icon-color1)\" d=\"\u2026\" \/&gt;\n  &lt;path fill=\"var(--icon-color2)\" d=\"\u2026\" \/&gt;\n  &lt;path fill=\"var(--icon-color3)\" d=\"\u2026\" \/&gt;\n  &lt;path fill=\"var(--icon-color4)\" d=\"\u2026\" \/&gt;\n  &lt;path fill=\"var(--icon-color5)\" d=\"\u2026\" \/&gt;\n  &lt;path fill=\"var(--icon-color6)\" d=\"\u2026\" \/&gt;\n&lt;\/symbol&gt;<\/code><\/pre>\n<p>For this demo, I stole an icon from the excellent <a href=\"https:\/\/web.archive.org\/web\/20221218014722\/http:\/\/useiconic.com\/\" target=\"_blank\" rel=\"nofollow noopener\">Iconic<\/a>, which offers responsive, multicolor SVG icons (powered by CSS and some JS, as I understand). I tried to mimic their own multicolor example for this icon, I hope they don\u2019t mind.<\/p>\n<figure class=\"wide\"><span style=\"font-size: 800%; line-height: 1;\"><br \/>\n<\/span><br \/>\n<span style=\"font-size: 800%; line-height: 1;\"><br \/>\n<\/span><br \/>\n<span style=\"font-size: 800%; line-height: 1;\"><br \/>\n<\/span><figcaption>One symbol using 6 different CSS custom properties.<br \/>\nSee in Firefox, Chrome, or Safari 9.1+<\/figcaption><\/figure>\n<p>It works fairly well <a href=\"http:\/\/caniuse.com\/#feat=css-variables\" target=\"_blank\" rel=\"nofollow noopener\">in supported browsers<\/a>. There\u2019s only one icon: the first instance doesn\u2019t declare the expected variables, so it falls back to currentColor; the next two instances each declare a set of variable values.<\/p>\n<h3>Sorry, no gradient fill<\/h3>\n<p>With all the possibilities for fill colors, surely we can do something simple like use a gradient as a <code>fill<\/code>?<\/p>\n<p>Sadly, we can\u2019t. The <code>fill<\/code> property doesn\u2019t accept image values, and CSS\u2019s <code>linear-gradient()<\/code> function generates an image value.<\/p>\n<p>SVG has its own syntax for coding and using gradients. But using it would take us rather far from <em>simple<\/em> SVG icons, so I\u2019m going to just say: it might be done, but it\u2019ll take same work and you\u2019ll have to hardcode at least some parameters. Give it a try if you want. \ud83d\ude42<\/p>\n<h3>Selecting individual shapes or paths<\/h3>\n<p>We\u2019ve looked at ways to customize fills, strokes etc. for all paths from a <code>&lt;symbol&gt;<\/code>, and 2 or more colors from different paths. But what if we could select specific paths (using classes maybe) directly in the <em>instance<\/em> of the <code>&lt;symbol&gt;<\/code>? Is it possible?<\/p>\n<p>Right now the answer is: yes and no.<\/p>\n<ol>\n<li>If you use external sprites, you can\u2019t select individual paths (or other elements) inside a used <code>&lt;symbol&gt;<\/code>.<\/li>\n<li>If you inline your sprite, you can select and style elements inside the sprite, but those styles will apply to <em>all instances<\/em> of the symbols.<\/li>\n<\/ol>\n<p>So even with an inlined sprite, you could do this:<\/p>\n<pre><code class=\"language-css\">#my-symbol .style1 {\n  \/* Styles for one group of paths *\/\n}\n#my-symbol .style2 {\n  \/* Styles for another *\/\n}<\/code><\/pre>\n<p>But you can\u2019t do this:<\/p>\n<pre><code class=\"language-css\">.MyComponent-button .Icon .style1 {\n  \/* For 1 group of paths for this icon in this context *\/\n}\n.MyComponent-button .Icon .style2 {\n  \/* For another group *\/\n}<\/code><\/pre>\n<p>Except in Firefox! Turns out that in Firefox, selecting inside an <em>instance<\/em> of the symbol works perfectly. The only problem is that it\u2019s a non-standard behavior, so there\u2019s no chance that other browsers will gain the same capabilities. It would actually be a good thing if Firefox fixed this bug they have.<\/p>\n<p>For the record, when we use the <code>&lt;use&gt;<\/code> element, browsers create a Shadow DOM where they duplicate the contents of the <code>&lt;symbol&gt;<\/code> we\u2019re using. Schematically, it looks like this:<\/p>\n<pre><code class=\"language-markup\">&lt;svg class=\"Icon Icon--something\" aria-hidden=\"true\"&gt;\n  &lt;use xlink:href=\"#something\"&gt;\n    &lt;svg viewBox=\"0 0 20 20\"&gt;\n      &lt;path d=\"\u2026\" \/&gt;\n    &lt;\/svg&gt;\n  &lt;\/use&gt;\n&lt;\/svg&gt;<\/code><\/pre>\n<p>Firefox allows CSS selectors to reach inside this Shadow DOM, but it shouldn\u2019t.<\/p>\n<p>In the future, there might be a standard way that allows selecting through a Shadow DOM, but that\u2019s not sure at all (there used to be the <code>\/deep\/<\/code> combinator, but it was removed).<\/p>\n<h3 id=\"fx-use-selector-bug\">Avoid targeting the <code>svg<\/code> element<\/h3>\n<p>It will create issues in Firefox. Why? As explained in the previous section, Firefox currently allows selection in the Shadow DOM created by the <code>&lt;use&gt;<\/code> element. So if you have this CSS:<\/p>\n<pre><code class=\"language-css\">svg {\n  fill: red;\n}\n.Icon--something {\n  fill: green;\n}<\/code><\/pre>\n<p>In Firefox the styles resolve as:<\/p>\n<pre><code class=\"language-markup\">&lt;svg class=\"Icon Icon--something\" aria-hidden=\"true\" fill=\"green;\"&gt;\n  &lt;use xlink:href=\"#something\"&gt;\n    &lt;svg viewBox=\"0 0 20 20\" fill=\"red;\"&gt;\n      &lt;path d=\"\u2026\" \/&gt;\n    &lt;\/svg&gt;\n  &lt;\/use&gt;\n&lt;\/svg&gt;<\/code><\/pre>\n<p>In other browsers, the icon will be green (as you expect), but in Firefox it will be red because the inner <code>&lt;svg&gt;<\/code> element will get styles from the first rule-set (<code>fill: red<\/code>).<\/p>\n<p><!-- Add IE support for external sprite demoes --><br \/>\n<script>\/\/ < ![CDATA[\n\/\/ < ![CDATA[\n!function(a,b){\"function\"==typeof define&#038;&#038;define.amd?define([],function(){return a.svg4everybody=b()}):\"object\"==typeof exports?module.exports=b():a.svg4everybody=b()}(this,function(){function a(a,b){if(b){var c=document.createDocumentFragment(),d=!a.getAttribute(\"viewBox\")&#038;&#038;b.getAttribute(\"viewBox\");d&#038;&#038;a.setAttribute(\"viewBox\",d);for(var e=b.cloneNode(!0);e.childNodes.length;)c.appendChild(e.firstChild);a.appendChild(c)}}function b(b){b.onreadystatechange=function(){if(4===b.readyState){var c=b._cachedDocument;c||(c=b._cachedDocument=document.implementation.createHTMLDocument(\"\"),c.body.innerHTML=b.responseText,b._cachedTarget={}),b._embeds.splice(0).map(function(d){var e=b._cachedTarget[d.id];e||(e=b._cachedTarget[d.id]=c.getElementById(d.id)),a(d.svg,e)})}},b.onreadystatechange()}function c(c){function d(){for(var c=0;c<l.length;){var g=l[c],h=g.parentNode;if(h&#038;&#038;\/svg\/i.test(h.nodeName)){var i=g.getAttribute(\"xlink:href\");if(e&#038;&#038;(!f.validate||f.validate(i,h,g))){h.removeChild(g);var m=i.split(\"#\"),n=m.shift(),o=m.join(\"#\");if(n.length){var p=j[n];p||(p=j[n]=new XMLHttpRequest,p.open(\"GET\",n),p.send(),p._embeds=[]),p._embeds.push({svg:h,id:o}),b(p)}else a(h,document.getElementById(o))}}else++c}k(d,67)}var e,f=Object(c),g=\/\\bTrident\\\/[567]\\b|\\bMSIE (?:9|10)\\.0\\b\/,h=\/\\bAppleWebKit\\\/(\\d+)\\b\/,i=\/\\bEdge\\\/12\\.(\\d+)\\b\/;e=\"polyfill\"in f?f.polyfill:g.test(navigator.userAgent)||(navigator.userAgent.match(i)||[])[1]&lt;10547||(navigator.userAgent.match(h)||[])[1]&lt;537;var j={},k=window.requestAnimationFrame||setTimeout,l=document.getElementsByTagName(\"use\");e&#038;&#038;d()}return c}); svg4everybody();\n\/\/ ]]><\/script><\/p>\n<p><em>Source: <a href=\"http:\/\/fvsch.com\/code\/svg-icons\/how-to\/\" target=\"_blank\" rel=\"nofollow noopener\">fvsch<\/a><\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>check source as stupid wordpress erase svg There are many ways to use SVG icons in HTML and CSS, and I haven\u2019t tried them all. This is how we do it in our small front-end team at Kaliop. It works &hellip; <a href=\"https:\/\/hellbach.us\/blog\/tech\/dev\/work-svg-icons\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[29],"tags":[],"class_list":["post-1981","post","type-post","status-publish","format-standard","hentry","category-dev"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.9 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>How to work with SVG icons - Hellbach blog<\/title>\n<meta name=\"description\" content=\"A technical summary of how we use SVG icons for web pages\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/hellbach.us\/blog\/tech\/dev\/work-svg-icons\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How to work with SVG icons\" \/>\n<meta property=\"og:description\" content=\"A technical summary of how we use SVG icons for web pages\" \/>\n<meta property=\"og:url\" content=\"https:\/\/hellbach.us\/blog\/tech\/dev\/work-svg-icons\/\" \/>\n<meta property=\"og:site_name\" content=\"Hellbach blog\" \/>\n<meta property=\"article:published_time\" content=\"2016-03-31T00:14:22+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-01-27T02:47:26+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/fvsch.com\/code\/svg-icons\/how-to\/example-1.png\" \/>\n<meta name=\"author\" content=\"alex\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:title\" content=\"How to work with SVG icons\" \/>\n<meta name=\"twitter:description\" content=\"A technical summary of how we use SVG icons for web pages\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"alex\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"17 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/hellbach.us\/blog\/tech\/dev\/work-svg-icons\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/hellbach.us\/blog\/tech\/dev\/work-svg-icons\/\"},\"author\":{\"name\":\"alex\",\"@id\":\"https:\/\/hellbach.us\/blog\/#\/schema\/person\/9bf1a63e253268c42a6e9db64611c507\"},\"headline\":\"How to work with SVG icons\",\"datePublished\":\"2016-03-31T00:14:22+00:00\",\"dateModified\":\"2023-01-27T02:47:26+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/hellbach.us\/blog\/tech\/dev\/work-svg-icons\/\"},\"wordCount\":3258,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/hellbach.us\/blog\/#\/schema\/person\/9bf1a63e253268c42a6e9db64611c507\"},\"image\":{\"@id\":\"https:\/\/hellbach.us\/blog\/tech\/dev\/work-svg-icons\/#primaryimage\"},\"thumbnailUrl\":\"http:\/\/fvsch.com\/code\/svg-icons\/how-to\/example-1.png\",\"articleSection\":[\"Dev\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/hellbach.us\/blog\/tech\/dev\/work-svg-icons\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/hellbach.us\/blog\/tech\/dev\/work-svg-icons\/\",\"url\":\"https:\/\/hellbach.us\/blog\/tech\/dev\/work-svg-icons\/\",\"name\":\"How to work with SVG icons - Hellbach blog\",\"isPartOf\":{\"@id\":\"https:\/\/hellbach.us\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/hellbach.us\/blog\/tech\/dev\/work-svg-icons\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/hellbach.us\/blog\/tech\/dev\/work-svg-icons\/#primaryimage\"},\"thumbnailUrl\":\"http:\/\/fvsch.com\/code\/svg-icons\/how-to\/example-1.png\",\"datePublished\":\"2016-03-31T00:14:22+00:00\",\"dateModified\":\"2023-01-27T02:47:26+00:00\",\"description\":\"A technical summary of how we use SVG icons for web pages\",\"breadcrumb\":{\"@id\":\"https:\/\/hellbach.us\/blog\/tech\/dev\/work-svg-icons\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/hellbach.us\/blog\/tech\/dev\/work-svg-icons\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/hellbach.us\/blog\/tech\/dev\/work-svg-icons\/#primaryimage\",\"url\":\"http:\/\/fvsch.com\/code\/svg-icons\/how-to\/example-1.png\",\"contentUrl\":\"http:\/\/fvsch.com\/code\/svg-icons\/how-to\/example-1.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/hellbach.us\/blog\/tech\/dev\/work-svg-icons\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/hellbach.us\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How to work with SVG icons\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/hellbach.us\/blog\/#website\",\"url\":\"https:\/\/hellbach.us\/blog\/\",\"name\":\"Hellbach blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/hellbach.us\/blog\/#\/schema\/person\/9bf1a63e253268c42a6e9db64611c507\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/hellbach.us\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/hellbach.us\/blog\/#\/schema\/person\/9bf1a63e253268c42a6e9db64611c507\",\"name\":\"alex\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/hellbach.us\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/9868a7f8fd709cd74cf51d978359a3ce66a47a17cd57185a9e1a4774d288e228?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/9868a7f8fd709cd74cf51d978359a3ce66a47a17cd57185a9e1a4774d288e228?s=96&d=mm&r=g\",\"caption\":\"alex\"},\"logo\":{\"@id\":\"https:\/\/hellbach.us\/blog\/#\/schema\/person\/image\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"How to work with SVG icons - Hellbach blog","description":"A technical summary of how we use SVG icons for web pages","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/hellbach.us\/blog\/tech\/dev\/work-svg-icons\/","og_locale":"en_US","og_type":"article","og_title":"How to work with SVG icons","og_description":"A technical summary of how we use SVG icons for web pages","og_url":"https:\/\/hellbach.us\/blog\/tech\/dev\/work-svg-icons\/","og_site_name":"Hellbach blog","article_published_time":"2016-03-31T00:14:22+00:00","article_modified_time":"2023-01-27T02:47:26+00:00","og_image":[{"url":"http:\/\/fvsch.com\/code\/svg-icons\/how-to\/example-1.png","type":"","width":"","height":""}],"author":"alex","twitter_card":"summary_large_image","twitter_title":"How to work with SVG icons","twitter_description":"A technical summary of how we use SVG icons for web pages","twitter_misc":{"Written by":"alex","Est. reading time":"17 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/hellbach.us\/blog\/tech\/dev\/work-svg-icons\/#article","isPartOf":{"@id":"https:\/\/hellbach.us\/blog\/tech\/dev\/work-svg-icons\/"},"author":{"name":"alex","@id":"https:\/\/hellbach.us\/blog\/#\/schema\/person\/9bf1a63e253268c42a6e9db64611c507"},"headline":"How to work with SVG icons","datePublished":"2016-03-31T00:14:22+00:00","dateModified":"2023-01-27T02:47:26+00:00","mainEntityOfPage":{"@id":"https:\/\/hellbach.us\/blog\/tech\/dev\/work-svg-icons\/"},"wordCount":3258,"commentCount":0,"publisher":{"@id":"https:\/\/hellbach.us\/blog\/#\/schema\/person\/9bf1a63e253268c42a6e9db64611c507"},"image":{"@id":"https:\/\/hellbach.us\/blog\/tech\/dev\/work-svg-icons\/#primaryimage"},"thumbnailUrl":"http:\/\/fvsch.com\/code\/svg-icons\/how-to\/example-1.png","articleSection":["Dev"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/hellbach.us\/blog\/tech\/dev\/work-svg-icons\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/hellbach.us\/blog\/tech\/dev\/work-svg-icons\/","url":"https:\/\/hellbach.us\/blog\/tech\/dev\/work-svg-icons\/","name":"How to work with SVG icons - Hellbach blog","isPartOf":{"@id":"https:\/\/hellbach.us\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/hellbach.us\/blog\/tech\/dev\/work-svg-icons\/#primaryimage"},"image":{"@id":"https:\/\/hellbach.us\/blog\/tech\/dev\/work-svg-icons\/#primaryimage"},"thumbnailUrl":"http:\/\/fvsch.com\/code\/svg-icons\/how-to\/example-1.png","datePublished":"2016-03-31T00:14:22+00:00","dateModified":"2023-01-27T02:47:26+00:00","description":"A technical summary of how we use SVG icons for web pages","breadcrumb":{"@id":"https:\/\/hellbach.us\/blog\/tech\/dev\/work-svg-icons\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/hellbach.us\/blog\/tech\/dev\/work-svg-icons\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/hellbach.us\/blog\/tech\/dev\/work-svg-icons\/#primaryimage","url":"http:\/\/fvsch.com\/code\/svg-icons\/how-to\/example-1.png","contentUrl":"http:\/\/fvsch.com\/code\/svg-icons\/how-to\/example-1.png"},{"@type":"BreadcrumbList","@id":"https:\/\/hellbach.us\/blog\/tech\/dev\/work-svg-icons\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/hellbach.us\/blog\/"},{"@type":"ListItem","position":2,"name":"How to work with SVG icons"}]},{"@type":"WebSite","@id":"https:\/\/hellbach.us\/blog\/#website","url":"https:\/\/hellbach.us\/blog\/","name":"Hellbach blog","description":"","publisher":{"@id":"https:\/\/hellbach.us\/blog\/#\/schema\/person\/9bf1a63e253268c42a6e9db64611c507"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/hellbach.us\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/hellbach.us\/blog\/#\/schema\/person\/9bf1a63e253268c42a6e9db64611c507","name":"alex","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/hellbach.us\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/9868a7f8fd709cd74cf51d978359a3ce66a47a17cd57185a9e1a4774d288e228?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/9868a7f8fd709cd74cf51d978359a3ce66a47a17cd57185a9e1a4774d288e228?s=96&d=mm&r=g","caption":"alex"},"logo":{"@id":"https:\/\/hellbach.us\/blog\/#\/schema\/person\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/hellbach.us\/blog\/wp-json\/wp\/v2\/posts\/1981","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hellbach.us\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hellbach.us\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hellbach.us\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/hellbach.us\/blog\/wp-json\/wp\/v2\/comments?post=1981"}],"version-history":[{"count":0,"href":"https:\/\/hellbach.us\/blog\/wp-json\/wp\/v2\/posts\/1981\/revisions"}],"wp:attachment":[{"href":"https:\/\/hellbach.us\/blog\/wp-json\/wp\/v2\/media?parent=1981"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hellbach.us\/blog\/wp-json\/wp\/v2\/categories?post=1981"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hellbach.us\/blog\/wp-json\/wp\/v2\/tags?post=1981"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}