There are several ways to add icons in a project. Using fonts, background-image or even adding the direct asset into your html. I will try to cover the pros and cons of each one.
Images (jpg, png, gif) | Svg-inline | Svg-background | Font | |
---|---|---|---|---|
Scalable | ||||
Multiple colours | ||||
Respect font-size and color | ||||
Easy implementation | ||||
Maintainable | ||||
Accessible by DOM |
Images (png, gif or jpgs)
Implementation
<img src=”icon-email.png” />
If there is an approach you shouldn't follow, it is this one. Images are not scalable, the DOM has no access to its properties and there other, far better solutions.
Inline-svg
Implementation before webpack transformation
<img src="box.svg">
after webpack transformation
<svg width="400" height="110">
<rect width="300" height="100" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
</svg>
With a little bit of webpack magic, you could embed the svg source of an img
tag in the html document. From this point we could edit almost every property of the svg content, color, shapes, borders, you name it.
The problem with this method is the same as using images. The implementation of the icons relies on the icons asset, not on style.
It means that any other project that requires your styles, will have to import not only the css classes, but all those assets as well.
Font
Thanks to the webpack community, the painful process to generate the font files and css classes is mostly taken care of with a little extra build configuration.
There is more than one webpack loader that will help with the task, but the way they work are very similar.
The loader will read a folder with all your svg files and generate not only a font file, but the icons css classes as well.
Thanks to that, I can say the Font solution for icons is now maintainable and shareable between projects.
Development
Here is a list of webpack loaders in the process.
Webfont-loader
Fontgen-loader
webfont
Implementation
<h1><i class="icon-email'/>Send this email</h1>
One of the most common practice(s). The implementation as I showed above is quite simple and powerful.
Because it is a font, it will respect the color
and font-size
set on css.
There are few cons with this approach.
- Webpack configuration needed
- Only flat icons supported
- Asset weight. Even if your project uses only half of the icons available, it still has to load the entire font.
SVG Background
Development
.icon-email:before {
width: 28px;
height: 28px;
background: url(../assets/obs-icon-info-solid.svg) no-repeat;
background-size: contain;
}
Implementation
<h1><i class="icon-email'/>Send this email</h1>
Is scalable, could have multiple colours, easy to share, but using svg as background kills one of the greatest svg advantages: properties accessible by DOM.
What is the problem with that? Well, if you plan to change the icon color on hover state, it won’t be possible.
And with that, come the sizing issues.
If your icon is inside a h1
tag, it will not have the h1
font size.
Conclusion
There are many ways to work with icons these days, but unfortunately, there is no strategy that is bulletproof.
Some solutions work perfectly when implemented, but are terrible to maintain and others are the other way around. The perfect solution depends on each project requirement.