How to svg data uris: browser compatibility, encoding rules, and troubleshooting
- Step 1Check the MIME type — The prefix must be
data:image/svg+xml.data:image/svg(missing+xml) or an omitted type makes the browser refuse to render it. The JAD tool always emitsdata:image/svg+xml;charset=utf-8,. - Step 2Verify the special characters are escaped —
#→%23,<→%3C,>→%3E,&→%26, and%→%25(first). An unescaped#is the single most common cause of a truncated, blank-rendering URI. The generator escapes all of these. - Step 3Confirm the inner quotes are single — Wrap the URI in double quotes (
url("...")) and use single quotes inside the SVG. Double quotes inside would terminate the URI early. The tool converts all double quotes to single quotes automatically. - Step 4Test the URI in the address bar — Paste the full
data:image/svg+xml,...string into the browser's address bar and press Enter. If the SVG renders, the encoding is valid and any failure is in your CSS. If it doesn't, the encoding is the problem. - Step 5Test the same URI in Firefox — Firefox is stricter than Chrome about escaping and namespaces. If a URI works in Chrome but not Firefox, re-encode it (the JAD tool produces Firefox-safe output) and confirm the SVG carries
xmlns="http://www.w3.org/2000/svg". - Step 6Check the rendered context — A
background-imageneeds a sized box; an<img>needs width/height or it uses intrinsic size. Confirm the SVG has aviewBoxsobackground-size: containhas an aspect ratio to work with.
Encoding requirements
What must be true for a CSS/HTML SVG data URI to render. The JAD generator satisfies every row automatically.
| Requirement | Correct | Symptom if wrong |
|---|---|---|
| MIME type | data:image/svg+xml | Browser rejects the URI; nothing renders |
| Charset (optional but used here) | ;charset=utf-8 | Non-ASCII text in the SVG may misrender |
# escaped | %23 | URI truncates at the #; usually blank |
< / > escaped | %3C / %3E | Parse failure, especially in Firefox |
& escaped | %26 | Read as an entity/separator; parse error |
% escaped first | %25 | Double-encoding corrupts later escapes |
| Inner quotes | single (') | Double quotes terminate url("...") early |
| Namespace present | xmlns="http://www.w3.org/2000/svg" | Firefox may refuse to render |
Browser behaviour notes
Both URL-encoded and base64 SVG data URIs render in current Chrome, Firefox, Safari, and Edge. Differences are about strictness, not support.
| Browser | Strictness | Practical note |
|---|---|---|
| Chrome / Edge (Chromium) | Lenient | May tolerate some under-escaping — don't rely on it |
| Firefox | Strict | Requires # escaped and a proper namespace; the JAD output passes |
| Safari | Standard | Works with correctly escaped, namespaced SVG |
| All modern browsers | Support both encodings | URL-encoded is smaller for SVG; base64 is a separate tool |
Cookbook
Diagnostic recipes for the failures people actually hit. Each isolates the cause so you fix the right thing.
The unescaped-# truncation
The classic. The first # in a colour value ends the URI; everything after is treated as a fragment, so the SVG is incomplete and renders blank.
Broken (literal #):
background-image: url("data:image/svg+xml,<svg ... fill=#000000 ...></svg>");
→ truncates at #000000; blank.
Fixed (# → %23, via the tool):
background-image: url("data:image/svg+xml;charset=utf-8,<svg ... fill='%23000000' ...></svg>");Wrong MIME type
Dropping the +xml is a silent killer — the browser doesn't treat the payload as SVG.
Rejected: url("data:image/svg,<svg ...></svg>")
Rejected: url("data:,<svg ...></svg>") (no type)
Correct: url("data:image/svg+xml;charset=utf-8,<svg ...></svg>")Quote collision
Double quotes inside the SVG end the url() wrapper prematurely. Single quotes inside, double quotes outside.
Broken:
url("data:image/svg+xml,<svg xmlns="http://..."> ...")
→ the second " closes the url() too early.
Fixed (tool converts " → '):
url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://...'> ...")Works in Chrome, blank in Firefox
Chrome's leniency masks an under-escaped URI; Firefox enforces the rules. Re-encode and add the namespace.
Symptom: renders in Chrome, blank in Firefox.
Check 1: is every # escaped to %23? (Firefox enforces it)
Check 2: does the <svg> have
xmlns="http://www.w3.org/2000/svg"?
Fix: re-run through the JAD generator and ensure the
source carries the namespace.Address-bar isolation test
Separate encoding bugs from CSS bugs in five seconds.
1. Copy the data:image/svg+xml,... value.
2. Paste into the address bar, press Enter.
- Renders → encoding is fine; debug your CSS
(box size, viewBox, selector).
- Blank/error → encoding is the problem
(MIME, #, quotes, namespace).Edge cases and what actually happens
MIME type missing +xml
Rejecteddata:image/svg (without +xml) or an omitted type causes the browser to refuse the payload as an image. The required prefix is data:image/svg+xml. The JAD generator always emits the correct type.
Unescaped # in a colour
TruncatedA literal # starts a URL fragment, cutting the SVG off mid-markup so it renders blank. Every # must be %23. This is the number-one hand-rolled-URI failure; the generator escapes it for you.
Works in Chrome, fails in Firefox
Strictness mismatchChromium browsers sometimes render under-escaped URIs; Firefox enforces escaping and namespace rules. A URI that 'works' in Chrome can be subtly invalid. Re-encode with the tool and ensure the SVG declares its namespace.
Double quotes inside the SVG
Parse errorInner double quotes terminate the url("...") wrapper early, corrupting the rule. Use single quotes inside; the encoder converts double quotes to single quotes automatically so this can't happen with generated output.
Missing xmlns
May not renderAn SVG without xmlns="http://www.w3.org/2000/svg" may render in some contexts but not others (Firefox is strict). Keep the namespace on the root <svg> before encoding.
Trying to style the SVG from outside
IsolatedSVGs in a data URI (background or <img>) are sandboxed from the page's CSS — :root custom properties and parent color don't reach them. For themeable colour, inline the SVG and use svg-to-tailwind or svg-css-variable-injector.
Very large data URI
Payload concernBrowsers support large data URIs (well into the megabytes), so the practical limit is your own CSS/HTML size budget, not a hard cap. A huge inlined asset slows CSS parsing — see the data-URI vs external-file guide.
External reference inside the SVG
Won't loadOnce an SVG is a data URI, references to external images, fonts, or <use href> generally won't resolve. Flatten everything into the SVG before encoding, or keep it as an external file.
Frequently asked questions
Are SVG data URIs supported in all modern browsers?
Yes. Both URL-encoded and base64 SVG data URIs render in current Chrome, Firefox, Safari, and Edge. The differences between browsers are about how strictly they enforce escaping and namespaces, not whether support exists.
What MIME type does an SVG data URI need?
data:image/svg+xml. Dropping the +xml (data:image/svg) or omitting the type makes the browser reject the URI. The JAD generator emits data:image/svg+xml;charset=utf-8,.
Why does my data URI render in Chrome but not Firefox?
Firefox is stricter: every # must be escaped as %23, and the SVG needs a proper xmlns namespace. Chrome sometimes tolerates under-escaping. Re-encode with the tool and confirm the namespace is present.
Why is my SVG data URI rendering blank?
Most often an unescaped # truncated the URI, a wrong MIME type, double quotes inside the SVG, or a missing namespace. Paste the URI into the address bar to test the encoding in isolation, then check your CSS box sizing.
How do I escape the # character?
Replace each # with %23. The generator does this automatically — it also escapes < > & % and converts double quotes to single quotes.
Is there a size limit for data URIs?
Browsers handle data URIs well into the megabytes, so there's no practical hard cap for icons. The real constraint is your CSS/HTML payload size and parse time — large inlined assets slow rendering.
Can I use CSS variables inside a data-URI SVG?
No. An SVG in a data URI is isolated from the document's cascade, so :root custom properties don't propagate into it. For variable-driven colours, inline the SVG and use svg-css-variable-injector.
Do I need to base64-encode for compatibility?
No — URL-encoded SVG works everywhere base64 does and is smaller. Use base64 only if a specific tool requires it; the svg-to-base64 tool covers that case.
Should I include charset=utf-8?
It's optional, but it's what the JAD tool emits and it helps non-ASCII text in the SVG render correctly. It doesn't hurt for ASCII-only markup.
Why does the SVG need a viewBox?
A viewBox gives the SVG an intrinsic aspect ratio, which background-size: contain and scaled <img> use to size the graphic. Without it, scaling behaviour can be unpredictable.
Can I use a data URI SVG in an <img> tag?
Yes, in all modern browsers. It renders identically to a background but, like the background, it can't be styled by the page's external CSS. The generator emits a background rule; copy the url("...") value for an <img>.
How do I quickly confirm the encoding is valid?
Paste the full data:image/svg+xml,... string into the browser address bar and press Enter. If it renders, the encoding is correct and any remaining problem is in your CSS rather than the URI.
Privacy first
Every JAD SVG tool runs entirely in your browser using the DOM API and Canvas. Your SVG files never leave your device — verified by zero outbound network requests during processing.