Using SVG on the web

Five ways to put SVG on a page — and when to use each

Inline <svg>

Pasting the SVG markup directly into your HTML document is the most powerful technique. Because the SVG elements become part of the HTML DOM, your page's CSS can reach inside and style individual shapes, and JavaScript can query and animate them just like any other DOM node.

One of the most useful consequences: if shapes inside the SVG use fill="currentColor", they inherit the CSS color property from their ancestor — the same mechanism that makes text color work. This means a single icon can appear in dozens of colors without duplicating any SVG markup.

<!-- The icon uses fill="currentColor" so it inherits the parent's CSS color --> <span class="icon-context teal-brand"> <svg class="demo-svg" viewBox="0 0 24 24" width="24" height="24" role="img" aria-label="Star icon, teal"> <path d="M12 2l2.9 6.3 6.9.7-5.1 4.7 1.4 6.8L12 17.8 5.9 20.5 7.3 13.7 2.2 9l6.9-.7z" fill="currentColor" /> </svg> Teal context </span> <span class="icon-context orange-brand"> <svg class="demo-svg" viewBox="0 0 24 24" width="24" height="24" role="img" aria-label="Star icon, orange"> <path d="M12 2l2.9 6.3 6.9.7-5.1 4.7 1.4 6.8L12 17.8 5.9 20.5 7.3 13.7 2.2 9l6.9-.7z" fill="currentColor" /> </svg> Orange context </span> <span class="icon-context red-brand"> <svg class="demo-svg" viewBox="0 0 24 24" width="24" height="24" role="img" aria-label="Star icon, red"> <path d="M12 2l2.9 6.3 6.9.7-5.1 4.7 1.4 6.8L12 17.8 5.9 20.5 7.3 13.7 2.2 9l6.9-.7z" fill="currentColor" /> </svg> Red context </span>
  • Teal context
  • Orange context
  • Red context

Trade-offs

  • Pro: full CSS and JavaScript access; supports currentColor recoloring; no extra HTTP request.
  • Con: bloats the HTML; not cached separately by the browser; duplicated across pages if the same icon appears many times.

<img src="*.svg">

The simplest technique — exactly how you would embed a JPEG or PNG. The browser fetches the SVG file, renders it, and caches it independently. It scales with standard width/height attributes or CSS.

The catch is that an <img> tag creates a completely opaque boundary: your page's CSS and JavaScript cannot reach inside the SVG to change colors, animate shapes, or query elements. Treat it as a pre-rendered image.

<img src="../assets/sample-logo.svg" width="200" height="80" alt="Vector sample logo"> Vector sample logo

Trade-offs

  • Pro: simplest syntax; file is cached; works everywhere; alt attribute gives a clean text alternative.
  • Con: no CSS or JS access inside the SVG; cannot recolor with CSS; scripts inside the SVG file do not run.

<object data="*.svg">

The <object> element embeds the SVG as an independent, fully parsed document with its own browsing context. Unlike <img>, scripts inside the SVG file run normally. The outer page can also reach into the embedded document via contentDocument, though cross-origin restrictions apply.

Fallback content placed between the opening and closing tags is shown only if the browser cannot load or render the SVG — a simple text description or a raster fallback image are common choices.

<object data="../assets/sample-logo.svg" type="image/svg+xml" width="200" height="80"> Vector logo <!-- fallback text if SVG cannot be loaded --> </object> Vector logo

Trade-offs

  • Pro: scripts inside the SVG run; fallback content is easy to provide; file is cached separately.
  • Con: more verbose; page CSS cannot style SVG internals directly (requires contentDocument); currentColor does not propagate from the outer page.

CSS background-image

Any element can display an SVG as its CSS background. This is purely decorative: the image has no DOM representation, carries no semantic meaning, and is invisible to screen readers. Use it only when the graphic is decorative rather than informative — or when an element's background is the right visual layer for the design.

.bg-icon-demo { width: 48px; height: 48px; background: url("../assets/sample-icon.svg") no-repeat center / contain; } <div class="bg-icon-demo" role="presentation" aria-hidden="true"></div>

Trade-offs

  • Pro: works with any element; file is cached; easy to swap with a media query or class change.
  • Con: decorative only — no accessible name; no CSS or JS access inside; currentColor does not work; cannot be targeted by JavaScript.

Data URI

A data URI embeds the SVG source directly into the src attribute (or CSS url()) as a URL-encoded string. No separate HTTP request is made; the image is literally part of the HTML or stylesheet.

The encoding rule: replace # with %23; angle brackets should be percent-encoded too (%3C for <, %3E for >) — a raw < inside an attribute value can confuse the HTML parser — and spaces become %20. URL encoding is preferred over base64 for SVG because the SVG source is already mostly ASCII text — base64 bloats it by ~33% and makes it unreadable and impossible to cache as a separate resource.

Data URIs make the most sense for tiny, critical-path icons that you want to guarantee render without a network round-trip. They hurt for anything larger because they cannot be cached independently, inflate HTML/CSS size, and are hard to edit.

<!-- A small teal circle encoded as a data URI --> <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 40' width='40' height='40'%3E %3Ccircle cx='20' cy='20' r='18' fill='%230f766e'/%3E %3C/svg%3E" alt="Teal circle" width="40" height="40"> Teal circle

Trade-offs

  • Pro: zero extra HTTP requests; useful for tiny critical icons; works anywhere a URL is accepted.
  • Con: not cached separately; bloats HTML/CSS; hard to read and maintain; no CSS or JS access to SVG internals.

Summary: which technique to choose?

The five techniques each occupy a different niche. Use this table as a quick reference:

Technique CSS access inside SVG JS access inside SVG Cached separately CSS recolorable Best for
Inline <svg> Yes Yes No Yes (currentColor) Icons that need theming; interactive graphics
<img src="*.svg"> No No Yes No Logos, illustrations — simple and cacheable
<object data="*.svg"> Via contentDocument Yes (internal scripts) Yes No SVGs with their own scripts; fallback support
CSS background-image No No Yes No Decorative backgrounds; design-layer patterns
Data URI No No No No Tiny critical icons; offline/embedded contexts