My Tool Studio
CSS Generators·5 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. It's 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 encodings to choose from. URL-encoding percent-escapes only the dangerous characters, angle brackets, hashes, percent signs and a few others, leaving the rest human-readable. Base64 converts the whole document into an opaque alphabet that survives even ancient parsers like IE9's, at the cost of about a third more size and total unreadability. The SVG to CSS Converter offers both under Browser support, as Modern (URL-encoded) and Legacy (base64).

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 attributes use single quotes so they don't fight the double quotes around the url() value. 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.

When an external SVG file wins

Inline is not always the answer.

Choosing between a data URI and a separate file 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 line in the SVG to CSS Converter, which shows the data URI size in KB and bytes, is exactly the number to sanity-check before committing.

Escaping SVG without breaking the stylesheet

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's Modern output does automatically. If the SVG already contains single quotes, it encodes double quotes as %22 instead so attributes stay intact. It also 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, so currentColor falls back to black. Swap it for a real color in the converter's Replace colors panel before encoding.
  • 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 long decimal coordinates, and every saved input byte is roughly a saved output byte. The converter's Optimize switch strips the XML declaration, comments, metadata and Inkscape, Sodipodi and Sketch attributes, rounds numbers to the decimal places you pick, and reports the bytes saved. It is lighter than a full optimizer like SVGO, so run SVGO first for heavy files.

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 much 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. Paste the markup, upload an .svg or drop one on the input, recolor fills and strokes under Replace colors, and pick one of seven helpers: a bare URL wrapper, a basic or advanced background-image rule, CSS bullets with list-style-image, a ready-made .svg-bg class, a recolorable mask-image icon, or a CSS custom property. The preview shows the render before you press Copy CSS.

When the destination can't consume vectors at all, an email template, an og:image, a favicon fallback, the SVG to PNG Converter 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