Data URIs: The Complete Guide
How to embed images, fonts, and files directly in HTML and CSS using Base64-encoded data URIs.
What is a Data URI?
A data URI (also called a data URL) is a URI scheme defined in RFC 2397 that allows you to embed small files directly within HTML, CSS, or JavaScript as a text string, rather than linking to an external resource. Instead of the browser making a separate HTTP request to fetch an image, font, or other asset, the file content is encoded directly in the document itself, typically using Base64 encoding.
Data URIs have been supported by all major browsers since Internet Explorer 8 (2009), and they remain a valuable tool in the modern web developer's toolkit for specific use cases where eliminating network requests improves performance or simplifies deployment.
The Data URI Format
Every data URI follows a specific syntax:
data:[<mediatype>][;base64],<data>Let us break down each component:
data:- The URI scheme identifier. This tells the browser that what follows is inline data, not a URL to fetch.[<mediatype>]- An optional MIME type that describes the data format. If omitted, it defaults totext/plain;charset=US-ASCII. Common types includeimage/png,image/svg+xml,application/font-woff2, andtext/css.[;base64]- An optional indicator that the data is Base64-encoded. Without this, the data is assumed to be percent-encoded text.<data>- The actual content, either Base64-encoded binary data or percent-encoded text.
Examples
<!-- A tiny 1x1 red pixel PNG -->
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==" alt="Red pixel" />
<!-- An inline SVG icon -->
<img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2L2 22h20L12 2z'/%3E%3C/svg%3E" alt="Triangle icon" />
<!-- Plain text (no base64 needed) -->
<a href="data:text/plain,Hello%20World">Download text</a>
<!-- CSS with embedded background image -->
.icon {
background-image: url(data:image/png;base64,iVBORw0KGgo...);
}Using Data URIs in HTML
Data URIs can appear anywhere a regular URL is expected in HTML. The most common uses are in <img> tags and as href values.
Inline Images
The most common use of data URIs is embedding small images directly in HTML. This is particularly useful for icons, logos, and decorative elements that would otherwise require separate HTTP requests:
<!-- Inline a small PNG icon -->
<img
src="data:image/png;base64,iVBORw0KGgoAAAANSUh..."
alt="Settings icon"
width="24"
height="24"
/>
<!-- Inline an SVG (can use percent-encoding instead of base64) -->
<img
src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3C/svg%3E"
alt="Circle icon"
/>Favicons
Data URIs work excellently for favicons, eliminating the extra request for /favicon.ico:
<link
rel="icon"
href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Ctext y='.9em' font-size='90'%3E🔧%3C/text%3E%3C/svg%3E"
/>This technique is popular in development environments and single-page applications where you want to avoid an extra network request for a small asset.
Using Data URIs in CSS
CSS is where data URIs truly shine. Embedding small images in stylesheets means the assets load with the CSS file itself, with no additional requests needed:
Background Images
/* Small background pattern */
.pattern {
background-image: url(data:image/svg+xml,%3Csvg width='20' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='2' cy='2' r='1' fill='%23ccc'/%3E%3C/svg%3E);
background-repeat: repeat;
}
/* Custom checkbox icon */
.checkbox:checked::after {
content: '';
display: block;
width: 16px;
height: 16px;
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgdmlld0JveD0iMCAwIDE2IDE2Ij48cGF0aCBkPSJNNS44IDEwLjZMMy4yIDhsLTEgMSAzLjYgMy42IDcuNi03LjYtMS0xLTYuNiA2LjZ6IiBmaWxsPSJ3aGl0ZSIvPjwvc3ZnPg==);
}
/* Loading spinner */
.spinner {
background-image: url(data:image/svg+xml;base64,...);
animation: spin 1s linear infinite;
}Custom Fonts
While less common due to the size of font files, embedding small icon fonts or subsetted fonts in CSS can reduce loading time in specific scenarios:
@font-face {
font-family: 'Icons';
src: url(data:font/woff2;base64,d09GMgABAAAAA...) format('woff2');
font-weight: normal;
font-style: normal;
}Performance Tradeoffs
Data URIs involve a fundamental tradeoff: you eliminate HTTP requests at the cost of increased document size and reduced cacheability. Understanding this tradeoff is essential for making informed decisions.
Advantages
- Fewer HTTP requests: Each data URI eliminates one network round-trip. For pages with many small assets, this can significantly reduce total load time, especially on high-latency connections (mobile networks, distant servers).
- Atomic loading: The asset loads with its containing document. There is no flash of unstyled content (FOUC) or layout shift while waiting for an image to download.
- Simplified deployment: Everything is contained in a single file. No broken image links, no missing assets, no CORS issues.
- Offline compatibility: Since the data is inline, it works without any network access once the containing document is loaded.
Disadvantages
- 33% size increase: Base64 encoding adds approximately 33% overhead. A 3 KB image becomes approximately 4 KB of Base64 text.
- No separate caching: External files can be cached independently by the browser. A data URI in your CSS means the encoded data is downloaded every time the CSS file is re-fetched. If the image rarely changes but the CSS changes frequently, you lose the caching benefit.
- Increased parse time: The browser must parse and decode the Base64 string, which adds CPU overhead compared to loading a binary file directly.
- Blocks rendering: Data URIs in CSS block rendering because the browser must parse the entire stylesheet before rendering. Large data URIs can delay the first paint.
- Cannot be lazy-loaded: Unlike external images that can use
loading="lazy", data URIs are decoded immediately when the HTML or CSS is parsed. - Harder to maintain: Base64 strings are opaque and unreadable. Updating an image means regenerating the entire data URI. Version control diffs become meaningless for binary assets.
Size Comparison: When Data URIs Pay Off
The breakeven point depends on your specific circumstances, but general guidelines based on HTTP/2 multiplexing and typical network conditions suggest:
Data URI Decision Matrix
| Original File Size | Base64 Size | Recommendation |
|---|---|---|
| < 1 KB | < 1.37 KB | Use data URI - the HTTP request overhead exceeds the size increase |
| 1-5 KB | 1.37-6.85 KB | Consider data URI - good for critical-path assets above the fold |
| 5-10 KB | 6.85-13.7 KB | Use cautiously - only if reducing requests is critical |
| > 10 KB | > 13.7 KB | Use external file - the size overhead negates request savings |
Note: With HTTP/2 and HTTP/3 multiplexing, the cost of additional requests is lower than with HTTP/1.1. These guidelines are approximate and should be validated with your specific performance metrics.
SVG Data URIs: A Special Case
SVG images deserve special attention because they are already text-based. Unlike PNG or JPEG images, SVGs do not need to be Base64-encoded to be used in data URIs. You can use percent-encoding instead, which is more efficient:
<!-- Base64-encoded SVG (works but inefficient) -->
<img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48Y2lyY2xlIGN4PSIxMiIgY3k9IjEyIiByPSIxMCIgZmlsbD0icmVkIi8+PC9zdmc+" alt="" />
<!-- Percent-encoded SVG (more efficient, smaller) -->
<img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='10' fill='red'/%3E%3C/svg%3E" alt="" />The percent-encoded version is typically 10-20% smaller than the Base64 version because SVG source code is already text. You only need to encode a few special characters: < becomes %3C, > becomes %3E, and # becomes %23. Single quotes work without encoding, which further reduces size.
Generating Data URIs
There are several ways to create data URIs depending on your workflow:
Using Our Tool
The quickest way to generate a data URI is with our Base64 Encoder/Decoder. Switch to the File tab, drop or select a file, and the tool generates the complete data URI string with the correct MIME type, ready to paste into your HTML or CSS.
Using Command Line
# macOS / Linux
echo "data:image/png;base64,$(base64 < icon.png)" > data-uri.txt
# Or using openssl
echo "data:image/png;base64,$(openssl base64 -in icon.png | tr -d '\n')"
# Node.js one-liner
node -e "console.log('data:image/png;base64,' + require('fs').readFileSync('icon.png').toString('base64'))"
# Python
python3 -c "import base64; print('data:image/png;base64,' + base64.b64encode(open('icon.png','rb').read()).decode())"Using Build Tools
Most modern build tools can automatically inline small assets as data URIs:
// Vite (vite.config.ts) - inline assets under 4 KB by default
export default defineConfig({
build: {
assetsInlineLimit: 4096, // bytes
},
});
// Webpack (module rule)
{
test: /\.(png|jpg|gif|svg)$/i,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 4 * 1024, // 4 KB
},
},
}
// PostCSS (postcss-url plugin)
// Automatically inlines url() references in CSS
postcssUrl({
url: 'inline',
maxSize: 5, // KB
})Security Considerations
Data URIs have important security implications that developers should be aware of:
- Content Security Policy (CSP): If your site uses a Content Security Policy, data URIs must be explicitly allowed. The
data:source must be included in the relevant CSP directive (e.g.,img-src data:,font-src data:). Be cautious withscript-src data:as it can enable XSS attacks. - XSS vectors: Data URIs containing
text/htmlorapplication/javascriptcan be used as XSS vectors. Never allow user-supplied data URIs in security-sensitive contexts. Many browsers have mitigated this by preventing navigation todata:URIs in the top-level browsing context. - Obfuscation: Malicious content can be hidden in Base64-encoded data URIs to evade content scanners. Always validate and sanitize user-provided data URIs.
Browser Support and Limitations
Data URIs are universally supported in modern browsers, but there are practical limits:
- Size limits: While there is no hard limit in the specification, browsers impose practical limits. Chrome handles data URIs up to approximately 2 MB, while other browsers may have lower limits. Internet Explorer 8 had a 32 KB limit, though this is no longer relevant for modern development.
- MIME type support: Most image types (PNG, JPEG, GIF, SVG, WebP), font types (WOFF, WOFF2), and text types (CSS, HTML, plain) are supported. Audio and video data URIs work but are impractical due to size.
- Top-level navigation: Modern browsers (Chrome 60+, Firefox 59+) block navigation to
data:URIs in the top-level browsing context as a security measure. Data URIs still work for resource embedding (img,link, etc.).
Best Practices Summary
Based on everything covered in this guide, here are the recommended best practices for using data URIs effectively:
- Inline assets under 4 KB. The HTTP request overhead typically justifies the 33% size increase for files smaller than 4 KB.
- Use percent-encoded SVGs instead of Base64-encoded SVGs. SVGs are already text and do not benefit from Base64 encoding. Percent-encoding produces smaller output.
- Automate with build tools. Let Vite, Webpack, or PostCSS handle data URI generation based on file size thresholds. Manual data URIs are error-prone and hard to maintain.
- Prioritize critical-path assets. Use data URIs for above-the-fold images, loading spinners, and essential icons that must appear immediately.
- Measure the impact. Always test performance with and without data URIs using Lighthouse or WebPageTest. The optimal strategy depends on your specific page structure and user base.
- Consider caching implications. If an asset changes rarely but its containing document changes frequently, an external file with proper cache headers may be more efficient.
- Update your CSP. If you adopt data URIs, ensure your Content Security Policy allows them in the appropriate directives.
Generate Data URIs with DevPane
Ready to create data URIs for your project? Our Base64 Encoder/Decoder makes it simple. Switch to the File tab, select or drag your file, and get a complete data URI with the correct MIME type. The tool processes everything in your browser, so your files never leave your machine.
Further Reading
- RFC 2397 — The "data" URL scheme
The IETF specification defining data: URI syntax and usage.
- MDN Data URLs
Practical guide to data URLs with examples and browser support details.
- Can I Use — Data URIs
Browser compatibility table for data URI support across platforms.