How to use SVG in HTML: inline, img or CSS background
Three main ways to put an SVG in a web page: an img tag, inline svg markup, or a CSS background. What each allows, with code, sizing and common faults.
Published
There are three main ways to use an SVG in HTML. Link to the file with <img src="logo.svg">, paste the <svg> markup straight into the page (inline SVG), or set it as a CSS background-image. Use <img> for pictures that only need showing, inline SVG when CSS or JavaScript must change the drawing, and a background for decoration.
The methods compared
<img> | Inline <svg> | CSS background | <object> | |
|---|---|---|---|---|
| Cached as its own file | Yes | No | Yes | Yes |
| Page CSS can restyle the shapes | No | Yes | No | No |
| Page JavaScript can reach the shapes | No | Yes | No | Yes, on the same origin |
| Scripts inside the SVG run | No | Yes | No | Yes |
| Links inside the SVG work | No | Yes | No | Yes |
| Alternative text | alt | <title> or aria-label | None | Fallback content |
1. The img tag
<img src="logo.svg" alt="Plotcaster" width="200" height="60">
This treats the SVG like any other image. The file is cached by the browser, the markup stays short, and alt gives it a text alternative. Setting width and height reserves the space before the file arrives, so the page does not jump.
The browser draws an SVG in an <img> in a restricted mode. Scripts in the file do not run, links in it cannot be clicked, and it cannot load anything else: an external font, stylesheet or picture that the SVG refers to is ignored. Styles and animations written inside the file itself still work.
2. Inline SVG
<svg viewBox="0 0 24 24" width="24" height="24" role="img" aria-label="Warning">
<path d="M12 2 2 22h20z" fill="currentColor"/>
</svg>
The SVG becomes part of the page. Every shape is an element that CSS can style and JavaScript can change, hover and click included. fill="currentColor" makes the shape take the colour of the surrounding text, which is how to change an SVG’s colour with CSS.
Three things to know:
- In an HTML page the
xmlnsattribute is not needed on an inline<svg>. In a separate .svg file it is required. - Inline SVG is not cached on its own. An icon pasted into fifty pages is downloaded fifty times, so keep inline SVG for small drawings.
- If the same SVG is pasted in twice, any
idinside it (for a gradient or clipping path) is duplicated, and both copies will use the first one. Give them different ids.
For a decorative icon beside text that already says the same thing, hide it from screen readers with aria-hidden="true" in place of the role and label.
3. CSS background
.hero {
background: url(waves.svg) no-repeat center / cover;
}
Good for patterns and decoration, which do not belong in the content. The image stays sharp at any background-size. It has the same limits as <img> and no text alternative, so do not use it for anything a reader needs.
Small SVGs can be written into the stylesheet itself as a data URI, which saves a request. SVG to data URI produces one with the characters escaped correctly.
Other ways
<object> loads the SVG as a document of its own, with its scripts and links working:
<object type="image/svg+xml" data="chart.svg">A chart of sales by month</object>
Use it for an interactive SVG that should stay in a separate file. The text inside is shown if the file cannot be loaded. <iframe> and <embed> do much the same and are rarely the better choice.
<use> draws a shape that is defined elsewhere, usually a <symbol> in a sprite file holding many icons:
<svg width="24" height="24"><use href="/icons.svg#search"/></svg>
The sprite is cached once, and an icon drawn with currentColor still takes its colour from the page. The file must come from the same origin as the page: the same scheme, host and port.
Setting the size
An SVG scales cleanly only if its root element has a viewBox. With one, set the size however you like:
.logo { width: 12rem; height: auto; }
Without a viewBox an inline SVG has a fixed size and a smaller box crops it; in an <img> or a background the browser stretches it to the box without keeping its proportions. With neither a size nor a viewBox, browsers draw it at 300 by 150 pixels. SVG viewBox explained shows how to add one.
An inline <svg> is laid out like text, so it sits on the baseline and leaves a small gap beneath when it stands alone. display: block or vertical-align: middle removes the gap.
Which to choose
- Logo or illustration that never changes:
<img>. - Icons that change colour with the text or on hover: inline SVG, or a sprite with
<use>. - Animation driven by page CSS or JavaScript, charts, maps: inline SVG.
- Patterns and decorative shapes: CSS background.
- Email: none of these. Most email programs do not show SVG, so convert it to PNG.
Common problems
| What you see | Cause | Fix |
|---|---|---|
| Broken image icon | The .svg file lacks xmlns="http://www.w3.org/2000/svg", or the path is wrong | Add the attribute to the root <svg>; check the address |
| Works on your computer, broken on the server | The server sends the file with the wrong type | Serve .svg as image/svg+xml |
| Shown at the wrong size, often 300 by 150 | No size and no viewBox | Add a viewBox, then set a width |
Cropped (inline) or stretched (<img>) when resized | No viewBox | Add viewBox="0 0 W H" with the original size |
| Text in the wrong font | An SVG in an <img> cannot load web fonts | Convert the text to paths in a vector editor |
| CSS colour has no effect | The SVG is in an <img> or a background | Inline it, or use a mask |
| Gap under the image | Inline SVG sits on the text baseline | display: block |
| An upload form refuses the file | SVG can carry scripts, so many sites block it | Upload a PNG copy |
Questions
Is inline SVG bad for page speed? Not for a few small icons: it saves requests. Large drawings repeated on many pages are better as files, which the browser caches.
Do all browsers support SVG? Every current browser supports all the methods here.
Can an SVG be a favicon? Chrome, Edge and Firefox accept one, with <link rel="icon" href="/icon.svg" type="image/svg+xml">. Keep an .ico file as the fallback, since not every browser version still in use takes an SVG icon.
What is inside the markup? Shapes, paths and groups, described in What is an SVG file.