Skip to main content
Loading time...

Data URIs in CSS: Complete Guide to Inline Images and Icons

How to embed images directly in your stylesheets using the data URI scheme.

What Is a Data URI?

A data URI (Uniform Resource Identifier) is a scheme that allows you to embed small files directly into documents as a string of text. Instead of referencing an external file with a URL like url(images/icon.png), you embed the file content inline:url(data:image/png;base64,iVBORw0KGgo...). The browser decodes the Base64 string and renders the image without making an additional HTTP request.

The data URI scheme was defined in RFC 2397 in 1998 and has been supported by all major browsers for over a decade. It works in CSS property values wherever a URL is accepted:background-image, border-image, list-style-image,cursor, and content.

Data URI Syntax

A data URI follows this structure:

data:[<mediatype>][;base64],<data>

/* Examples */
data:image/png;base64,iVBORw0KGgoAAAANSUhEU...
data:image/svg+xml;base64,PHN2ZyB4bWxucz0i...
data:image/svg+xml,%3Csvg xmlns='...'%3E...  /* URL-encoded SVG */

The mediatype specifies the MIME type of the data. For images, this is typically image/png, image/jpeg, image/gif,image/svg+xml, or image/webp. The ;base64 flag indicates that the data is Base64-encoded. If omitted, the data is assumed to be URL-encoded text.

Using Data URIs for Background Images

The most common CSS use case for data URIs is background images. Small repeating patterns, gradient overlays, and decorative elements are ideal candidates because they are typically under a few kilobytes and are needed on first render.

.pattern-dots {
  background-image: url(data:image/svg+xml;base64,PHN2Zy...);
  background-size: 20px 20px;
  background-repeat: repeat;
}

.icon-checkmark::before {
  content: url(data:image/svg+xml;base64,PHN2Zy...);
  display: inline-block;
  width: 16px;
  height: 16px;
}

This approach ensures the pattern or icon renders on first paint without waiting for an additional HTTP request. The browser parses the CSS, decodes the Base64 data, and renders the image as part of the initial layout calculation.

SVG Data URIs: The URL-Encoded Alternative

SVG images have a unique advantage: because SVG is XML text, you can embed them in CSS without Base64 encoding by URL-encoding the SVG source. This avoids the 33% size overhead of Base64 and produces more readable (if still verbose) CSS:

/* URL-encoded SVG (no Base64 overhead) */
.icon {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5 13l4 4L19 7' stroke='%230d9488' fill='none' stroke-width='2'/%3E%3C/svg%3E");
}

/* Base64-encoded SVG (33% larger, but simpler escaping) */
.icon-b64 {
  background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0...);
}

URL-encoded SVGs are smaller and allow you to use CSS custom properties for colors by referencing variables within the SVG markup. However, the URL-encoding syntax is harder to read and debug. Base64 is simpler to generate and paste. Choose based on your workflow and whether you need dynamic color theming.

Custom Cursors with Data URIs

CSS custom cursors accept data URIs, allowing you to embed cursor images without external files. This is useful for web-based design tools, drawing applications, and games:

.canvas-draw {
  cursor: url(data:image/png;base64,iVBORw0KGgo...) 2 2, crosshair;
}

.canvas-erase {
  cursor: url(data:image/svg+xml;base64,PHN2Zy...) 8 8, default;
}

The numbers after the data URI specify the cursor hotspot coordinates. Cursor images should be very small (16x16 to 32x32 pixels) to ensure smooth rendering. Most browsers support PNG and SVG cursors; some older browsers only support CUR format.

Build Tool Integration

Modern build tools can automatically inline small images as data URIs during the build process. This gives you the best of both worlds: you write normal CSS with file references during development, and the build tool converts small images to data URIs for production.

Webpack uses url-loader or the built-in asset module with a size limit. Images below the limit are inlined as data URIs; larger images are emitted as files.Vite does this automatically with a default 4 KB threshold configurable viabuild.assetsInlineLimit.PostCSS has plugins like postcss-url that can inline images matching specific patterns.

Performance Considerations

Data URIs in CSS have specific performance characteristics that differ from data URIs in HTML:

  • CSS is render-blocking. A large CSS file with many data URIs delays first paint because the browser must download and parse the entire stylesheet before rendering. Keep critical CSS lean.
  • No independent caching. Data URIs embedded in CSS are cached with the stylesheet. If the CSS changes for any reason, all embedded images must be re-downloaded. Separate image files can be cached independently with long TTLs.
  • Duplicated bytes. If the same image appears in multiple CSS rules, the Base64 string is duplicated. CSS custom properties or a shared class can mitigate this, but the encoded data is still in the file once.
  • Parse time. Very large CSS files with many data URIs increase CSS parse time. The browser must process the entire Base64 string even if the rule is not applied to any visible element.

Browser Support and Limits

Data URIs are supported by all modern browsers. The maximum size limit varies: Internet Explorer had a 32 KB limit (now irrelevant), but modern browsers support data URIs well into the megabytes. However, as discussed above, using data URIs for large assets defeats their purpose.

One gotcha: some older email clients and webmail providers strip or block data URIs in inline styles. If you are generating CSS for HTML emails, test thoroughly across clients.

Try It Yourself

Use our Image to Base64 converter to generate CSS-ready data URIs. Select the "CSS" output format for a ready-to-pastebackground-image declaration. For encoding non-image data, try our Base64 Encoder. For URL encoding SVGs, our URL Encoder can help.

Further Reading