My Tool Studio
CSS Generators·4 min read

Embedding SVG in CSS as Data URIs

A stylesheet can carry its own images. Encode an SVG as a data URI, wrap it in url(), and the icon, pattern, or bullet arrives with the CSS itself, no extra request, no asset pipeline. Embedding svg in css this way is an old technique that modern URL-encoding made practical again, producing output small enough and readable enough to live comfortably in source control. This article covers how the encoding works, a worked example you can paste, when an external file still wins, and the mistakes that leave you staring at a blank background.

SVG to CSS …{"id": 78"ok": true}

Why an SVG background beats another request

The math on small assets.

For a tiny asset, the HTTP request often costs more than the payload: headers and queueing to fetch a 400-byte arrow is terrible economics, and multiplied across chevrons, checkmarks, and dividers it adds up. Inlining the graphic into the stylesheet deletes those requests entirely.

The technique fits a specific size class: icons, list bullets, repeating background patterns, form control decorations. These assets are small, stable, and referenced from CSS anyway, so moving the bytes into the url() they were already sitting inside is a pure win. Photographic or heavily detailed vector art is a different story, covered below.

Embedding SVG in CSS: how the data URI works

A URL that contains its own answer.

A data URI packs the resource into the URL itself: data:image/svg+xml, followed by the markup, encoded so no character can break the surrounding CSS. Browsers parse it like any fetched image, just without the fetch.

There are two ways of encoding svg for css. Modern URL-encoding percent-escapes only the dangerous characters, angle brackets, hashes, quotes, and a few others, leaving the rest human-readable. Base64 encoding converts the whole document into an opaque alphabet that survives even ancient parsers like IE9's, at the cost of about 33 percent size inflation and total unreadability. The SVG to CSS Converter offers both as a Browser support toggle.

A worked SVG data URI you can paste

One purple dot, fully encoded.

Take a minimal 8px circle: <svg xmlns='http://www.w3.org/2000/svg' width='8' height='8'><circle cx='4' cy='4' r='4' fill='#A855F7'/></svg>. URL-encoded and wrapped, it becomes: background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Ccircle cx='4' cy='4' r='4' fill='%23A855F7'/%3E%3C/svg%3E");.

Read the substitutions: %3C and %3E are the angle brackets, %23 is the hash in the hex color, and the double quotes became singles so they don't fight the url() wrapper. Everything else survived untouched, which is why you can still spot the circle and its radius in the encoded string. That legibility is the practical argument for URL-encoding over base64.

Data URI vs external SVG

Inline is not always the answer.

The data uri vs external svg decision is about caching and reuse. An inlined graphic is fused to the stylesheet: it can't be cached separately, lazy-loaded, or updated without shipping new CSS, and if the same URI appears in five rules, you pay its bytes five times.

External files keep their own cache entry and URL, which wins for anything large, shared across stylesheets, or likely to change independently. The working rule: inline assets under a couple of kilobytes that belong to the stylesheet's design, keep everything else as files. The size readout in the SVG to CSS Converter, shown in KB under the output, is exactly the number to sanity-check before committing.

Encoding SVG for CSS without breaking it

The characters that matter.

Raw SVG can't sit in url() because its own syntax collides with the stylesheet's: angle brackets, hashes, parentheses, and quotes all have meanings in CSS. Safe encoding escapes those while leaving letters, numbers, spaces, and most punctuation alone.

Quotes need a plan: the standard trick is converting the SVG's double quotes to singles, then wrapping the whole URI in doubles, which is what the converter does automatically. It also strips XML comments and collapses whitespace runs before encoding, since every stray newline would otherwise become a three-character escape sequence in the output.

SVG encoding mistakes that blank the background

Nothing renders, nothing errors.

Data URI failures are silent, the element just shows no background, so it pays to know the usual causes in advance.

  • No xmlns attribute. Standalone SVG in a data URI must declare xmlns="http://www.w3.org/2000/svg" or browsers render nothing, even though the same markup works inlined in HTML.
  • An unescaped # in a fill color, which the parser reads as a URL fragment and truncates everything after it.
  • Expecting currentColor or CSS custom properties to work inside the URI; a background image can't see the page's cascade.
  • Pasting the encoded string into a single-quoted url() after the encoder already chose single quotes for attributes.
  • Editing the SVG later and forgetting to re-encode, leaving raw angle brackets in the stylesheet.

Tips for smaller SVG data URIs

Bytes you don't ship.

Optimize before you encode. Vector editors bury exports in metadata, editor namespaces, and twelve-decimal coordinates; a pass through SVGO routinely halves file size, and every saved input byte is roughly a saved output byte.

Prefer presentation attributes like fill='#A855F7' over <style> blocks inside the graphic, they encode shorter and behave predictably in both modes. And keep the viewBox simple: an icon drawn on an 0 0 16 16 grid with integer coordinates encodes dramatically tighter than the same shape exported from a 1024-unit artboard.

SVG to CSS Converter alongside related tools

Match the output to the job.

The SVG to CSS Converter is the right tool when the destination is a stylesheet: it encodes, wraps the result as a bare url(), a background-image rule, list bullets, or a full class, and previews the render before you copy.

When the destination can't consume vectors at all, an email template, an og:image, a favicon fallback, the SVG to PNG tool rasterizes the same markup into fixed pixels instead. And for a plain-color fade you were about to encode as a graphic, stop first at the CSS Gradient Generator; a gradient background costs fewer bytes than any encoded image of one.

Try it now

Open SVG to CSS Converter

The tool is one click away. No sign up, no upload, no payment.

Open SVG to CSS Converter