July 25th, 2024

SVG Triangle of Compromise

The article explores SVG (Scalable Vector Graphics) on the web, highlighting its stylability, cacheability, and dimensionality, while discussing advantages and challenges in web design and performance considerations.

Read original articleLink Icon
InterestFrustrationAppreciation
SVG Triangle of Compromise

The article discusses the use of SVG (Scalable Vector Graphics) on the web, focusing on three key properties: stylability, cacheability, and dimensionality. It explains that SVGs can be styled with CSS, allowing for dynamic changes such as hover states, and can inherit colors from parent elements. When referenced via an <img> tag, SVGs are cacheable, meaning they do not need to be re-downloaded on multiple pages. However, inline SVGs, while allowing for CSS styling, cannot be cached, which may lead to increased bandwidth usage.

The article also addresses the dimensionality issue of SVGs when used in different contexts. For instance, SVGs referenced through an <iframe> do not have intrinsic dimensions, which can complicate their use. To mitigate this, developers can measure dimensions using JavaScript, although this may introduce a flash of unstyled content. The author suggests creating separate SVG files for different states (normal and hover) and using CSS to swap them, as well as embedding symbols within an SVG to reuse icons on the same page.

Overall, the article provides insights into the advantages and challenges of using SVGs in web design, emphasizing the balance between styling capabilities and performance considerations.

AI: What people are saying
The comments on the article about SVG highlight various perspectives on its use in web design.
  • Many users appreciate SVG for its cacheability and scalability, often suggesting methods to optimize its use, such as using the `` tag or external files.
  • There are concerns about the complexity and reliability of SVG across different browsers, with some users sharing negative experiences regarding text readability and rendering issues.
  • Several commenters discuss alternative methods for achieving interactivity and styling, including CSS animations, SMIL, and JavaScript frameworks like React.
  • Some users propose the idea of including external SVG files or using templating languages to improve caching and reduce loading times.
  • There is a debate over the definition of "stylable" in the context of SVG, with some clarifying that inline SVG allows for more dynamic styling compared to other methods.
Link Icon 20 comments
By @OskarS - 3 months
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"

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?

    <html>
    <head>
      <<< include head.html >>>
      <title>Cool page!</title>
    </head>
    <body>
        <svg>
            <<< include logo.svg >>>
        </svg>
    </body>
    <html>

Where the `<<< include ... >>>` is a pretend bit of HTML that makes the browser fetch that from somewhere else. A preprocessor, more or less.

I realize this is what templating languages are for, but if this happened on the HTML layer, the browser could do way better caching.

By @panstromek - 3 months
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.

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.

By @geokon - 3 months
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

Example: svg poster - includes svg diagrams - that include svg maps (maps are generated programmatically)

https://kxygk.github.io/imergination/

Though.. if you open the SVG itself (in a separate window/tab) most elements refuse to display for "security"

https://raw.githubusercontent.com/wiki/kxygk/imergination/ag...

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

By @tannhaeuser - 3 months
Actually, for interactivity you don't have 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.
By @HenriTEL - 3 months
You can specify an svg file with the use tag like this: <use xlink:href="/your/icons.svg#whatever">

It pretty much solves the cache issue to me.

By @chrismorgan - 3 months
I’m not confident of what is meant by “stylable”, but I’m pretty sure it’s a misnomer.

If you mean applying static styles, you can do that with any form of SVG (that is, <img> qualifies as well).

If you mean inheriting styles from the parent document, you can only do that with inline SVG (that is, <iframe> doesn’t qualify).

But by the actual usage in the article (that it’s <svg> and <iframe> but not <img>), I think what is actually meant is interactive—that you can run scripts, have :hover styles, links, things like that.

By @ABNW - 3 months
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!
By @Springtime - 3 months
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).
By @akira2501 - 3 months
> but might waste bandwidth if used for SVGs used often, like a logo or icon.

You can put SVGs into a <TEMPLATE>. I've used this for "site and social icons" to great effect.

By @lucideer - 3 months
Doesn't the <use/> tag tick all three boxes?

(the OP does mention the <use/> tag in the final notes but only for in-document fragment references, not for remote URLs)

By @rawoke083600 - 3 months
Actually there is very important 4th point about implementation (browser)

A few years ago a made a Monopoly-Deal-Clone game using mostly SVG + CSS + Svelte.

I was intrigued by the promise of SVG:

  - Loss-Less Scaling

  - Looks the same (or somewhat) the same on all browsers

  - Text would also scale and be readable up and down.  

Build playing cards on the fly with SVG elements dynamically (base-card-svg + text + icon/image/glyph)

All of these were never true-enough even for even a card-based game.

The SVG text never looked good-enough or readable at all sizes used. Depending on scaling the text/icons and lines got blurred worse.

The "fix" for many of these were endless and browser version-dependent magic-css properties and values.

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 !

By @baggy_trough - 3 months
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:

  /images/icons/9bac00/door.svg
  /images/icons/ffffff/door.svg
By @GeoAtreides - 3 months
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!)
By @spankalee - 3 months
Something like this <html-include> element should be able to hit all three requirements, if you allow for JavaScript: https://www.npmjs.com/package/html-include-element
By @AlienRobot - 3 months
All 3: Javascript.

Just load a .svg and put it into a <SVG>.

By @beardyw - 3 months
I can add:

In CSS: hold it as a background-image with the SVG in a data URL (requires some encoding).

Works for me.

By @TheRealPomax - 3 months
Still waiting for HTML imports. And that work was discontinued...
By @genezeta - 3 months
In case the author reads this:

I would suggest editing your Venn diagram a bit so that it makes more sense. Something like this

  <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>

This way, the region where your three circles overlap actually disappears, signifying that you can't indeed get all three at the same time.
By @quink - 3 months
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.

It's a first class citizen, put it in a React Component, anything goes. Cacheable, stylable, and dimensional.