Anatomy of a data URI

A data URI packs a file into the place where a URL would go: data:image/png;base64,iVBORw0KGgo…. Three parts, in order: the data: scheme, the MIME type that tells the browser how to decode the payload, and after ;base64, the file's bytes as Base64. The browser treats it like any other image source, except that no request leaves the page.

The MIME type is the part hand-built URIs get wrong: paste PNG bytes behind image/jpeg and some browsers sniff their way to a rendered image while others silently show nothing. This converter reads the type from the dropped file itself, checking the magic bytes when the browser does not report one, so the prefix always matches the payload.

How to use this converter

  1. Drop an image on the left pane. PNG, JPEG, GIF, WebP, AVIF, SVG and ICO all work. The image is previewed above the output, with its real pixel dimensions in the stats strip.
  2. Pick the output shape. The default is the bare data URI. --css wraps it in a ready-to-paste rule with a class named after your file. --html builds an <img> tag. --plain gives just the Base64 payload for APIs that add their own prefix.
  3. Copy or download. The full string, on one line, the way data URIs must be.

The HTML snippet is where this tool does something the bare-string converters skip: it writes the image's real width and height into the tag. Inline image data still arrives after layout, and a tag without dimensions makes the page jump exactly like a slow-loading file would. Those two attributes are the fix, and typing them from memory is how they end up wrong.

Inline or separate file?

Inlining trades one thing for three. You save an HTTP request; you pay 33% more bytes, you lose separate caching (the image now re-downloads with every HTML or CSS change), and you make the document itself slower to parse. Since HTTP/2 multiplexed requests onto one connection, the saved request is worth far less than it was, which moved the break-even point way down.

AssetVerdict
Icon or logo under ~2 KBInline it, the request overhead genuinely outweighs the size tax.
Small repeated decoration (dots, noise texture)Inline in CSS, it ships with the stylesheet that needs it.
Photo, hero image, anything over ~10 KBSeparate file, cached, with width/height or aspect-ratio in the markup.
Image used on many pagesSeparate file, otherwise every page carries its own copy.

One more number worth knowing: Base64 output barely compresses, so inlining a 30 KB JPEG grows your gzipped HTML by close to the full 40 KB of encoded size, not by some smaller compressed amount. The tool warns above the output when a dropped image is past sensible inlining territory.

Using the URI in CSS and HTML

The rules that decide whether the image renders are small and easy to violate. In CSS, quote the URI (url("data:…")); unquoted, characters that are legal in Base64 and SVG can terminate the token early. Keep the whole URI on one line, since a wrapped string is a broken string. In HTML, the URI goes into src like any URL, and the same one-line rule applies. If the image refuses to appear on a site with a Content-Security-Policy, look at img-src: the data: scheme has to be allowed explicitly, and on hardened sites it often is not, precisely because inline data is a classic exfiltration channel.

The SVG special case

SVG is text, and Base64-encoding text you could embed directly is pure loss. The percent-encoded form, url("data:image/svg+xml,%3Csvg …%3E"), is smaller than Base64 for typical icons, works in every current browser, and leaves the markup greppable in your stylesheet, which matters the day you want to change a fill color without re-exporting anything. Encode only the characters that break the URI (<, >, #, " and % itself) and keep double quotes around the URL so single quotes inside the SVG survive.

Base64 remains the right answer for SVG when the string has to pass through systems that mangle percent signs, some templating engines and email builders do, or when a consumer explicitly expects ;base64. Drop an SVG above and the tool encodes it, but tells you about the alternative in the note under the output.

Data URI questions

Should I embed images as Base64 data URIs in HTML or CSS?

Only small ones. A data URI saves an HTTP request, which used to matter more before HTTP/2 multiplexing, but the image itself grows by a third and can no longer be cached separately from the document. Icons and logos under roughly 2 KB are fine inline; anything bigger ships faster as a normal file. Also note that Base64-encoded images compress poorly, so the gzip size of your HTML grows by more than you might expect.

Why is my Base64 image not displaying?

Work through the usual four causes. The prefix is wrong or missing: the value must start data:image/png;base64, (with the real format in place of png), and a typo like data:image/png,base64 fails silently. The string contains line breaks, often introduced by an encoder that wraps at 76 characters; a data URI must be one unbroken line. In CSS, the URI is not quoted: url("data:…") is safe, unquoted URIs break on certain characters. Or a Content-Security-Policy blocks it; the img-src directive needs the data: scheme listed. Browsers report none of these loudly, the image just stays blank.

How do I put a Base64 image in CSS?

background-image: url("data:image/png;base64,iVBORw0KGgo…"); with the whole URI on one line and inside quotes. Set background-repeat and background-size as you would for any image. The quotes matter: an SVG data URI in particular can contain characters that end an unquoted url() token early. This tool builds the complete rule for you with the --css flag, using a class named after the image file.

How do I display a Base64 image in HTML?

<img src="data:image/jpeg;base64,/9j/4AAQ…" width="640" height="480" alt="…"> works in every browser. Keep the width and height attributes even though the image data is inline: the browser parses HTML before it decodes the image, and without dimensions the layout still jumps once the pixels arrive. That layout shift is measured by Core Web Vitals as CLS, which is why the --html flag here reads the real dimensions out of the dropped image and writes them into the tag.

Do Base64 images work in email?

Mostly no, and it is not worth fighting. Gmail strips data URIs from img src in most contexts, Outlook on Windows does not render them, and support in other clients is inconsistent enough that your logo would be invisible for a large slice of recipients. The approaches that actually work in HTML email are hosted images referenced by URL (the standard) and CID-referenced attachments (multipart/related), which every email library supports. Data URIs are a web-page technique; email rendering engines are a different world.

Should SVG be Base64-encoded or URL-encoded in CSS?

URL-encoded, in almost every case. SVG is already text, so it does not need Base64 at all: url("data:image/svg+xml,%3Csvg xmlns=…%3E…%3C/svg%3E") with <, >, # and quotes percent-encoded is valid, typically 20 to 30 percent smaller than the Base64 version, and the markup stays readable and diffable in your stylesheet. Base64 only earns its keep for SVGs when a build tool or framework mangles the percent-encoded form. This tool notes the alternative whenever you drop an SVG.

How do I convert an image to Base64 in JavaScript?

From a File or Blob, FileReader.readAsDataURL gives you the finished data URI: reader.onload = () => use(reader.result). From a URL, fetch it, take response.blob() and feed that to the same FileReader. The canvas route (drawImage plus canvas.toDataURL()) also exists but re-encodes the pixels, so the bytes differ from the original file, quality is lost for JPEG, and any EXIF data disappears; use it only when you want that re-encoding. In Node.js it is one line: fs.readFileSync("logo.png").toString("base64").

Does converting an image to Base64 reduce its size?

No, it adds a third. Base64 is a transport encoding, not compression: every 3 bytes of image data become 4 characters of output, about +33%, and the stat under this tool shows the exact figure. If the goal is a smaller image, that happens before encoding: export at the right pixel size, use a modern format (WebP or AVIF instead of PNG for photos), and run lossy compression. Encoding a well-compressed 8 KB WebP beats encoding a 40 KB PNG of the same picture, in exactly the proportion you would expect.

What image formats work in a data URI?

Every format the browser can render works, with its own MIME type: image/png, image/jpeg, image/gif, image/webp, image/avif, image/svg+xml and image/x-icon are the ones that matter. The format inside the URI faces the same support matrix as a normal file, so an AVIF data URI fails in a browser without AVIF support just as the file would; there is no fallback mechanism like the picture element inside a single URI. When the MIME type in the prefix does not match the actual bytes, some browsers sniff and render anyway while others show nothing, so it is worth getting right; this tool reads it from the file.