How to generate css background-image data uris from svg files
- Step 1Open the generator and confirm you are on Pro — The CSS Data-URI Generator is a Pro-tier tool. On the free plan the page shows an upgrade overlay instead of the upload box. On Pro the file limit is 50 MB; the free limit elsewhere on the SVG suite is 5 MB.
- Step 2Upload an SVG file or paste the source — Drop a
.svgfile onto the dashed area, click to browse, or paste the markup into the textarea. When you paste, the tool validates it as SVG XML first and rejects anything whose root element is not<svg>or that fails to parse. - Step 3Click Process SVG — There are no options to set — the generator has a single fixed behaviour. It URL-encodes the markup, derives a class name from the filename, and assembles the CSS rule. Pasted source is treated as the file
input.svg, so the class becomes.icon-input. - Step 4Copy the CSS or download the file — Use Copy to clipboard for a quick paste, or Download to save a
<stem>-data-uri.cssfile. The result panel also shows the original SVG size and the encoded output size so you can see the encoding overhead. - Step 5Rename the class to match your design system — The generated class is
.icon-<filename-stem>(lowercased, non-alphanumerics folded to-). It is a starting point — rename it in your stylesheet to whatever your naming convention expects; only the selector changes, theurl(...)value stays identical. - Step 6Apply it to a sized element — A
background-imagepaints onto an element that already has dimensions. Give the target awidth/height(or padding) —background-size: containthen scales the SVG to fit. The defaultbackground-position: centerandno-repeatmean a single centred mark.
What the generator emits
The output is a fixed-shape CSS rule. The only thing that varies per file is the class name (derived from the filename) and the encoded markup. There is no UI to change these.
| Part of the output | Value | Configurable in the web tool? |
|---|---|---|
| Selector | .icon-<filename-stem> — stem lowercased, runs of non-alphanumerics replaced with - | No — rename in your stylesheet after copying |
background-image | url("data:image/svg+xml;charset=utf-8,<encoded>") | No |
background-repeat | no-repeat | No |
background-position | center | No |
background-size | contain | No |
| Encoding | URL/percent-encoding with charset=utf-8 (never base64) | No — for base64 use svg-to-base64 |
Characters the encoder rewrites
Applied in this exact order. % is encoded first so the % introduced by later substitutions is not encoded again. Spaces and most other characters are left literal — modern browsers accept unencoded spaces inside a quoted data URI.
| Input character | Becomes | Why |
|---|---|---|
| Newlines / runs of 2+ spaces | Collapsed to a single space | Shrinks the URI; whitespace between tags is insignificant in SVG |
% | %25 | Must go first so later-introduced % escapes are not double-encoded |
" | ' (single quote, literal) | Inner double quotes would terminate the url("...") wrapper |
# | %23 | An unescaped # starts a URL fragment and truncates the data URI (the classic fill="#000" bug) |
< | %3C | Safest cross-browser; Firefox in particular is strict about raw angle brackets |
> | %3E | Pairs with < for consistent parsing |
& | %26 | Avoids being read as an entity/parameter separator |
Cookbook
Real before/after fragments. The url(...) value is identical whether you copy from the web tool or pull it from a paired runner — only the surrounding rule and class name change.
A two-colour icon encoded to a CSS rule
The hashes in the fills are the part that breaks naive inlining. Notice # → %23 and the attribute quotes flipped to single quotes.
Input (search-icon.svg):
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<circle cx="11" cy="11" r="7" fill="#0a0a0a"/>
<path d="M21 21l-4-4" stroke="#0a0a0a"/>
</svg>
Output (search-icon-data-uri.css):
.icon-search-icon {
background-image: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'> <circle cx='11' cy='11' r='7' fill='%230a0a0a'/> <path d='M21 21l-4-4' stroke='%230a0a0a'/> </svg>");
background-repeat: no-repeat;
background-position: center;
background-size: contain;
}Pasted source becomes .icon-input
When you paste markup instead of uploading a file, the tool names the virtual file input.svg, so the class is derived from input. Rename it before shipping.
Paste this into the textarea:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><rect width="16" height="16" fill="#6366f1"/></svg>
Generated selector:
.icon-input { ... }
Fix in your stylesheet:
.btn-icon { /* paste the background-image + repeat/position/size lines here */ }Filename with spaces and capitals
The class name is sanitised: lowercased, and any run of characters outside [a-z0-9_-] collapses to a single dash.
File: Brand Logo FINAL (v2).svg
Derived class:
.icon-brand-logo-final-v2- { ... }
(trailing dash comes from the closing paren → dash)
Rename to .brand-logo for production CSS.Using the rule on a sized element
A background image needs a box with dimensions. The generated rule supplies repeat/position/size; you supply width and height.
/* generated */
.icon-menu {
background-image: url("data:image/svg+xml;charset=utf-8, ... ");
background-repeat: no-repeat;
background-position: center;
background-size: contain;
}
/* you add */
.icon-menu {
display: inline-block;
width: 24px;
height: 24px;
}Why this beats base64 here
For SVG, URL-encoding leaves the bulk of the markup as ASCII; base64 expands everything ~33%. Same icon, two encodings.
SVG source: ~190 bytes URL-encoded data URI value: ~210 bytes (only #,<,>,& expanded) base64 data URI value: ~260 bytes (whole payload +~33%) → For background-image, prefer this tool. → If a build step or library REQUIRES base64, use /svg-tools/svg-to-base64 instead.
Edge cases and what actually happens
Free-tier user opens the tool
Pro requiredThe CSS Data-URI Generator has minTier: pro. On the free plan the page renders an upgrade overlay instead of the upload box, so there is no free encode here. The free 5 MB SVG limit applies to free-eligible tools elsewhere in the suite; Pro raises the per-job limit to 50 MB.
Pasted text is not valid SVG
Invalid SVGWhen you paste source, the tool parses it and checks that the root element is <svg> with no parser error. A snippet that is just a <path>, an HTML fragment, or malformed XML is rejected with Invalid SVG — could not parse the pasted content as valid SVG XML before any encoding runs.
You expected a base64 string
By designThis generator only produces URL/percent-encoded output (charset=utf-8). There is no toggle to switch to base64. If a toolchain specifically needs base64 (some older bundlers, certain email pipelines), generate it with svg-to-base64, which has an includePrefix option.
You wanted just the URI, not a full CSS rule
ExpectedThe output is always a complete CSS rule (selector + four declarations). To reuse only the URI — for example in an <img src> or a CSS custom property — copy the value inside url("..."). The tool does not emit a bare-URI variant.
The class name has a trailing or doubled dash
ExpectedThe selector is icon- plus the filename stem with every run of non-[a-z0-9_-] characters folded to one dash. Parentheses, spaces, and dots all become dashes, which can leave a trailing dash (e.g. logo (1).svg → .icon-logo-1-). Rename the selector after copying; it has no effect on the encoded value.
SVG references an external resource
Not fetchedThe encoder works on the literal text you give it. An <image href="photo.png">, an external font, or a <use href="sprite.svg#id"> is encoded verbatim, not inlined — and once inside a data URI, an SVG generally cannot reach external resources, so those references will not load. Flatten such references before encoding.
SVG already uses single quotes
PreservedThe quote substitution only rewrites double quotes to single quotes. Markup that already uses single-quoted attributes passes through unchanged on that step and still encodes correctly, because the wrapper is double-quoted (url("...")).
An unencoded # in your own hand-edit truncates the URI
Encoding errorIf you copy the rule and later hand-edit a colour back to a literal #abcdef, the URI will silently truncate at the # (everything after is treated as a fragment). Re-run the file through the tool instead of patching colours in the encoded string — it encodes # to %23 for you.
Multi-megabyte SVG (illustration, not icon)
Allowed but largePro accepts up to 50 MB input, but a large illustration produces a correspondingly huge data URI that bloats your CSS and slows parsing. Data URIs suit small marks. For heavyweight art, keep an external .svg file — see the data-URI vs external-file trade-off guide.
Frequently asked questions
Does this tool output URL-encoded or base64 data URIs?
URL-encoded (percent-encoded) only, with a charset=utf-8 declaration. It never produces base64. URL-encoding is preferred for SVG because most of the markup stays as plain text and only % # < > & expand, so the result is usually smaller than base64.
Can I switch it to base64 output?
No — there is no encoding toggle on this tool. If you need base64 (for example a bundler or library that requires it), use the svg-to-base64 tool, which has an option to include or omit the data:image/svg+xml;base64, prefix.
Do I have to use single quotes inside my SVG?
You don't have to prepare them — the encoder automatically converts every double-quoted attribute to single quotes during encoding. That is required because the data URI itself is wrapped in double quotes (url("...")), so inner double quotes would terminate it early.
What class name will I get?
.icon-<filename-stem>, with the stem lowercased and any run of characters outside a-z, 0-9, _, - folded to a single dash. If you paste source instead of uploading, the file is treated as input.svg, so you get .icon-input. Rename it freely after copying.
Why does the output include background-repeat, position, and size?
The tool emits a complete, sensible default rule: no-repeat, center, and contain so a single icon renders centred and scaled to its box. You can delete or override any of those lines — only the background-image value is load-bearing.
Can I use the result in an <img> tag or pseudo-element?
The tool emits a background-image rule, but the url("data:...") value itself is reusable. Copy the part inside url("...") for an <img src> or a ::before { content: url(...) }. For pseudo-elements, set explicit dimensions on the element.
Does the SVG get uploaded anywhere?
No. Processing runs in your browser. On Pro with a paired local @jadapps/runner the same transform can run on your own machine via the runner — JAD's hosted API never accepts file uploads.
Why is my icon not showing up?
A background-image is invisible on a zero-size box. Give the target element a width and height (or padding). Also confirm the SVG has a viewBox so background-size: contain has an aspect ratio to scale within.
What tier do I need?
This is a Pro-tier tool. The free plan shows an upgrade overlay. Pro allows SVG inputs up to 50 MB per job.
Are spaces encoded?
No — the encoder collapses runs of whitespace to single spaces and leaves those spaces literal. Modern browsers accept unencoded spaces inside a quoted data URI value, so this keeps the output shorter.
Will it inline external images or fonts referenced by the SVG?
No. It encodes the literal markup. External <image>, <use>, or font references are encoded as-is and generally won't load from inside a data URI. Flatten or embed them before encoding.
How do I theme the icon's colour with CSS later?
You can't restyle an SVG that lives inside a data URI from the outside — it's isolated from the document's cascade. If you need theme-aware colour, inline the SVG instead and use svg-to-tailwind (currentColor / palette classes) or svg-css-variable-injector.
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.