Base64 Data URIs in CSS and HTML

Base64 Data URIs in CSS and HTML

How Base64 data URIs embed images, fonts, and SVGs directly in CSS and HTML: the exact syntax, performance trade-offs, and when inlining helps or hurts.

A data URI lets you embed an entire file — an image, a font, an SVG icon — directly inside your HTML or CSS, with no separate network request. The file is Base64-encoded and pasted inline as text. Used well, it shaves milliseconds off page loads. Used carelessly, it bloats your stylesheets and slows everything down. This guide shows the exact syntax, the real trade-offs, and a clear rule for when to reach for it.

Want to generate one right now? Paste a file into Base64 Decode to encode it, or use the dedicated data URI generator to get a ready-to-paste data: string.


What a Data URI Looks Like

A data URI follows a simple structure defined in RFC 2397:

data:[<media type>][;base64],<data>

Broken into parts:

  • data: — the scheme, like https: or mailto:
  • <media type> — the MIME type, e.g. image/png, font/woff2, image/svg+xml
  • ;base64 — signals that the payload is Base64-encoded (omit it for plain-text formats)
  • <data> — the actual encoded bytes

A real example for a tiny PNG:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==" alt="1px dot">

The browser decodes that string and renders it as an image — no HTTP request to a separate file.


Using Data URIs in CSS

The most common place data URIs shine is CSS backgrounds, where eliminating a request avoids a render-blocking round trip:

.icon-check {
  background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0i...");
  background-repeat: no-repeat;
  width: 16px;
  height: 16px;
}

You can inline web fonts the same way inside an @font-face rule:

@font-face {
  font-family: "Brand";
  src: url("data:font/woff2;base64,d09GMgABAAAAAA...") format("woff2");
  font-display: swap;
}

SVG: The One Format You Often Should NOT Base64

SVG is text, not binary. Base64-encoding it works, but it actually makes the file larger and unreadable. For SVG, prefer URL-encoding instead — it stays smaller and you can still edit it by hand:

/* Base64 — larger, opaque */
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxu...");

/* URL-encoded — smaller, human-readable */
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'...%3E");

A dedicated tool like the SVG to data URI converter produces the optimized, URL-encoded form automatically. Reserve Base64 for genuinely binary assets like PNG, JPEG, and WOFF2.


The Performance Trade-Off

Inlining is not free. Every data URI carries the same costs and benefits:

Benefits

  • One fewer HTTP request. For tiny, above-the-fold assets, removing a round trip can measurably improve first paint.
  • Atomic delivery. The asset arrives with the HTML or CSS, so there is no flash of missing image and no second request that might fail.
  • No CORS or path issues. The data travels with the document.

Costs

  • ~33% larger payload. Base64 inflates binary data by roughly a third (every 3 bytes become 4 characters). A 9 KB image becomes ~12 KB of text.
  • No independent caching. A separate image.png is cached once and reused across every page. An inlined image is re-downloaded inside every HTML or CSS file that contains it, on every cache miss.
  • Render-blocking CSS gets heavier. Inlining large images into a stylesheet delays the entire stylesheet — and therefore first paint.
  • Harder to maintain. A 40 KB Base64 blob in your CSS is unreadable and bloats diffs.

The 33% size penalty is inherent to the encoding. If you want to understand exactly why it happens, see what is Base64 encoding.


A Simple Rule of Thumb

Use a data URI when all of these are true:

  • The asset is small (a common guideline is under ~2–4 KB).
  • It is critical and above the fold (a logo, a hero icon, a background used immediately).
  • It is used on one or few pages, so you are not duplicating it site-wide.

Use a normal <img src> or external url() when:

  • The asset is large (photos, illustrations) — the 33% overhead and lost caching outweigh the saved request.
  • It is reused across many pages — shared caching wins.
  • You rely on a CDN, lazy loading, or responsive srcset — none of which work with inlined data.

Modern HTTP/2 and HTTP/3 multiplex requests cheaply, which has reduced the payoff of inlining compared to the old HTTP/1.1 days. Inline deliberately, for specific small assets — not as a blanket strategy.


Generating and Decoding Data URIs

To create a data URI, encode the file to Base64 and wrap it in the data:<mime>;base64, prefix. The data URI generator does this in one step and picks the correct MIME type for you.

To read a data URI back into a file, strip everything up to and including the comma, then Base64-decode the remainder. The Base64 to image tool previews the result, and Base64 to file recovers any file type. Everything runs in your browser, so sensitive assets never leave your machine.


FAQ

What is a Base64 data URI?

A data URI is a string that embeds a file's contents directly in HTML or CSS using the data: scheme. When the file is binary (like a PNG), it is Base64-encoded and prefixed with data:<mime-type>;base64,. The browser decodes it inline, so no separate network request is needed.

Do data URIs make a page faster?

They can, for small critical assets, by removing an HTTP request. But they add ~33% to the asset's size and cannot be cached independently, so inlining large or widely reused files usually makes pages slower overall.

Should I Base64-encode SVG for a data URI?

Usually no. SVG is text, so URL-encoding keeps it smaller and human-readable. Reserve Base64 for truly binary formats like PNG, JPEG, and WOFF2 fonts.

What is the maximum size for a data URI?

There is no hard spec limit, but browsers historically capped data URIs (older IE limited them to 32 KB). Practically, keep them small — a few kilobytes — because large inlined assets bloat your HTML/CSS and hurt caching and paint times.

How do I convert an image to a data URI?

Encode the image to Base64 and prepend data:image/png;base64, (matching the real MIME type). The data URI generator and Base64 Decode do this in the browser, with no upload to a server.

Why is my data URI image not showing?

The usual culprits are a wrong MIME type, a missing ;base64 flag, stray whitespace or line breaks inside the string, or truncated Base64. Re-encode the file cleanly and confirm the prefix matches the actual format.

Try it yourself

Use our free online tool to get started right away

Open Tool