Fun with hot dogs!

Check this out:

If you're using any modern browser (that rules out IE6 and IE7), you should
see a picture of a hot dog above.

But no such image file exists on my server—or on any other server. You're looking at a PNG image, but there's no PNG file anywhere.

How is that possible?

Right-click on the hot dog and view the image properties—in particular, note the image's src. You'll see a URI that begins with data:, followed by a very long string of gibberish.

That gibberish is the image data. Ordinary URIs simply point to data stored somewhere else. But URIs that begin with data: contain the data itself, represented as ASCII text. Instead of downloading an image file from somewhere on the Internet, the browser interprets the URI itself as an image file.

data: URIs can be used to embed any kind of data—images, HTML, JavaScript, PDF files, MP3s, anything—and you can use them wherever you'd ordinarily use a standard http: URI.

You can even use them in CSS files—and that's really the meat of this post. I'm going to show you how to embed image data in a stylesheet. It's actually quite simple.

This page contains the following inline style rule:

p.polka {
	background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9YGARc5KB0XV+IAAAAddEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q72QlbgAAAF1JREFUGNO9zL0NglAAxPEfdLTs4BZM4DIO4C7OwQg2JoQ9LE1exdlYvBBeZ7jqch9//q1uH4TLzw4d6+ErXMMcXuHWxId3KOETnnXXV6MJpcq2MLaI97CER3N0vr4MkhoXe0rZigAAAABJRU5ErkJggg==");
}

And here's a paragraph with the class polka:

Hi! I'm polka-dotted!

Why would you want to do this? The main advantage is speed. Ordinarily, the browser must download the stylesheet, parse it, and download each image separately. Even if the total payloads are the same, multiple HTTP requests are much slower than a single transfer. Embedding the image data in the stylesheet allows the browser to download everything in a single package.

This is the same motivation behind CSS spriting, which allows the browser to download a single image instead of many. The method illustrated here simply takes that principle to a logical (and arguably ridiculous) extreme, by eliminating the need for any additional downloads.

There are, naturally, a few limitations:

  • data: URIs aren't supported in Internet Explorer 6 or 7. This renders them impractical for real-world use—unless you're working on an intranet, and can be sure that all users have a supporting browser.

  • Internet Explorer 8 supports data:, but limits URIs to 32KB in length, and disallows most content types except for images and CSS (for security reasons).

  • There's also maintenance to consider: new and updated images will have to be re-encoded and pasted into the stylesheet, and the next person who works on your site might look at your code and have no idea what to do with it.

  • If you use the same images in multiple style rules, you'll end up with duplicate image data—which will increase load times. In this case, you're better off using regular URIs, pointing to real image files.

  • This technique forces the browser to download all images on the first page view, rather than as they're needed. This could be a bug or a feature, depending on the type of site you're building.

So—at least until IE6 and IE7 go away—use of this method is limited to experimental projects and parlor tricks.

You can encode your own data: URIs with Ian Hickson's data: URI kitchen.

Comments

No comments yet.

Leave a Reply

(will not be published)
(optional)

What My Clients Say

Travis has helped us with many web development projects, and has proven himself to be very talented, professional, consistent, reliable, and thorough.

—Derrick Miller
Axis 80 Interactive