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.

ZERO UPLOAD · ALL LOCAL
  1. Select DECODE (default) to paste Base64 and get the original text, or switch to ENCODE to convert text to Base64.
  2. For text: type or paste into the text area — the result appears instantly.
  3. For files: drop a file onto the drop zone or click it to browse — any file up to 500 MB works.
  4. Use Copy to grab the output, or Download as .txt to save long Base64 strings.
  5. Note: Base64 is encoding, not encryption. Anyone can decode it with no key.

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.

INPUT
FILE INPUT

Drop a file here

or click to select a file · any format · max 500 MB

OUTPUT

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.

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