SVG Icons

Adding icons to a web page can be done in a number of different ways. In times past, you would use an image file (JPG, GIF, PNG, etc), but these would not scale nicely and you could not style them. Then came the method of using font files, with them containing a collection of vector graphic icons, instead of letters, and allowing you to style them, setting whatever color you wanted and scaling them to any size. They are very easy to add into your HTML using simple CSS classes. It does require you to load in the whole font file, even if you are only showing one icon.

Another option is to use embedded SVG elements, containing all the vector graphics with the required colors to draw the icon. These scale very well and because they where embedded in the HTML you don't need to load in any extra files. However, the more complex the icon, the larger the SVG data, making it harder to handle at times.

There is a way to combine a SVG icon with a custom element to make a reusable and easy to use icon tag. Imagine you have the icon tag <icon-search></icon-search>, which you can style to change both the foreground and background colors, set its size and other properties.

Adding SVG data into HTML could be done by hand, using the <path> tag with its data path information for example, but I would not recommended it. A better method is to use some type of vector graphics application and take the resulting SVG data and copy it into the required HTML location. Taking a look inside a SVG image, looking at the XML data, can seem scary, full of XML tags and settings that don't make much sense, but you only need to copy the important parts, the rest is not needed.

Let's take a look at an example of how this is done. Below is the source code for the search icon, which includes the SVG data, placed inside a custom element.

export default class IconSearch extends HTMLElement {
  constructor() {
    // Must call super first
    super();

    // Set the inner HTML to the SVG
    this.innerHTML =
    `
    <svg
      viewBox="0 0 16 16" style="display: block; height: inherit;">
      <path
        d="M 7 0 A 7 7 0 0 0 0 7 A 7 7 0 0 0 7 14
            A 7 7 0 0 0 10.84375 12.84375 
            L 13.646484 15.646484
            A 0.5 0.5 0 0 0 14.353516 15.646484 
            L 15.646484 14.353516 
            A 0.5 0.5 0 0 0 15.646484 13.646484 
            L 12.84375 10.84375 
            A 7 7 0 0 0 14 7 
            A 7 7 0 0 0 7 0 z
            M 7 2 A 5 5 0 0 1 12 7 A 5 5 0 0 1 7 12 A 5 5 0 0 1 2 7 A 5 5 0 0 1 7 2 z ">
      </path>
    </svg>
    `;
  }
}

// Define custom control
customElements.define('icon-search', IconSearch);

This is a very basic custom element. We are setting the inner HTML to the SVG data. The whole SVG icon was converted into a single path before we copied it into the HTML. This means that inside the SVG file, there is only one <path> tag and therefore only one block of data we need to copy over into the custom element. We are putting the path data inside some <svg> tags and adding a viewBox attribute. In this example I am setting the viewBox to a 16x16 pixel grid. Therefore, all the path points are located within this grid.

We have added some styling to the SVG, making the display a block type and setting the height as inherited (the same as its parent element, the custom element).

We can style the custom element and get it to change the background-color of the icon just like any other element. We can also set the color of the icon with the CSS fill style property (using the color style property does not change SVG parts). To use the SVG icon custom element you just need to add the tag with a height style.

<!-- Display the icon -->
<icon-search
  style="
    display: inline-block;
    height: 4rem;
    fill: #277da1;
    background-color: white;">
</icon-search>  

Here we are setting the style of the search icon. Take a look at what it looks like.

Not the most exciting example, but it does show how easy it is to setup and work with. There are some drawbacks with this method. You do need to import each of the SVG icon custom element files that you want for each page. The more icons you have, the more files you'll need to load up. You could put them all together into one larger file and just import that once.

There are some benefits with this method however. There are no 3rd party libraries used. You can create your own custom SVG icons. The amount of data loaded could be a lot smaller than a font based icon set.

I have put together a large collection of custom element SVG icons. They are all free to use in your own web applications. Take a look.