Isn't the fundamental issue here not so much anything to do with `<svg>`, but with the fact that you can't easily include HTML snippets from other files in HTML? Like, the only reason not use the <svg> tag seems to be "it's not cached, and it contains a BUNCH of svg, and it has to be loaded with the main HTML page"<p>Can't you say that about anything in HTML? Like, imagine you had a huge `<head>` tag that contained a bunch of stuff, but it's essentially the same (except for, like, the title) for all documents. Don't you wanna do this?<p><pre><code> <html>
<head>
<<< include head.html >>>
<title>Cool page!</title>
</head>
<body>
<svg>
<<< include logo.svg >>>
</svg>
</body>
<html>
</code></pre>
Where the `<<< include ... >>>` is a pretend bit of HTML that makes the browser fetch that from somewhere else. A preprocessor, more or less.<p>I realize this is what templating languages are for, but if this happened on the HTML layer, the browser could do way better caching.
I like to use sprite files for conditional styling of icons, because using separate file for each state creates a visible delay on state changes, which doesn't look great.<p>You can make them with <defs> and <use> tags pretty easily if you understand svg a bit. I usually bundle two-state icon into a single svg file, and then use `object-position: left/right` property on the <img> tag to switch between the variants. You can also combine this with some simple css animations.
Another option would be to including SVG files from SVG elements, though the whole thing is a bit cursed. I'm not 100% sure how it plays with CSS and caching<p>Example: svg poster - includes svg diagrams - that include svg maps (maps are generated programmatically)<p><a href="https://kxygk.github.io/imergination/" rel="nofollow">https://kxygk.github.io/imergination/</a><p>Though.. if you open the SVG itself (in a separate window/tab) most elements refuse to display for "security"<p><a href="https://raw.githubusercontent.com/wiki/kxygk/imergination/agu2023-poster.svg" rel="nofollow">https://raw.githubusercontent.com/wiki/kxygk/imergination/ag...</a><p>It's honestly an unreliable format for anything that's mildly complex.. this poster will render differently in different browsers (and inkscape) and can't be turned into a PDF consistently. It's a mess
Actually, for interactivity you don't <i>have</i> to use CSS but can also use SMIL animations to set SVG (or CSS) properties for things like clicking/hovering, timed transitions, and even animation sequences. Never understood the CSS march of progress narrative when CSS just piecemeally incorporares concepts (paint servers, filters, etc) SVG had for 20 years now, and what's so great about having those available in CSS" wild unchecked syntax, especially when you'd need (or prefer) JS anyway. SVG at least can be targetted as a reasonable output format by vector drawing tools.
You can specify an svg file with the use tag like this: <use xlink:href="/your/icons.svg#whatever"><p>It pretty much solves the cache issue to me.
I’m not confident of what is meant by “stylable”, but I’m pretty sure it’s a misnomer.<p>If you mean applying static styles, you can do that with any form of SVG (that is, <img> qualifies as well).<p>If you mean <i>inheriting</i> styles from the parent document, you can only do that with inline SVG (that is, <iframe> <i>doesn’t</i> qualify).<p>But by the actual usage in the article (that it’s <svg> and <iframe> but not <img>), I think what is actually meant is <i>interactive</i>—that you can run scripts, have :hover styles, links, things like that.
Really interesting, am a big fan of the utility that SVG's provide, an undersung hero of the web imo. One thing I've always particularly liked is you can wrap elements inside of an <svg> tag with an <a> tag, useful in the battle against a "square" web!
For the particular purpose mentioned in the article another solution is to use CSS' `mask-image`/`-webkit-mask-image` and fragment identifiers in a single SVG that get swapped between hover/regular states. Avoids any inline markup and as a bonus the element color is stylable via the parent page's CSS, albeit one isn't manipulating the inner SVG (though in the OP's case it's a static shape).
> but might waste bandwidth if used for SVGs used often, like a logo or icon.<p>You can put SVGs into a <TEMPLATE>. I've used this for "site and social icons" to great effect.
Doesn't the <use/> tag tick all three boxes?<p>(the OP does mention the <use/> tag in the final notes but only for in-document fragment references, not for remote URLs)
Actually there is very important 4th point about implementation (browser)<p>A few years ago a made a Monopoly-Deal-Clone game using mostly SVG + CSS + Svelte.<p>I was intrigued by the promise of SVG:<p><pre><code> - Loss-Less Scaling
- Looks the same (or somewhat) the same on all browsers
- Text would also scale and be readable up and down.
</code></pre>
Build playing cards on the fly with SVG elements dynamically (base-card-svg + text + icon/image/glyph)<p>All of these were never true-enough even for even a card-based game.<p>The SVG text never looked good-enough or readable at all sizes used.
Depending on scaling the text/icons and lines got blurred worse.<p>The "fix" for many of these were endless and browser version-dependent <i>magic-css</i> properties and values.<p>TL;DR
I wouldn't use SVG for more than 50% of your game or professional product that uses images/visual-elements. Its not worth the pain and effort !
I like using external svg files for icons because they are tiny and cacheable. I get around the colorization problem by creating different icon files for each color. In practice, I only have a small number of colors to worry about. So:<p><pre><code> /images/icons/9bac00/door.svg
/images/icons/ffffff/door.svg</code></pre>
Seeing that svg is text, enabling gzip compression on server will certainly help with reducing size; especially if using lots of inlined repeating svg elements (like icons, glyphs, etc). I also imagine SPA that compile to one index.js file can massively benefit from inlining svg + server compression (also, very cacheable!)
Something like this <html-include> element should be able to hit all three requirements, if you allow for JavaScript: <a href="https://www.npmjs.com/package/html-include-element" rel="nofollow">https://www.npmjs.com/package/html-include-element</a>
In case the author reads this:<p>I would suggest editing your Venn diagram a bit so that it makes more sense. Something <i>like</i> this<p><pre><code> <circle class="property stylable" cx="190" cy="145" r="70"></circle>
<text class="stylable" x="150" y="140" fill="black">stylable</text>
<circle class="property cacheable" cx="310" cy="145" r="70"></circle>
<text class="cacheable" x="300" y="140" fill="black">cacheable</text>
<circle class="property dimensional" cx="250" cy="260" r="70"></circle>
<text class="dimensional" x="210" y="280" fill="black">dimensional</text>
</code></pre>
This way, the region where your three circles overlap actually disappears, signifying that you can't indeed get all three at the same time.
Or just use any modern DOM-manipulating JavaScript framework like React - in effect putting an `<svg>` tag in very cacheable JavaScript. <div style={...}><p className="...">...</p><svg viewBox="..."><g fill="...">...</g></svg></div>, whichever.<p>It's a first class citizen, put it in a React Component, anything goes. Cacheable, stylable, and dimensional.