A native way to color SVG icons

When you need the ability to change the color of icons through CSS, what do you do? There are not many options.



Usually either icon fonts are used, or the SVG source code is downloaded and inserted into the HTML manually. The font needs to be optimized, otherwise the user will download all the icons at once unnecessarily. Working with source code requires heavy DOM operations and is potentially dangerous.



To protect against malicious SVG code, you need to "clean". Angular's built-in sanitizer, for example, does not work with SVGs and turns them into an empty string. You can use the proven DOMPurify tool and connect it using our ng-dompurify library , which I talked about in detail .


Let's take a look at another method available in modern browsers - the USE tag .







How is USE useful for us?



This tag is designed to reuse symbols and entire SVG blocks on a page. But in modern browsers (sorry IE) it can even reach external resources!



External SVGs must be on the same domain, so a CDN won't work. Bye .


This allows SVGs to be inserted natively into the Shadow DOM, much like IMGan attribute tag src, only with the ability to use CSS. And it even works with the cache itself! But you need to prepare the icons a little. Here's what to do:







First, in each icon you need to make a symbol with a unique id and move it viewBoxto it.



Then you need to assign fill(or stroke) to currentColor, then use the CSS rule colorto set the color. You can also set these attributes inheriton other elements, which will allow you to make two-color icons (for more details, see the example below).



When our icons are ready, all that remains is to drop them into a folder assetsand use:







Named Icon Component for Angular



Writing a path and referring to a symbol every time is tedious. Let's make an Angular component that finds icons by name. Dependency Injection makes this very easy.



We'll need a token to provide a path to all our icons and a simple component. It will form hrefbased on the name and the specified path. We can even hang it on a native SVG using a selector: this way we take out the concern for size.



Keep in mind that Safari prior to 12.1 only supports the legacy syntax xlink:href. So it's best to use both options.


Let's make strokeit filltransparent for multiple colors in CSS:







Live example: stackblitz.com/edit/angular-colored-svg



Conclusion



This approach has limitations - lack of IE and cross-domain support. However, if they are not critical for you, this solution can be a good alternative to other methods.



You don't have to include icons in the app bundle or download them by request. You can rely on the cache to speed up loading, and the absence of DOM operations makes this approach faster and safer than manual insertion of sources. All bright decisions!



All Articles