Three Ways to Use SVG Icons in Your Web Projects
SVG icons stay sharp at any size, and a simple logo is usually a few kilobytes instead of the tens you would pay for a PNG at several resolutions. But there is more than one way to put an SVG on a page, and the method you pick decides what you can do with the icon afterwards: whether you can recolor it, animate it, cache it, or make it accessible to screen readers.
This guide walks through the three techniques that cover almost every real project, shows working code for each, and ends with a short checklist for choosing between them.
1. Inline SVG
With inline SVG you paste the <svg> markup straight into your HTML (or return it from a component). The icon becomes part of the page's DOM, which means CSS and JavaScript can reach every path inside it. You can change colors on hover, animate individual shapes, or swap strokes for a dark theme.
<svg viewBox="0 0 24 24" width="32" height="32" fill="currentColor" role="img" aria-label="Linux">
<path d="M12 2a10 10 0 100 20 10 10 0 000-20z" />
</svg>The costs are real, though. The markup is repeated in every page that uses it, so it cannot be cached separately from the HTML, and a large icon set pasted inline can noticeably bloat your documents. Inline SVG is best for a handful of important icons, such as the logo in your header or icons you need to animate.
2. The img tag
Referencing an SVG file from an img tag is the simplest approach and behaves exactly like any other image. The browser downloads it once, caches it, and reuses it everywhere. Giving it explicit width and height attributes also reserves space before it loads, which prevents layout shift.
<img src="/svgs/linux.svg" alt="Linux" width="32" height="32" loading="lazy" />The trade-off is isolation. An SVG loaded through img is rendered as a separate document, so the page's CSS cannot restyle what is inside it. That makes img a good fit for multi-color logos whose colors should never change, and a poor fit for icons that must follow your theme. A useful side effect is safety: scripts inside an SVG do not run when it is loaded through img.
3. CSS mask-image
For single-color icons there is a middle path. You load the SVG file as a mask and paint the visible area with any background color. The shape comes from the cacheable file, while the color is ordinary CSS. This is how the gallery on this site tints its icons with their brand colors.
.icon {
width: 32px;
height: 32px;
background-color: #1793d1;
-webkit-mask: url(/svgs/archlinux.svg) center / contain no-repeat;
mask: url(/svgs/archlinux.svg) center / contain no-repeat;
}Two limits to know about. A mask only carries shape, so every icon rendered this way is one flat color; multi-color logos will lose their detail. And if the SVG is served from a different origin than your page, the browser requires CORS headers before it will use it as a mask.
Making icons accessible
Whichever method you use, decide whether the icon carries meaning. If it is the only content of a button or link, it needs a text alternative. If it is purely decorative, hide it from assistive technology so it is not announced as noise.
- img: write a meaningful alt attribute, or alt="" when the icon is decorative.
- Inline SVG: add role="img" and an aria-label, or aria-hidden="true" when decorative.
- Masked element: a div has no inherent meaning, so add role="img" with aria-label, or aria-hidden="true".
Performance tips that apply to all three
- Run files through an optimizer such as SVGO to strip editor metadata; this often cuts file size noticeably without changing the picture.
- Always set width and height (or a CSS size) so the page does not jump when the icon loads.
- Serve SVG files with compression enabled; they are text and compress very well.
- Prefer a single cached file over copying the same markup into many places.
Which should you pick?
- You need to animate or style individual paths: use inline SVG.
- You are showing a logo or multi-color artwork that should not change: use img.
- You want to recolor single-color icons from CSS while keeping files cacheable: use mask-image.
Many sites mix all three: inline SVG for the header logo, img for decorative illustrations, and masks for a themed icon set. Pick per icon based on what you need to do with it, and you will rarely have to revisit the decision.