How to Convert SVG to a Data URI for Inline CSS

You've got a small SVG icon — a chevron, a checkmark, a background pattern — and you don't want to burn a separate HTTP request just to load it. So you try pasting the raw markup into a CSS url() and it breaks immediately: the icon doesn't show, or the whole CSS rule gets silently ignored. Quotes conflict, a stray # cuts the string off early, and suddenly a five-minute task turns into twenty minutes of trial and error.

The fix isn't complicated once you know what's actually happening. A data URI just needs specific characters encoded — not the whole string — and SVG being plain text (not binary) means you almost never need base64 for it. Get the encoding right once, and you can drop any small SVG straight into background-image, mask-image, or list-style-image with zero extra requests.

Quick Answer

To convert an SVG into a data URI for CSS, minify the markup, swap its double quotes for single quotes, and URL-encode only the characters that break CSS parsing — mainly #, ", and <>. Skip base64: since SVG is plain text, URL-encoding produces a smaller, human-readable string that drops straight into background-image: url().

What is a data URI, and why use it for SVG?

A data URI embeds a file's actual content inside the URL itself, instead of pointing to a separate file. The format looks like this:

Data URI structure data:[<mediatype>][;base64],<data>

For SVG, that means the icon's XML markup lives directly inside a CSS url() value — the browser parses it in place, with no round trip to a server. This matters most for small, one-off icons: chevrons, checkmarks, dividers, and simple background patterns that would otherwise cost a full HTTP request each.

The key insight: because SVG is already text, not a binary format like a JPEG, it doesn't need base64 to be safely embedded. It just needs the handful of characters that conflict with URL or CSS syntax swapped out — everything else can stay as plain, readable text.

Why it matters

Inlining an SVG as a data URI isn't just a neat trick — it changes how the browser loads and renders your styles in a few concrete ways:

📊 Quick stat URL-encoding a typical small icon (under 1KB) usually adds only 10–20% to its size, while base64-encoding the same file adds roughly 33% — with no upside for a text-based format like SVG.

Step-by-step: convert SVG to a data URI

  1. Minify the SVG first. Strip comments, editor metadata, and unnecessary decimal precision before encoding anything — design tools often export SVGs two or three times larger than they need to be.
  2. Replace double quotes with single quotes. Change every " inside the SVG's attributes to ', since you'll wrap the whole data URI in double quotes inside your CSS url().
  3. Encode the characters that break URLs or CSS. At minimum, encode #%23, <%3C, >%3E, and %%25. Everything else can generally stay as plain text.
  4. Drop the XML declaration and namespace clutter. Remove any <?xml ...?> prolog — it isn't needed inside a data URI and just adds extra characters to encode.
  5. Skip the base64 flag. Use the plain form, data:image/svg+xml,, rather than data:image/svg+xml;base64, — no ;base64 means the browser reads your encoded text directly.
  6. Paste it into the CSS declaration. Wrap the finished string in double quotes inside url(), as shown in the example below.
  7. Test it in the browser at real size. Some encoders miss an edge-case character in complex paths or gradients — always render the result before shipping it, especially for icons with # in fill or stroke colors.
Before → after /* Raw SVG */ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path fill="#333" d="M5 12h14M12 5l7 7-7 7"/> </svg> /* As a CSS-ready data URI */ .icon-arrow { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23333' d='M5 12h14M12 5l7 7-7 7'/%3E%3C/svg%3E"); }
Try the Rebrixe SVG to Data URI Converter — free Paste your SVG, get a CSS-ready data URI instantly, with a live preview.
Convert an SVG Now →

Common mistakes that break the icon

1. Leaving the # character unencoded

In a URL, # marks the start of a fragment identifier. An unencoded #333 fill color or an #-prefixed id reference will cause the browser to treat everything after it as a fragment, quietly breaking the icon. Always encode it as %23.

2. Mixing double quotes inside and outside the URI

If your SVG's attributes use double quotes and you also wrap the data URI in double quotes in CSS, the first internal quote closes the url() value early. Switch the SVG's attribute quotes to single quotes before encoding — it's the single most common cause of a "correctly encoded" icon that still won't render.

3. Reaching for base64 by default

Base64 is necessary for binary formats like JPEG or PNG, but SVG is text. Base64-encoding it adds roughly a third more characters for no benefit and makes the resulting CSS completely unreadable and undiffable in version control.

4. Skipping minification before encoding

Encoding a bloated, unminified SVG just carries that bloat into your CSS file. Comments, editor-generated metadata, and excessive path precision should be stripped before encoding, not after — there's nothing to gain by inlining wasted bytes.

💡 Pro tip Keep the original, editable SVG file in your project as the source of truth, and generate the encoded data URI from it as a build step. Editing an already-encoded string by hand is error-prone — always go back to the readable source when the icon needs to change.

Real-world encoding examples

These are representative results from minifying and URL-encoding common icon types, compared to their original exported SVG size:

Chevron icon
Editor export → minified + encoded
−58%
410 bytes → 172 bytes. Renders identically as a background-image.
Checkmark icon
URL-encoded vs base64
−24%
URL-encoding came in noticeably smaller than the base64 version of the same icon.
Background pattern
Unminified → minified before encoding
−63%
1.4 KB → 520 bytes once editor metadata and comments were removed.
Multi-color icon
With unencoded # characters
Broken
Failed to render until every # in fill/stroke values was encoded to %23.

The pattern holds across icon types: minifying before encoding does most of the size work, URL-encoding beats base64 for anything text-based, and the vast majority of "it just won't show up" cases trace back to an unencoded # or a quote conflict.

Comparison: URL-encoding vs base64

Both methods work in every modern browser, but they trade off differently depending on what you need from the result:

Method Size overhead Readability Effort Best for
URL-encoding (percent-encoding) 10–20% Human-readable, diffable Low Nearly every SVG icon in CSS
Base64 encoding ~33% Unreadable Low Build-tool-generated output, complex SVGs with heavy quoting
External SVG file 0% Fully readable Low Icons reused across many pages, cache-friendly assets
Inline <svg> in HTML 0% Fully readable Low Icons that need CSS styling of individual paths (not usable in url())

Free tool: SVG to Data URI Converter

The Rebrixe SVG to Data URI Converter runs entirely in your browser. Paste in your SVG markup, and it minifies, escapes quotes, and URL-encodes the result into a ready-to-paste url() value — with a live preview so you can confirm it renders before you copy it into your stylesheet. No account, no upload, no watermark.

Turn your SVG into CSS-ready code in seconds

Paste your markup, get a properly encoded data URI, and preview it live before you copy it.

Open the SVG to Data URI Converter →

Frequently asked questions

A data URI embeds the actual file content inside the URL itself, using the format data:[mediatype][;base64],<data>. For SVG, this means the icon's markup lives directly inside a CSS url() value, so the browser never has to make a separate HTTP request to fetch it.
URL-encoding almost always wins for SVG. Because SVG is plain text (not binary), URL-encoding it produces a smaller, human-readable string, while base64 adds roughly 33% overhead on top of the original size for no benefit in modern browsers.
In a URL, # marks the start of a fragment identifier. If your SVG contains an unencoded # (common in fill colors like #333 or in id references), the browser treats everything after it as a fragment and the icon fails to render. Encoding it as %23 fixes this.
Yes, if you're wrapping the data URI in double quotes inside your CSS, the SVG's own attribute quotes need to be single quotes instead. Otherwise the outer double quote closes the url() value early and the browser reads the remaining SVG as invalid CSS.
Yes, somewhat. An external SVG file is cached once and reused across pages, while a data URI is baked into the CSS file itself and re-downloaded every time that CSS changes. For icons reused across many pages, an external file can cache better; for one-off or CSS-only icons, inlining wins on request count.
There's no hard browser limit for typical use, but practically you should keep inlined SVGs small — under a few kilobytes. Large or highly detailed SVGs bloat the CSS file itself and are better served as external files or sprite sheets.
Yes. The same encoded data URI works in background-image, mask-image, border-image, and list-style-image — anywhere CSS accepts a url() value.
Often a significant one. Editor metadata, comments, unnecessary decimal precision, and default attributes exported by design tools can double or triple an SVG's size before it's ever encoded. Minifying first means less to encode and a smaller CSS file.

Stop hand-encoding SVGs

The Rebrixe SVG to Data URI Converter runs entirely in your browser — no uploads, no account, no file size limits. Preview the result before you copy it.

Open the SVG to Data URI Converter →
← Back to blogs