{"id":1395,"date":"2021-11-17T18:05:28","date_gmt":"2021-11-17T17:05:28","guid":{"rendered":"https:\/\/nguenkam.com\/blog\/?p=1395"},"modified":"2021-11-17T23:03:44","modified_gmt":"2021-11-17T22:03:44","slug":"using-an-svg-sprite-icon-system-in-angular","status":"publish","type":"post","link":"https:\/\/nguenkam.com\/blog\/index.php\/2021\/11\/17\/using-an-svg-sprite-icon-system-in-angular\/","title":{"rendered":"Using an SVG sprite icon system in Angular"},"content":{"rendered":"\n<p>I used to work with <em><span class=\"has-inline-color has-vivid-cyan-blue-color\">icon-fonts<\/span><\/em>, much time. Lots of projects ( Site  or applications)  really need a system for icons, and <em><span class=\"has-inline-color has-vivid-cyan-blue-color\">icon-fonts<\/span><\/em> offer a very fine system.  But there is an another alternative to reference an icon :  <span class=\"has-inline-color has-vivid-red-color\"><strong><em>using inline SVG and the&nbsp;<code>&lt;use&gt;<\/code>&nbsp;element .<\/em><\/strong><\/span><\/p>\n\n\n\n<p>Whether it\u2019s <em><span class=\"has-inline-color has-vivid-cyan-blue-color\"><strong>icon-fonts<\/strong><\/span><\/em> or <span class=\"has-inline-color has-vivid-red-color\"><strong><em>SVG<\/em><\/strong><\/span> <span class=\"has-inline-color has-vivid-red-color\"><em><strong>sprites <\/strong><\/em><\/span>you use as icon sets in your application is your decision. However, we\u2019ll cover some advantages that SVG sprites have, but most importantly how you can implement them in Angular.<\/p>\n\n\n\n<h4>Why an SVG sprite icon system?<\/h4>\n\n\n\n<ol><li><em>SVGs don\u2019t experience the problem of anti-aliasing like fonts do, so your icon will always be crisp<\/em><\/li><li><em>You can manipulate different elements within an SVG<\/em><\/li><li><em>Multi-colour support<\/em><\/li><li><em>More &amp; easier control over the positioning of an icon (fonts are under the influence of&nbsp;<code>vertical-align<\/code>,&nbsp;<code>line-height<\/code>,&nbsp;<code>letter-spacing<\/code>,&nbsp;<code>word-spacing<\/code>, \u2026)<\/em><\/li><\/ol>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h4>Setup<\/h4>\n\n\n\n<h4><span class=\"has-inline-color has-vivid-red-color\">1.  Icon set<\/span><\/h4>\n\n\n\n<p>First, we need&nbsp;an icon set. (Combining the .svg files).<\/p>\n\n\n\n<p>\u00a0Let\u00b4s do it manualy. First we create a file named \u00a0<code>icons-defs.svg<\/code>\u00a0(we can give any name to the svg file). <\/p>\n\n\n\n<p>The content of the file should just be an\u00a0<code>&lt;svg><\/code>\u00a0tag, with a\u00a0<code>&lt;defs><\/code>\u00a0tag (which just means you are defining stuff to use later), and then a bunch of\u00a0 <strong>&lt;symbol><\/strong> tags. Each\u00a0<strong>&lt;symbol><\/strong>\u00a0tag will have a unique ID, and will wrap all the paths for each icon.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;svg&gt;\n  &lt;defs&gt;\n\n    &lt;symbol id=\"shape-icon-1\"&gt;\n      &lt;!-- all the paths and shapes and whatnot for this icon --&gt;\n    &lt;symbol&gt;\n\n    &lt;symbol id=\"shape-icon-2\"&gt;\n      &lt;!-- all the paths and shapes and whatnot for this icon --&gt;\n    &lt;symbol&gt;\n\n    &lt;!-- etc --&gt;\n\n  &lt;\/defs&gt;\n&lt;\/svg&gt;<\/code><\/pre>\n\n\n\n<p>As we see, we can do that by hand, but of course that\u2019s a bit laborious. And there are  lot of tools who can assist us to generate our<em> icon-set<\/em> more quickly. <\/p>\n\n\n\n<h4>Another way: IcoMoon<\/h4>\n\n\n\n<p>We will use&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/icomoon.io\/\" target=\"_blank\">icomoon<\/a>&nbsp;to create an <em>icon-set<\/em>. Go to&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/icomoon.io\/\" target=\"_blank\">icomoon\u2019s<\/a>&nbsp;website and click on the purple button \u201cIcoMoon App\u201d.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" src=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/11\/1_JRL306sgquOa29mdnFaG5A.png\" alt=\"\" class=\"wp-image-1396\" width=\"700\" height=\"424\" srcset=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/11\/1_JRL306sgquOa29mdnFaG5A.png 700w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/11\/1_JRL306sgquOa29mdnFaG5A-300x182.png 300w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/figure>\n\n\n\n<p>Next, click on \u201cGenerate SVG &amp; More\u201d.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"700\" height=\"436\" src=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/11\/1_8eIjDm6wCL7tcKEyaFyQrw.png\" alt=\"\" class=\"wp-image-1398\" srcset=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/11\/1_8eIjDm6wCL7tcKEyaFyQrw.png 700w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/11\/1_8eIjDm6wCL7tcKEyaFyQrw-300x187.png 300w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/figure>\n\n\n\n<p>Now we can download the generated SVG icon set<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"700\" height=\"435\" src=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/11\/1_OSWd4giOh8XxnsDYR8KsgA.png\" alt=\"\" class=\"wp-image-1399\" srcset=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/11\/1_OSWd4giOh8XxnsDYR8KsgA.png 700w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/11\/1_OSWd4giOh8XxnsDYR8KsgA-300x186.png 300w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/figure>\n\n\n\n<p>When the download is successful,  let\u00b4s unzip the file. There is a file called<em><strong><span class=\"has-inline-color has-vivid-red-color\">&nbsp;<code>symbol-defs.svg<\/code><\/span><\/strong><\/em>. This is the <em><strong>SVG sprite <\/strong><\/em>we\u2019re going to use. So copy &amp; paste this file inside&nbsp;<code><em><strong>src\/assets<\/strong><\/em><\/code>&nbsp;folder of the Angular app.<\/p>\n\n\n\n<p>We now have everything set up to use the icon set, and we can  use it like this: <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;svg&gt; &lt;use attr.xlink:href=\"assets\/symbol-defs.svg#icon-images\"&gt;&lt;\/use&gt; &lt;\/svg&gt;<\/code><\/pre>\n\n\n\n<p>if we  start the app right now, we should see the following.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"700\" height=\"109\" src=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/11\/1_8npdn40_EaXqlptbwxDPIA.png\" alt=\"\" class=\"wp-image-1400\" srcset=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/11\/1_8npdn40_EaXqlptbwxDPIA.png 700w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/11\/1_8npdn40_EaXqlptbwxDPIA-300x47.png 300w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/figure>\n\n\n\n<h5>Explanation: <\/h5>\n\n\n\n<p>We created all necessary html tags to display an SVG image inline, but with a twist. We defined that our source is&nbsp;<code><em><strong>assets\/symbol-defs.svg<\/strong><\/em><\/code>, which is our sprite file. We didn\u2019t want to show every single icon in our sprite so we defined which icon we wanted to show. We managed this by suffixing our source with<em><strong>&nbsp;<code>#icon-images<\/code><\/strong><\/em>. Whenever we want to change our icon we just change the suffix to the name of the icon that is defined in our SVG sprite file.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h4><span class=\"has-inline-color has-vivid-red-color\">2.  Implementation time <\/span><\/h4>\n\n\n\n<p>Let us create a new component file called:&nbsp;<code><em><span class=\"has-inline-color has-vivid-cyan-blue-color\"><strong>svg-icon.component.ts<\/strong><\/span><\/em><\/code>, and add the following content.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import { Component, Input, OnInit } from '@angular\/core';\n\n@Component({\n  selector: 'bvg-icon',\n  template: '&lt;svg&gt; &lt;use attr.xlink:href=\"assets\/symbol-defs.svg#{{icon}}\"&gt;&lt;\/use&gt; &lt;\/svg&gt;',\n  styleUrls: &#91;'.\/icon.component.scss']\n})\nexport class IconComponent {\n\n  @Input() icon: string;\n\n}\n<\/code><\/pre>\n\n\n\n<p>&nbsp;we use an <em><strong>@Input<\/strong><\/em> for the icon name. By doing this everybody who consumes this component can define which icon they need.<\/p>\n\n\n\n<p>Next, register our new component to the<em><strong><span class=\"has-inline-color has-vivid-cyan-blue-color\">&nbsp;<code>app.module.ts<\/code><\/span><\/strong><\/em>&nbsp;file.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import { BrowserModule } from '@angular\/platform-browser';\nimport { NgModule } from '@angular\/core';\n\nimport { AppComponent } from '.\/app.component';\nimport { IconComponent } from '.\/bvg\/components\/icon\/icon.component';\n\n@NgModule({\n  declarations: &#91;\n    AppComponent,\n    IconComponent\n  ],\n  imports: &#91;\n    BrowserModule\n  ],\n  providers: &#91;],\n  bootstrap: &#91;AppComponent]\n})\nexport class AppModule {\n}<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<p>Finally,we can use our icons that way: <em>(ps: Be aware of the component selector above)<\/em><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> &lt;bvg-icon  icon=\"icon-notification_summary\"&gt;&lt;\/bvg-icon&gt;<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<p>If we want to change the dimensions of our icons we have to apply these on the&nbsp;<em><strong><code>svg<\/code>&nbsp;tag<\/strong><\/em>. This means that our styling would look like this.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>bvg-icon { \/\/ component tag\n  svg {\n    display: inline-block;\n    width: 20px;\n    height: 20px;\n  }\n}<\/code><\/pre>\n\n\n\n<p><strong> PS<\/strong>: <em>This isn\u2019t an ideal situation. You should be able to consume the&nbsp;<code>svg-icon<\/code>&nbsp;as if it\u2019s the icon on it\u2019s own. We want to apply styling on the component tag and be done with it. Other components who consume this component should\u2019t need to know the internal implementation. We can solve it like thi<\/em>s:<\/p>\n\n\n\n<p>in the <em><strong> icon.component.scss <\/strong><\/em>file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>:host {\n  display: inline-block;\n  \n  svg {\n    display: inline-block;\n    all: inherit;\n  }\n}<\/code><\/pre>\n\n\n\n<p>What we are doing here is saying, every single style that is applied to our component itself  , should apply as well on the&nbsp;<code>svg<\/code>&nbsp;tag.<\/p>\n\n\n\n<p>Its mean, if we now give the<span class=\"has-inline-color has-vivid-red-color\"><strong>&nbsp;<code>bvg-icon<\/code>&nbsp;<\/strong><\/span>tag a&nbsp;<strong><code>width<\/code>,<\/strong>&nbsp;<code><strong>height<\/strong><\/code>&nbsp;and&nbsp;<strong><code>fill<\/code>&nbsp;color<\/strong>, our SVG will inherits all the styling.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> &lt;bvg-icon icon=\"icon-radio_speaker_volume_control\"  \n       style=\"width: 32px; height: 32px; fill:#c00\"&gt;\n &lt;\/bvg-icon&gt;<\/code><\/pre>\n\n\n\n<p><strong><em>Be aware that the&nbsp;<\/em><\/strong><code><strong><span class=\"has-inline-color has-vivid-cyan-blue-color\"><em>all<\/em><\/span><\/strong><\/code><strong><em><span class=\"has-inline-color has-vivid-cyan-blue-color\">&nbsp;<\/span>property&nbsp;<\/em><\/strong><a rel=\"noreferrer noopener\" href=\"https:\/\/caniuse.com\/#feat=css-all\" target=\"_blank\"><strong><em>isn\u2019t supported in IE and Edge<\/em><\/strong><\/a><strong><em>. If you need support for them you must inherit every single property separately. Next to this you\u2019ll also need a polyfill (<\/em><\/strong><a href=\"https:\/\/medium.com\/@rubenvermeulen\/using-an-svg-sprite-icon-system-in-angular-9d4056357b60\"><strong><em>svg4everybody<\/em><\/strong><\/a><strong><em>) for the SVG support.<\/em><\/strong><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h5>Reference:<\/h5>\n\n\n\n<p><a href=\"https:\/\/medium.com\/@rubenvermeulen\/using-an-svg-sprite-icon-system-in-angular-9d4056357b60\">https:\/\/medium.com\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I used to work with icon-fonts, much time. Lots of projects ( Site or applications) really need a system for icons, and icon-fonts offer a very fine system. But there is an another alternative to reference an icon : using inline SVG and the&nbsp;&lt;use&gt;&nbsp;element . Whether it\u2019s icon-fonts or SVG sprites you use as icon [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1402,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1,37],"tags":[130,392,287],"_links":{"self":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/1395"}],"collection":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=1395"}],"version-history":[{"count":10,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/1395\/revisions"}],"predecessor-version":[{"id":1418,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/1395\/revisions\/1418"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/media\/1402"}],"wp:attachment":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=1395"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=1395"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=1395"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}