An SVG referenced by an img tag and the same SVG pasted into your HTML are not equivalent. The differences decide styling, caching and security.
Inline SVG
The markup lives directly in your document.
Can do:
- Be styled by your page's CSS — fill, stroke, currentColor inheritance, hover states, dark-mode variants.
- Animate individual parts, respond to JavaScript, be part of the accessibility tree with title and aria attributes.
- Avoid an extra network request entirely.
Costs:
- Adds weight to every page that includes it, and is not cached separately — the same icon repeated across ten pages is re-downloaded with each HTML document.
- Bloats markup if you paste raw editor exports full of metadata, comments and hidden layers.
- Its ids and class names live in the page's global namespace, so two inlined SVGs with the same internal ids can collide and break gradients or clip paths.
SVG via img (or CSS background)
The browser treats it as an image and renders it in an isolated context.
Can do:
- Be cached as a separate file and shared across pages — the right choice for a logo used site-wide.
- Keep your HTML clean.
- Use normal image attributes: alt text, loading, dimensions.
Cannot do:
- Be styled by page CSS. The document's rules don't cross into the image, so you can't recolour it with currentColor. (Styles *inside* the SVG file still apply, and CSS variables don't penetrate either.)
- Run scripts — which is a feature, not a limitation, as below.
The Security Point
SVG is XML and can contain script elements and event handlers. When inlined into your page, that script runs in your origin with full access to your DOM, cookies and session. This makes an inlined, user-uploaded SVG a stored cross-site-scripting vector.
Rules:
- Never inline SVG from an untrusted source.
- If you accept SVG uploads, sanitize them server-side with a dedicated library that strips scripts, event handlers, external references and foreignObject.
- Prefer serving user-uploaded SVG through an img tag or from a separate, cookieless domain, where script execution is blocked or harmless.
- Consider rasterizing user SVG to PNG/WebP if you don't need vector fidelity — it removes the entire class of risk.
Choosing
- Interface icons you recolour and animate → inline SVG (or an SVG sprite with use, which recovers caching).
- Site logo repeated everywhere, no dynamic styling → img with an external SVG file.
- Decorative background shapes → CSS background.
- Anything a user uploaded → sanitize, then img — never inline.
Whichever you choose, optimize the file first: strip editor metadata, reduce coordinate precision, and remove hidden layers. Well-optimized UI icons are usually a few hundred bytes, and unoptimized exports are routinely ten times that.