Skip to content

Encode an SVG for CSS and HTML

Convert an SVG to Base64 or the smaller URL-encoded form, with copy-ready background-image, img and Markdown snippets for inline icons.

  • Runs in your browser
  • Files are never uploaded
  • Free, no account
Drop an SVG file hereThe markup is read locally.SVG

Base64 or URL-encoding for an SVG?

This is the one image format where Base64 is usually the wrong answer. SVG is text, so it can go into a data: URI directly with only the handful of characters that break CSS escaped. That produces a shorter string than Base64, keeps the markup readable in the stylesheet, and compresses better over the wire.

Base64URL-encoded
Typical size versus source+33%+5% to +15%
Readable in the stylesheetNoYes
Gzip / Brotli friendlyPoor — byte alignment destroyedGood
Safe in an <img src>YesYes
Tolerant of hand-editingNoYes, with care

Use the toggle above to switch between the two and compare the actual character counts for your own file. Base64 still wins in one situation: a build pipeline or CMS that mangles percent signs or quotes in stylesheet values.

What has to be escaped

In a URL-encoded SVG data URI, the characters that must be handled are %, #, <, > and the quote characters. The technique used here is the one that survives every CSS parser: swap the double quotes inside the markup for single quotes, wrap the whole URI in double quotes, and percent-encode the rest. A raw # is the classic failure — it starts a fragment identifier and silently truncates the icon.

You cannot recolour a data URI

Once an SVG is inside background-image, it is an image. fill: currentColor, CSS custom properties and :hover rules inside your page no longer reach it. Three ways round that, in order of preference:

  1. Inline the <svg> element in your HTML or component. The icon then inherits currentColor and every other CSS rule.
  2. Use mask-image instead of background-image, with a solid background-color behind it. The mask takes the shape and the colour comes from CSS.
  3. Generate one data URI per colour at build time. Crude, but fine for two or three states.

Sanitise before you inline

An SVG is executable markup: it can carry <script>, event handlers and external references. A data URI in background-image renders in a restricted mode where scripts do not run, but the same file inlined as an <svg> element in your DOM absolutely can execute. If the file came from a user, an icon marketplace or a design handoff, read it first — it is text, so you can.

Trim the markup first

Editor exports are verbose. Before encoding, it is usually worth removing the editor metadata, any <title> and <desc> you do not need, empty groups, and a width/height pair that fights your CSS — keep the viewBox, which is what makes the icon scale. This tool collapses runs of whitespace, which is always safe; it deliberately does not rewrite path data, because rounding coordinates changes rendering in ways a preview will not show you.

Questions

Should I use Base64 or URL-encoding for an SVG in CSS?

URL-encoding, almost always. SVG is text, so Base64 adds 33% for nothing; percent-encoding adds far less, stays readable in the stylesheet, and compresses better. This page generates both so you can compare.

Why does my URL-encoded SVG break the stylesheet?

Unescaped hash and quote characters. Our output swaps double quotes for single quotes inside the markup and escapes # and %, which is the combination that survives every CSS parser.

Can I still recolour the icon with CSS?

Not once it is a data URI in background-image — it is an image, so currentColor and fill rules no longer reach it. Inline the SVG element in your HTML if you need it to follow the text colour, or use a mask-image instead.

Does the SVG get minified first?

We collapse runs of whitespace, which is safe. We do not rewrite paths or strip attributes, because that changes rendering in ways that are easy to get wrong and impossible to see in a preview.