Embedding Images as Data URIs in HTML and CSS

Learn how to embed images, SVGs, and fonts as Base64 data URIs in HTML attributes and CSS. Includes format, size limits, and when to avoid inlining.

Embedding Images as Data URIs in HTML and CSS

A Base64 data URI turns a file into document text.

Inlining beats requesting. A Base64 data URI eliminates the HTTP round-trip for a resource entirely, trading file size for latency. For small icons and email-safe images, the trade-off is favorable when the asset is tiny and reused nowhere else.

Data URIs follow the format data:[<mediatype>][;base64],<data>.1 The browser interprets them identically to external URLs in src and href attributes, CSS url() values, and email img tags. The 33% Base64 overhead is the price of zero network dependency.

What to look for

  • 33% larger than the original binary
  • 32 KB
  • up to 2 MB
  • 4,096 bytes (assetsInlineLimit)

A wrong or mismatched media type prefix produces a silently broken resource, with no console error to explain it.

Opens the Base64 Text & File Encoder/Decoder with this page's reference values shown at the top of the tool.

Open in the tool →

How data URI encoding works

Encoding a resource as a data URI requires three steps: read the file as raw bytes, Base64-encode those bytes using any standard encoder, then prepend data:<mediatype>;base64, to the encoded string to form the complete URI. Each step must be performed in order, because the media type prefix tells the browser how to interpret the bytes that follow, and without it the browser cannot distinguish a PNG from a PDF or a font file.

Building the data URI string

For a PNG, the result starts with data:image/png;base64,iVBORw0KGgoAAAANSUhEUg.... CSS accepts data URIs in the url() function; HTML accepts them in src, href, and action attributes. SVGs can also be URL-encoded instead of Base64-encoded, data:image/svg+xml,%3Csvg..., which is shorter for SVGs because they are text and compress well with percent-encoding. Getting the media type wrong is the single most common data URI mistake, because the browser silently ignores the resource rather than producing a visible error, leaving you with a broken image and no console message to indicate the cause. The media type must match the actual file format exactly: image/jpeg for JPEG files, image/png for PNG files, and font/woff2 for WOFF2 fonts, because the browser uses this type to select the correct decoder and an incorrect type causes the same silent failure as a missing type.

Getting the prefix and the encoded bytes from the same encoder step also keeps the two parts in sync, so the media type never describes a file format that the bytes no longer match after a later edit. It also avoids the classic copy-paste error where an edited asset gets re-encoded but the old media type prefix is left pointing at a format that no longer matches the data.

Common pitfalls and size limits

Internet Explorer historically limited data URIs to 32 KB, but modern Chromium browsers handle up to 2 MB and Safari supports even larger sizes.2 Exceeding the browser-specific limit silently produces a broken image with no console error, which makes this mistake especially frustrating during development because the same URI works correctly when the file is served as a standalone resource.

Budgeting encoded size before inlining

Furthermore, Base64 adds 33% overhead, so a 100 KB PNG inlines as 133 KB of text inside the HTML document. Data URIs bypass the browser's independent resource cache, meaning every page reload re-parses the inline data rather than serving it from cache. Yet for assets used on exactly one page and sized under 4-8 KB, inlining often wins because savings from eliminating an HTTP request outweigh the size penalty. The break-even point depends on your typical round-trip time: on a fast local network where an HTTP request costs 1 millisecond, inlining only makes sense for assets under 2 KB, but on a high-latency mobile connection where each request costs 200 milliseconds, inlining assets up to 8 KB can meaningfully improve the time to first render.

Security and best practice

Data URIs cannot execute scripts by themselves , the browser enforces that data: URLs do not inherit the page's origin. Consequently, an img src data URI cannot run JavaScript even if the payload contains script content. Yet browsers do execute JavaScript in data URIs opened as top-level navigation, so never navigate to user-supplied data URIs. For email, data URIs are the correct approach for embedded images because external image requests are blocked by default in Gmail, Outlook, and Apple Mail. In web applications, limit data URI usage to assets under 8 KB on single-use pages; use a CDN for everything else. Before inlining, compare the encoded size with the original file size and the number of pages that reuse the asset. If the same icon appears on ten pages, external caching may beat the one-request saving from a data URI.

Build tools automate data URI generation at compile time

Vite uses the assetsInlineLimit option (defaulting to 4,096 bytes) to inline assets as Base64 data URIs inside the JavaScript bundle.3 Webpack achieves the same result with url-loader configured with a limit option. Both tools apply the 1.333 multiplier to every inlined file; your bundle analysis report reflects the actual encoded size of each inlined asset. Choosing the right threshold requires understanding that the inlined Base64 text must be parsed and decoded on every page load, so a smaller bundle with more external requests can sometimes outperform a larger bundle with everything inlined.

Measuring the production bundle impact

Review the output of your production build before finalising the threshold. Run the build and open the bundle size report. Raise the threshold in 2 KB increments and measure the page load time impact. The right threshold balances the latency saving from eliminating HTTP requests against the parse cost of a larger JavaScript file at first load. A practical approach is to start with the default threshold, run a Lighthouse audit, and only raise it if the audit shows that eliminating additional HTTP requests meaningfully improves the Time to Interactive metric for your target devices.

Because the browser uses the media type to render the content

Specifying the wrong media type in a data URI causes silent rendering failures. A PNG file with a data URI declaring image/jpeg displays a broken image in some browsers. A font file with an incorrect MIME type fails to load in @font-face. The type must match the actual file format.

Common media types for data URI use: image/png, image/jpeg, image/gif, image/webp, image/svg+xml, font/woff2, application/pdf, text/css. Verify the type against the actual file format rather than trusting the filename extension. For SVG files, the correct MIME type is image/svg+xml; using image/svg or text/xml instead fails silently in CSS url() declarations without producing a browser console error.4

When to use this

Use data URIs when you need zero-request asset delivery: small icons in production HTML, pixel trackers in email, SVG logos in CSS. Avoid them for large images, multi-page assets, and anything that benefits from independent cache control. Once you have a candidate asset, weigh the 33% size cost before inlining to decide whether the zero-request trade-off is worth it for that file.5

Examples

PNG icon in an img tag

Before
<img src="icon.png" alt="Upload">
After
<img src="data:image/png;base64,iVBORw0KGgoAAAA..." alt="Upload">

Replace the file path with the full Base64-encoded PNG content.

SVG background in CSS

Before
.icon { background-image: url("icon.svg"); }
After
.icon { background-image: url("data:image/svg+xml;base64,PHN2Zy..."); }

Alternatively, use URL-encoded SVG (without base64) for text SVGs.

Sources
  1. 1.

    L. Masinter, "The 'data' URL scheme," RFC 2397, IETF, August 1998. https://www.rfc-editor.org/rfc/rfc2397

  2. 2.

    Microsoft, "URL Length Limits," learn.microsoft.com, August 2014. https://learn.microsoft.com/en-us/archive/blogs/ieinternals/url-length-limits

  3. 3.

    "Static Asset Handling," Vite, vitejs.dev, accessed June 2026. https://vite.dev/guide/assets

  4. 4.

    "data: URLs," MDN, developer.mozilla.org, accessed June 2026. https://developer.mozilla.org/en-US/docs/Web/URI/Reference/Schemes/data

  5. 5.

    "Base64," Wikipedia, accessed June 2026. https://en.wikipedia.org/wiki/Base64

FAQ

Yes for all modern browsers. Internet Explorer 9 supports up to 32 KB. Chromium-based browsers, Firefox, and Safari support much larger sizes. For email, data URIs work in Gmail, Apple Mail, and iOS Mail; Outlook for Windows requires external images or inline CID attachments.

Minifiers and CSS processors sometimes truncate or escape Base64 strings. Ensure the data URI is wrapped in quotes inside url() and that your build tool treats the entire string as opaque.

URL-encoded SVG (without ;base64) is typically shorter because SVG is text and percent-encoding compresses well. Base64 is safer , it handles all characters without escaping conflicts. Use URL-encoding for SVGs under 500 bytes where size is critical; use Base64 for compatibility.

Yes. Encode a WOFF2 file as Base64 and use data:font/woff2;base64,... in a CSS @font-face src. This eliminates the font HTTP request but adds font size × 1.33 to your stylesheet. Only embed fonts that are very small (under 20 KB after encoding).

Yes. Drop any file into the encoder to get its Base64 output. Prepend the appropriate data:[mediatype];base64, prefix to create the complete data URI. All processing stays in your browser , no upload required.

Additional resources

Guides

Embedding Images as Data URIs in HTML and CSS Learn how to embed images, SVGs, and fonts as Base64 data URIs in HTML attributes and CSS. Includes format, size limits, and when to avoid inlining. Building HTTP Basic Auth Headers with Base64 HTTP Basic Authentication encodes username:password in Base64 for the Authorization header. Learn the format, curl usage, and why HTTPS is required. How JWT Tokens Use Base64url Encoding JWT tokens encode header and payload as Base64url without padding. Learn the structure, how to decode the claims, and why JWTs are not encrypted by default. Base64 in Kubernetes Secrets Kubernetes Secrets store values as Base64-encoded strings in YAML. Learn how to encode, decode, and manage secrets , and why Base64 is not encryption. MIME Email Attachments and Base64 Encoding SMTP email encodes attachments as Base64 in MIME multipart messages. Learn the format, line length rules, charset headers, and common email encoding bugs. Storing Binary Secrets in Environment Variables Environment variables only hold text strings, but Base64 encoding lets you store binary secrets like TLS keys and certificates as env var values. Learn the pattern and risks. Embedding Binary Data in JSON APIs JSON cannot represent raw binary data. Base64 encoding is the standard way to embed images, files, and binary fields in JSON API requests and responses. URL-Safe Base64 vs Standard Base64 URL-safe Base64 replaces + with - and / with _ so strings are safe in URLs, HTTP headers, and filenames. Learn when to use each variant and how to convert between them. SSH Keys and PEM Certificates in Base64 SSH keys, TLS certificates, and PEM files wrap raw binary keys in Base64 between header and footer markers. Learn the format, how to decode keys, and common CI/CD patterns.