Inline SVG (linking to sprite in external svg file) as part of DOM: good support (no polyfills needed). This is the one to use.

Downside: messier DOM and frequent changes to DOM during design phase.

Upside: compared to full-fat version, page weight is not the same concern due to single file containing all symbols - download one svg once; easy manipulation via CSS and JS.

Recommended use-case: everywhere

Note: current standards have removed the 'xlink:href' and replaced it with just 'href'. Quantum, Blink, and EdgeHTML rendering engines support the new standard, but WebKit in Safari (desktop and mobile) do not.

Here's a test for Safari. This line should be preceded by a groovy little compass icon. In November 2018 it does not show up in Safari because the 'href' attribute is not in the xlink namespace.

The solution is to use both 'xlink:href' AND 'href':

<svg class="icon">
    <use xlink:href="symbol-defs.svg#icon-home3" 
         href="symbol-defs.svg#icon-home3" />
</svg>

Inline SVG as part of DOM: excellent support. CSS-Tricks recommendation in 2017.

Downside: messier looking DOM and frequent changes to DOM during design phase; depending upon frequency of use and size of SVGs used, page weight might become a concern; cache bloat

Upside: once SVG collection decided and placed in DOM, manipulation is easy via CSS and JS.

Recommended use-case: SVG code is minimalistic and not over-used in a page.

This is second best due to inherent cache bloat issues.


SVG in CSS as image: most like old-school use of images.

Downside: not subsequently manipulable by CSS or JS - need to have separate version for hover etc.; a little janky on load (resizing or something).

Upside: tidy DOM; easy to use.

Recommended use-case: retro-fitting old site, maybe(?). Workable, but not really recommended.


SVG in CSS using data protocol: keep development workflow as is.

Downside: extremely messy CSS - each version of the SVG needs to be re-created in CSS; more brittle due to finicky implementation requirements; subsequent manipulation impossible as not part of DOM; twice as much code as full-fat inline version.

Upside: no significant change to development and design workflow.

Recommended use-case: SCSS mixin

Note: if you use this with scss, try:

//$sc = standard colour; $hc = hover colour
@mixin svgIconHome($sc:red,$hc:red,$w:22px,$h:22px;) {
  content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"><style>.icon { fill:{$sc}; width:22px; height:22px; vector-effect: non-scaling-stroke; } .icon:hover { fill:{$hc}; }</style><path class="icon" d="M32 19l-6-6v-9h-4v5l-6-6-16 16v1h4v10h10v-6h4v6h10v-10h4z"></svg>');
}