Is there a fully great way to do icons on the internet?
What these are:
- SVG as IMG: You have an SVG file. Create an img element. SVG is the src of that image element. It's an img tag.
- Inline SVG: You put an
<svg>element into your HTML.
- Custom font: You use a font like Font Awesome where the letters are icons
- SVG as USE: You have one
<svg>element on your page that has a bunch of symbols, and you use use to reference them.
Explain the downsides:
- Dynamic colors: you want to be able to change the color of the icon to match the surrounding text. Everything but the
imgtag solution can do this, because images aren't really "a part of your webpage", they're self-contained little resources. This uses the
currentColorvalue in SVG, which uses the… current color.
- Efficient repetition: if you show the 'export' icon next to 20 things, do you include the source code for the icon 20 times, or can you reference it? Inline SVG includes the elements - the paths, circles, etc - every time you show the icon. This bloats the DOM.
- Semantic code: does this thing seem like an icon to screenreaders, naturally? Like - img tags are images, obviously. A span with a character in it - which is how font icons work - is not an icon. You can dress it up with aria tags to look like an icon, but it isn't.
- Multi-color: if you really want to have something in the icon with a specific color, can you? Fonts can't do this, and probably won't be able to for a long time.
- No ID conflicts: SVG use statements reference their
symbolsby using a local page-specific ID. This is a recipe for disaster: your page might have auto-generated IDs that conflict with those IDs. You might use the
basetag and throw all references off. I've seen it happen, it sucks.
I've stuck to doing inline svgs for a long time. The icon is a React component or a server-side-include and you just put it on the page when you want to display it. But the downside of bigger DOMs is annoying: it means a lot more code shipped with SSR, and a bigger DOM that Google Chrome will yet at you about.