Data URI’s – Using and Generating

A recent project of mine needed an image embedding into some HTML via JavaScript. Rather than use a separate image, I decided to embed it directly using a data URI.

An image in a data URI is the MIME type of the image and it’s content encoded with base64 into a string. This is great as it cuts down HTTP requests but does cause the initial page weight to increase and be difficult to update as each change means the image needs re-encoding. Modern browsers support data URI’s very well, but older browsers such as IE 7 and below won’t like it.

Examples Using A Data URI Encoded Image

HTML Example

Here’s how I can embed the image of a red cross into an HTML <img> tag.

<img src="data:image/gif;base64,R0lGODlhFAAUAJEAAP/9/fYQEPytrflWViH5BAAAAAAALAAAAAAUABQAQAJKhI+pGe09lnhBnEETfodatVHNh1BR+ZzH9LAOCYrVYpiAfWWJOxrC/5MASbyZT4d6AUIBlUYGoR1FsAXUuTN5YhxAEYbrpKRkQwEAOw==" alt="red cross" width="20" height="20" />

CSS Example

Here’s how I can embed the image of a red cross into background of an HTML element using CSS.

body { 
  background: url(data:image/gif;base64,R0lGODlhFAAUAJEAAP/9/fYQEPytrflWViH5BAAAAAAALAAAAAAUABQAQAJKhI+pGe09lnhBnEETfodatVHNh1BR+ZzH9LAOCYrVYpiAfWWJOxrC/5MASbyZT4d6AUIBlUYGoR1FsAXUuTN5YhxAEYbrpKRkQwEAOw==) no-repeat left center;
}

JavaScript Example

Here’s how I can add an image element with the red cross in to an HTML page using JavaScript.

var imagestring = "data:image/gif;base64,R0lGODlhFAAUAJEAAP/9/fYQEPytrflWViH5BAAAAAAALAAAAAAUABQAQAJKhI+pGe09lnhBnEETfodatVHNh1BR+ZzH9LAOCYrVYpiAfWWJOxrC/5MASbyZT4d6AUIBlUYGoR1FsAXUuTN5YhxAEYbrpKRkQwEAOw==";
var image = new Image();
image.src = imagestring;
image.onload = function() {
  document.body.appendChild(image);  
}

Encoding An Image To A Data URI

It’s easy to create the encoded image string using PHP as it comes with a Base64 encoder as part of the language. Automatically detecting the MIME type of an image is a bit harder, but we can use finfo_file with comes as an extension to PHP 5.3 and above to do this.

So assuming the filename of the image is in the variable $filename we can use the following code to get the mimetype, read the image and encode it to a data URI string.

$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimetype = finfo_file($finfo, $filename);
finfo_close($finfo);

$contents = file_get_contents($filename);
echo "data:" . $mimetype . ";base64," . base64_encode($contents);

Conclusion

We’ve seen it’s easy to embed encoded images into code. I have wrapped the encoding routine into a command line PHP script and placed it on GitHub as php-base64-encode so it’s easy to quickly generate data URI’s.

Centering A Header Image In jQuery Mobile

I needed to replace the header text in a jQuery Mobile application with an image.

I first tried wrapping the image in the <h1> tag, but that adds quite a large margin and cuts off some of my image.

The solution I used was to instead add a wrapper div that centers everything in it. My header ended up looking like this…

Header

center-wrapper is a custom style defined like this…

.center-wrapper {
  text-align: center;
}
.center-wrapper * {
  margin: 0 auto;
}

There may be a better way to do this, but this works for now.

Using CSS3 On Internet Explorer With PIE

Until a few hours ago some parts of this website used boring old images as buttons, however I’ve now started to bring this website into 2011 and swap them out for something far cooler and semantically better. These are now links styled up with CSS3.

The buttons had rounded corners and a drop shadow, easy to create using tools like Adobe’s Photoshop, but a pain to do before CSS3. With CSS3, we can use the following to add the curved border and drop shadow.

-webkit-border-radius: 8px;
-moz-border-radius: 8px;
border-radius: 8px;
-webkit-box-shadow: rgba(0,0,0, .5) 3px 3px 6px;
-moz-box-shadow: rgba(0,0,0, .5) 3px 3px 6px;
box-shadow: rgba(0,0,0, .5) 3px 3px 6px;

OK, we’ve had to use a few custom extensions for Mozilla and Webkit based browsers, but it works. However, as always, Microsoft’s Internet Explorer doesn’t want to play nicely and isn’t able to support these features. There are a few work arounds, but at present the best seems to be PIE – Progressive Internet Explorer.

PIE makes Internet Explorer 6-8 capable of rendering several of the most useful CSS3 decoration features. At present it has full or partial support for border-radius, box-shadow, border-image, multiple background images and linear gradient background images.

It’s easy to add PIE as an HTML Component (HTC), you just need to reference it in your CSS.

behaviour: url(PIE.htc);

As if by magic, those CSS3 features will start working in Internet Explorer.

You will need to download PIE and host it somewhere. You will also need to make sure that your web server is setup to serve HTC files with the content-type header of “text/x-component”. If you use Apache, you can use the following line in your config, or in a .htaccess file.

AddType text/x-component .htc