Should I Embed Images as Data/Base64 in CSS or Html

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.

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:

  • http://b64.io/
  • http://www.motobit.com/util/base64-decoder-encoder.asp (upload)
  • http://www.greywyvern.com/code/php/binary2base64 (from link with little tutorials underneath)

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?

Embedding Base64 Images

Update: 2017-01-10

Data URIs are now supported by all major browsers. IE supports embedding images since version 8 as well.

http://caniuse.com/#feat=datauri


Data URIs are now supported by the following web browsers:

  • Gecko-based, such as Firefox, SeaMonkey, XeroBank, Camino, Fennec and K-Meleon
  • Konqueror, via KDE's KIO slaves input/output system
  • Opera (including devices such as the Nintendo DSi or Wii)
  • WebKit-based, such as Safari (including on iOS), Android's browser, Epiphany and Midori (WebKit is a derivative of Konqueror's KHTML engine, but Mac OS X does not share the KIO architecture so the implementations are different), as well as Webkit/Chromium-based, such as Chrome
  • Trident

    • Internet Explorer 8: Microsoft has limited its support to certain "non-navigable" content for security reasons, including concerns that JavaScript embedded in a data URI may not be interpretable by script filters such as those used by web-based email clients. Data URIs must be smaller than 32 KiB in Version 8[3].
    • Data URIs are supported only for the following elements and/or attributes[4]:

      • object (images only)
      • img
      • input type=image
      • link
    • CSS declarations that accept a URL, such as background-image, background, list-style-type, list-style and similar.
    • Internet Explorer 9: Internet Explorer 9 does not have 32KiB limitation and allowed in broader elements.
    • TheWorld Browser: An IE shell browser which has a built-in support for Data URI scheme

http://en.wikipedia.org/wiki/Data_URI_scheme#Web_browser_support

Do modern browsers support base64 encoded JS or CSS chunks in HTML like they do for images?

Yes, browsers support DATA URLs (which can be base 64) in place of actual files.

<link rel="stylesheet" href="data:text/css;charset=utf-8;base64,Ym9keXtiYWNrZ3JvdW5kOmJsYWNrO2NvbG9yOndoaXRlO30="></link>
<script src="data:application/javascript;charset=utf-8;base64,d2luZG93LmFsZXJ0KCJ0aGlzIGlzIGV4ZWN1dGVkIGZybSBiYXNlNjQiKTs="></script>
<p>This text is styled white from the data-uri loaded css</p>

What is the effect of encoding an image in base64?

It will be approximately 37% larger:

Very roughly, the final size of Base64-encoded binary data is equal to 1.37 times the original data size

Source: http://en.wikipedia.org/wiki/Base64

cant use base64 image from css in img tag

The main problem is that you haven't provided a width and height for the image. HTML elements never resize themselves to fit the size of the background image, so you'll have to do that yourself.

And you have markup errors in the source: first of all, an img MUST have a src attribute. And img elements don't have end tags. So it's best to use another element, perhaps a div or a span with the proper styling.

#t {    width:100px; height:77px;    display:inline-block;    background-image: url("data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAyADIAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wgARCABNAGQDASIAAhEBAxEB/8QAGQABAQADAQAAAAAAAAAAAAAAAAcDBAUB/8QAFQEBAQAAAAAAAAAAAAAAAAAAAAH/2gAMAwEAAhADEAAAAaoAAAAAAAAAAA526ZAAJxR+cRVXkshV4SFXhDdGteHFq+PbsAAAAAAAAAAAAAAA/8QAIBAAAQQCAgMBAAAAAAAAAAAABAACAwUVFgZQEBITIP/aAAgBAQABBQLryzYA1HIyVn45RZlAk7DZLYbJbDZLYbJbDZLYbJHWRRzRiZhn13JSvaCT6xeCQhinYivWIr1iK9YivWIr1iK9XVC2doXFh40MNCM3tv/EABQRAQAAAAAAAAAAAAAAAAAAAFD/2gAIAQMBAT8BD//EABQRAQAAAAAAAAAAAAAAAAAAAFD/2gAIAQIBAT8BD//EACsQAAEDAAcGBwAAAAAAAAAAAAEAAgMEERIzNJGSFCEiMVBiBRAgQUJRcv/aAAgBAQAGPwLp7NpksB5qBKtRua9p92mv0wto0lkObWeEFX40BX40BX40BX40BX40BX40BNbSZLQbvHCArVHlfGe0oRzQbR+BU5B5jfHX8X8/MOpELJCNwrWEiyWEiyWEiyWEiyWEiyWEiyULfD4YozXxO5IGlSOlP0NwVmjxMjHaOr//xAAjEAACAQMDBAMAAAAAAAAAAAABEQAhwfBRcYEQIDFQYaGx/9oACAEBAAE/IfXmlDAQp2gh45KDz2hzHQGofyJndpndpndpndpndpndoN0bQQPAnDoR76w16mjccCh+oY0AeAAN+oxJsFod8IQhCDgK1kSmAz/X8nDwR76+3//aAAwDAQACAAMAAAAQ888888888884888CCCaF888888888888888//8QAGBEAAwEBAAAAAAAAAAAAAAAAAAERMED/2gAIAQMBAT8Q2RUVFRVw/wD/xAAUEQEAAAAAAAAAAAAAAAAAAABQ/9oACAECAQE/EA//xAAhEAEBAAAFBQEBAAAAAAAAAAABEQAhMWFxIFBRgZEQQf/aAAgBAQABPxDt9pNIGAUUH+tWGMwaBHCDHppP6gBlqTLr169evXrfX0aAR0LjyQhUbBoNm4P5kyt1B4A5Yrc167hQ+/udySdSw99d73ve4iurRSllXO6DiQ/zflKN8jwx5LQCty1W7e7/AP/Z"); }
<div id="t"></div>


Related Topics



Leave a reply



Submit