Base64 encoded images in HTML
Image data can be directly inserted into a HTML document using data URIs. This allows an entire HTML document to be loaded in a single request while referencing fewer external assets. The basic format is as follows:
data:[<mime type>][;charset=<charset>][;base64],<encoded data>
Base64 is just one format for a data URI. ASCII is another (UTF-8). Data URI's are supported in IE 8 and above. Data URIs are not limited to images. Any common mime-type is fine. Also, the size of the embedded uri is larger than size of resource by itself. On a mobile connection, using data URIs can be 6x lower than loading the static resource separately. For these reasons, it makes the most sense to use data URIs where total load speed is crucial or the page is cached (long expire time) and never changes.
In the right application, data URIs offer a huge advantage of static images, which are pulled from various resources across the network and sometimes other (insecure) domains. Each time another connection is made with a server, there is the overhead associated with the request-response transaction. While the overhead is typically around 12ms per asset, loading many assets can really take its toll. For small images and icons, this approach doesn't make a lot of sense, and for a while developers would rely on a sprite assets for smaller graphics.
Sprites: an option to reduce external resource quantity
A sprite asset is a single image with a transparent background that contains many image assets. Calling the single image reduces the number of external resource transactions - reducing the overall page load time. Developers had to make sure that the pixes of the sprite resource was maximized, but when content varied in size and shape, filling in all the empty spaces could become challenging.
Developers would also create individual css classes to position the background of the element such that only a portion of the sprite asset would be shown. This would create certain problems for browsers that handled the box-sizing differently - but fortunately this was fixed by using box-sizing: border-box;. The following is an example of the CSS used with the sprite technique.
<div class="base64EncodedImage spriteDemo"></div>
<div class="base64EncodedImage spriteDemo2"></div>
<!-- Scroll down in this example to see the base64EncodedImage class which contains the image information -->
<style>
/* create the left carrot */
.spriteDemo {
height: 30px;
width: 19px;
display: inline-block;
box-sizing: border-box;
background-position: -16px, -0px;
}
/* create the right carrot */
.spriteDemo2 {
height: 30px;
width: 35px;
display: inline-block;
box-sizing: border-box;
background-position: -50px, -0px;
}
</style>
The above sprite code has two objects created from the same sprite asset. In this example, one object is the open carrot and the other object is the close carrot. The results of the sprite code results in the following:
While this example works well, both these objects are relatively small. The padding of the individual object images as well as the negative tessellate space could be saved by simply including the image data inline as base 64 URIs.
Base 64 URIs as an img src
Using the URI format above, an entire image can be base 64 encoded and presented using its uri as the image source. A sample code is shown below:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA...
The above code will generate the following image. A user can still right click and save the content - just like any normal image. The mime-type will even be preserved.
This approach is not favorable when the image is repeated.
Base 64 URI in a css background-image
In the case of a repeated image, use of css (similar to the implementation of sprite objects) can be applied. This ensures the base64 content only appears once within the document payload.
The following code is an example of implementing the same base 64 encoded image in css.
<div class="base64EncodedImage"></div>
<div class="base64EncodedImage"></div>
<div class="base64EncodedImage"></div>
<style>
.base64EncodedImage {
height: 71px;
width: 104px;
display: inline-block;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA...
}
</style>
The above code will display the image three times, but as the background of a div element. The results of this example are shown below: