My current bad implementation of icons
I am currently working on a new Angular project, and I am not happy with my SVG-icon implementation in my other project (using @ngneat/svg-icon). It requires SVG files to be in a folder, then registered in Typescript and then compiled into (iconName).ts files with a script that has to be run.
An easier Way
In my current project i am using Bootstrap and while studying the docs i stumbled upon the following svg implementation:
Source: https://getbootstrap.com/docs/5.0/components/alerts/
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="check-circle-fill" fill="currentColor" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z"/>
</symbol>
<symbol id="info-fill" fill="currentColor" viewBox="0 0 16 16">
<path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"/>
</symbol>
<symbol id="exclamation-triangle-fill" fill="currentColor" viewBox="0 0 16 16">
<path d="M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5zm.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2z"/>
</symbol>
</svg>
<svg class="bi flex-shrink-0 me-2" width="24" height="24" role="img" aria-label="Info:"><use xlink:href="#info-fill"/></svg>
<svg class="bi flex-shrink-0 me-2" width="24" height="24" role="img" aria-label="Success:"><use xlink:href="#check-circle-fill"/></svg>
This usage would have me only paste the svg icons in the Symbols, and have all the icons in a hidden element that i load somewhere on the page. Giving them an appropriate id, this would allow me to use SVG icons anywhere on the page using xlink:href.
Too good to be true
According to MDN the xlink:href attribute is deprecated (Source). But since bootstrap is using it and i found many posts saying that it will never be removed because so many sites are using it, i am tempted to stil use it
A non-deprecated alternative
On the MDN Page of SVG <use> (Source) I found the following example not usin xlink:href but only href instead. At first i though this could only be used to reference another path within the same SVG but upon trying it on my site it worked.
<svg viewBox="0 0 30 10" xmlns="http://www.w3.org/2000/svg">
<circle id="myCircle" cx="5" cy="5" r="4" stroke="blue"/>
<use href="#myCircle" x="10" fill="blue"/>
<use href="#myCircle" x="20" fill="white" stroke="red"/>
<!--
stroke="red" will be ignored here, as stroke was already set on myCircle.
Most attributes (except for x, y, width, height and (xlink:)href)
do not override those set in the ancestor.
That's why the circles have different x positions, but the same stroke value.
-->
</svg>
The Question
So the tl:dr question is "how should i implement my icons?", but here are the questions leading to that:
- Would you still reccommend xlink:href since bootstrap is using it?
- Is <use href> a valid alternative or is it intendet to be different?
- Do Paths with display none have any bad impact like performance or page load, since all of the above mentioned possibilities would include all of my svg icons (even if not used on a specific page) in the html?
xlink:
is no longer required, justhref
works in all modern browsers. Problem withuse
is you can't have duplicate IDs.. often a problem when you apply filters.display:none
content is still content that needs to be parsed by the DOM parser. So yes, you pay a penalty; but if this causes performance issues you probably have loads more other bad-performing code... unless you have 7347 icons on one page – Danny '365CSI' Engelman