Is Embedding Background Image Data into CSS as Base64 Good or Bad Practice

Is embedding background image data into CSS as Base64 good or bad practice?

It's not a good idea when you want your images and style information to be cached separately. Also if you encode a large image or a significant number of images in to your css file it will take the browser longer to download the file leaving your site without any of the style information until the download completes. For small images that you don't intend on changing often if ever it is a fine solution.

as far as generating the base64 encoding:

  • (upload)
  • (from link with little tutorials underneath)

Should I embed images as data/base64 in CSS or HTML

Is this a good practice? Are there some reasons to avoid this?

It's a good practice usually only for very small CSS images that are going to be used together (like CSS sprites) when IE compatibility doesn't matter, and saving the request is more important than cacheability.

It has a number of notable downsides:

  • Doesn't work at all in IE6 and 7.

  • Works for resources only up to 32k in size in IE8. This is the limit that applies after base64 encoding. In other words, no longer than 32768 characters.

  • It saves a request, but bloats the HTML page instead! And makes images uncacheable. They get loaded every time the containing page or style sheet get loaded.

  • Base64 encoding bloats image sizes by 33%.

  • If served in a gzipped resource, data: images are almost certainly going to be a terrible strain on the server's resources! Images are traditionally very CPU intensive to compress, with very little reduction in size.

Advantages and disadvantages of using base64 encoded images

It's only useful for very tiny images. Base64 encoded files are larger than the original. The advantage lies in not having to open another connection and make a HTTP request to the server for the image. This benefit is lost very quickly so there's only an advantage for large numbers of very tiny individual images.

Why base64Encode images in CSS?

its a Data Uri Scheme and as far as I know, the only advantage is to save HTTP requests (as everything is loaded as one, rather than fetching images).

Why its on the google chrome landing page....well, google does like to show off and use the latest tech on everything.

Normal image Vs base 64 image

I would only base 64 encode small reusable elements like a simple icon but not a portrait of a person. Something that is 60KB is too large imho. You might save on requests by base 64 encoding your images into your CSS file but after a handful of 60KB images your CSS file is going to get heavy and that's without any actual CSS. Before long you might find yourself with a few MB CSS file and the browser would have to wait for the whole thing to download and then parse before it started rendering the page with your CSS.

For example, a recent project I worked on had a video with a placeholder/poster image with a play button icon over the placeholder/poster image of the video (much like on ESPN's website. The icon was just under 1KB when base 64 encoded along with being used numerous time on the site so it made sense in that instance to bake it into the CSS file.

Browsers today look ahead when parsing an HTML document for images so they can begin requesting and receiving images while the browser waits for other resources like CSS and JS files. Once downloaded, if properly configured on the server with a TTL, your images will be cached for future use and the page will be rendered even faster as the browser will use the images from its cache instead of requesting a copy from the server where your website is hosted.

Base 64 encoding fonts into a CSS file can weigh it down quickly also.

While you might be reducing the number of requests to the server for images, you will be increasing the time it takes to receive another. Test a few things out and see what gives you the best performance. Which is faster? One large file that includes "everything" or multiple yet fast requests?

Is there a way to set background-image as a base64 encoded image?

I tried to do the same as you, but apparently the backgroundImage doesn't work with encoded data. As an alternative, I suggest to use CSS classes and the change between those classes.

If you are generating the data "on the fly" you can load the CSS files dynamically.

function change() {
if (document.getElementById("test").className == "backgroundA") {
document.getElementById("test").className = "backgroundB";
document.getElementById("test2").className = "backgroundA";
} else {
document.getElementById("test").className = "backgroundA";
document.getElementById("test2").className = "backgroundB";

btn.onclick = change;
.backgroundA {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAIAAACRXR/mAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RDUxRjY0ODgyQTkxMTFFMjk0RkU5NjI5MEVDQTI2QzUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6RDUxRjY0ODkyQTkxMTFFMjk0RkU5NjI5MEVDQTI2QzUiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpENTFGNjQ4NjJBOTExMUUyOTRGRTk2MjkwRUNBMjZDNSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpENTFGNjQ4NzJBOTExMUUyOTRGRTk2MjkwRUNBMjZDNSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PuT868wAAABESURBVHja7M4xEQAwDAOxuPw5uwi6ZeigB/CntJ2lkmytznwZFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYW1qsrwABYuwNkimqm3gAAAABJRU5ErkJggg==");

.backgroundB {
background-image: url("data:image/gif;base64,R0lGODlhUAAPAKIAAAsLav///88PD9WqsYmApmZmZtZfYmdakyH5BAQUAP8ALAAAAABQAA8AAAPbWLrc/jDKSVe4OOvNu/9gqARDSRBHegyGMahqO4R0bQcjIQ8E4BMCQc930JluyGRmdAAcdiigMLVrApTYWy5FKM1IQe+Mp+L4rphz+qIOBAUYeCY4p2tGrJZeH9y79mZsawFoaIRxF3JyiYxuHiMGb5KTkpFvZj4ZbYeCiXaOiKBwnxh4fnt9e3ktgZyHhrChinONs3cFAShFF2JhvCZlG5uchYNun5eedRxMAF15XEFRXgZWWdciuM8GCmdSQ84lLQfY5R14wDB5Lyon4ubwS7jx9NcV9/j5+g4JADs=");
<div id="test" height="20px" class="backgroundA">
div test 1
<div id="test2" name="test2" height="20px" class="backgroundB">
div test2
<input type="button" id="btn" />

Related Topics

Leave a reply