Icons to the browser in 2016 using svg symbol
Icons to the browser in 2016
The way icons are sent to the browser have changed a lot over the past couple of years. In this article I will try to elaborate on the history and the technique to use in 2016.
Image Sprites
Image sprites are used in almost all web apps where multiple images are used since netscape/ie5. Rather than include each image as a separate image file, it is much more memory and bandwidth-friendly to send them as a single image, so the number of HTTP requests is reduced. This methode was one of the first effective ways to get custom icons to the browser. Unfortunately this method does not allow for scaling icons without loss of image quality and is not retina-proof. Furthermore it is not possible to change colors of the icon with css.
Automating sprite creation can be done with gulp-sprite-generator. I would not advise using this technique at this point.
Icon fonts
Icon font is a retina-proof method of building font files from a set of icons and then using the @font-face rule to load the icon font from CSS. The icon font has been used a lot since IE8 support for @font-face. Caching and loading of font files was difficult but possible providing great cross browser support. large icon fonts are open and available online. This method with custom icons is quite difficult to support because it relies on cumbersome build processes. Another drawback: You can’t have multi-colored icons in a font, but can only set one color using CSS. Scaling and aligning such icons can be difficult, because you can only change the font size; changing width and height is not possible.
Automating font creation of the fonts can be done with gulp-iconfont. I would advise using this technique for projects with large amounts (70+) of icons.
SVG symbols
In 2014 a goup working on grunt-svgstore suggested using svg symbols as a replacement for icon fonts. Advantages of the technique are.
- Multi color icon support.
- Allows for changing style of icons with CSS at will.
- The viewBox can be defined on the symbol, Allowing for any aspect ratio icon. so you don’t need to use it in the markup (easier and less error prone).
- Title and desc tags can be added within the and they kinda “come along for the ride” when the symbol gets used, making accessibility easier to do right.
- Symbols can be added to the or included with an html import of a html document. This means that the full font can be included at once and is cachable.
- Scalabillity without quality loss.
Automating symbols creation can be done with gulp-svg-symbols. I would advise using this technique in projects for 2016.
There are things you should look out for when creating symbols from separate svg files.
- Make sure your viewport is set.
- Remove height on the SVG tag and set width to 100%. this to make sure the svg is usable outside the symbol workflow.
- Add classes into the svg file for elements that you want to be able to style from within the web page css.
- Editors like illustrator or inkscape create svg files with a lot of unused xml markup. Optimise your files with a text edittor by removing this markup when using a svg edittor.
SVG Symbols exsample
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>The HTML5 symbol</title>
<style>
body {
background: #005b82;
}
.icon {
max-width: 230px;
}
.icon-white {
fill: #FFF;
}
.icon-yellow {
fill: yellow;
}
</style>
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" style="display:none">
<symbol id="icon-whitelogo" viewBox="0 0 230 150">
<g class="logo_svg_main">
<path d="M46.232,0v14.907c-0.006,3.459-2.869,6.308-6.339,6.313l-12.19,0.002V2.375h-4.562v18.848H10.948
c-3.468-0.008-6.33-2.856-6.336-6.315V0H0.051L0.049,14.907c0.01,5.989,4.889,10.848,10.899,10.858h28.946
c6.011-0.011,10.891-4.869,10.899-10.858V0H46.232z"></path>
<path d="M173.167,4.543H200V0h-26.833c-4.826,0.008-8.739,3.907-8.747,8.709v8.345
c0.008,4.805,3.921,8.7,8.747,8.711H200v-4.543h-26.833c-2.288-0.004-4.182-1.889-4.185-4.168v-1.901h27.098v-4.542h-27.098
V8.709C168.985,6.435,170.878,4.549,173.167,4.543z"></path>
<polygon points="90.833,0 90.833,10.611 66.004,10.611 66.004,0 61.444,0 61.444,25.765 66.004,25.765
66.004,15.153 90.833,15.153 90.833,25.765 95.395,25.765 95.395,0"></polygon>
<polygon points="156.123,0 122.173,0 122.173,4.543 136.871,4.543 136.871,25.765 141.43,25.765 141.43,4.543
156.123,4.543"></polygon>
<polygon points="107.883,25.765 107.883,0 112.447,0 112.447,25.765 107.883,25.765"></polygon>
</g>
</symbol>
<symbol id="shape-icon-2" viewBox="0 26 100 48">
<!-- <path>s and whatever other shapes in here -->
</symbol>
</svg>
<svg class="icon">
<use class="icon-white" xlink:href="#icon-whitelogo" />
</svg>
<svg class="icon">
<use class="icon-yellow" xlink:href="#icon-whitelogo" />
</svg>
</body>
</html>