Optimizing CSS background images using WebP

0.00 avg. rating (0% score) - 0 votes

In continuation to our first article on WebPOptimizing web pages using WebP”, we have extended our approach to display WebP images with the help of CSS background. As we earlier stated that Naukrigulf.com is one of the first few sites on the web to use WebP images format to serve banners. Now we are serving our background images in WebP format as well.

In this approach we have two solutions to call background WebP images.
– Using CSS Parent-Child Relationship
– Using @ queries.

CSS Parent-Child Relationship
– In this approach we have to check user’s browser and assign a class in the or tag to implement the WebP format image. So here is our dependency on the server side – The server detects the browser type (if chrome) and on the basis of that we put the class in or tag.

 

HTML
   <body class="chrome">
      <header class="backgroundImage"></header>
   </body>
CSS
   .backgroundImage{background-image:url(naukrigulf.gif)}
   .chrome .backgroundImage{background-image:url(naukrigulf.webp)}

 

Here we have to specify the class attribute for the or tag. The drawback is the dependency over the Server Side Language.

@ queries
In this approach we are handling in CSS only. With the help of @media or other support queries in CSS, we have achieved the functioning at frontend only.

How we achieved this?
We were reading about CSS hacks over the net. We found a good article of Paul Irish about “Browser CSS Hacks” and another one of CSS Hack at “http://browserhacks.com/”. Here we found

    /* saf3+, chrome1+ */
    @media screen and (-webkit-min-device-pixel-ratio:0) {
        #diez { color: red  }
    }

In the above media query, we wrote the CSS for Safari 3+ and Chrome 1+ but since the target has to be chrome, we had to again search and after doing so we found the way around

 

    @supports (-webkit-appearance:none) {}

 

This @supports query works in chrome >=28 and opera >=14.

In the above queries, one thing is common that both of them work for chrome >=28 browser and Chrome supports WebP format from versions 43 and above. The current version of Chrome is 46. We are supporting the latest version of chrome because Chrome is usually auto upgraded. So we are trying to merge these @ queries.

 

    @media screen and (-webkit-min-device-pixel-ratio:0) {
         @supports (-webkit-appearance:none) {
              .backgroundImage{background-image:url(naukrigulf.webp)}
         }              
    }

 

After this (written above), we were able to support WebP images into CSS without requiring any server side detection for background images. This has helped in improving our Front-End technology and provides a boost in improving the page performance.

4 thoughts on “Optimizing CSS background images using WebP

  1. Nice tip but it didn’t work with the most recent Edge version
    On IE it works, on Edge it tries to load the webp picture (blank image).

  2. For now the only alternative for CSS background it’s to use modernizer JS library. It’s lightweight (~1KB) so you can save a lot of bandwidth with this method.

    CODE to detect webP and inline SVG:

    /*! modernizr 3.3.1 (Custom Build) | MIT *
    * http://modernizr.com/download/?-inlinesvg-webp-setclasses !*/
    !function(e,n,A){function t(e,n){return typeof e===n}function o(){var e,n,A,o,a,i,s;for(var f in l)if(l.hasOwnProperty(f)){if(e=[],n=l[f],n.name&&(e.push(n.name.toLowerCase()),n.options&&n.options.aliases&&n.options.aliases.length))for(A=0;A<n.options.aliases.length;A++)e.push(n.options.aliases[A].toLowerCase());for(o=t(n.fn,"function")?n.fn():n.fn,a=0;a<e.length;a++)i=e[a],s=i.split("."),1===s.length?Modernizr[s[0]]=o:(!Modernizr[s[0]]||Modernizr[s[0]]instanceof Boolean||(Modernizr[s[0]]=new Boolean(Modernizr[s[0]])),Modernizr[s[0]][s[1]]=o),r.push((o?"":"no-")+s.join("-"))}}function a(e){var n=u.className,A=Modernizr._config.classPrefix||"";if(c&&(n=n.baseVal),Modernizr._config.enableJSClass){var t=new RegExp("(^|\\s)"+A+"no-js(\\s|$)");n=n.replace(t,"$1"+A+"js$2")}Modernizr._config.enableClasses&&(n+=" "+A+e.join(" "+A),c?u.className.baseVal=n:u.className=n)}function i(){return"function"!=typeof n.createElement?n.createElement(arguments[0]):c?n.createElementNS.call(n,"http://www.w3.org/2000/svg",arguments[0]):n.createElement.apply(n,arguments)}function s(e,n){if("object"==typeof e)for(var A in e)p(e,A)&&s(A,e[A]);else{e=e.toLowerCase();var t=e.split("."),o=Modernizr[t[0]];if(2==t.length&&(o=o[t[1]]),"undefined"!=typeof o)return Modernizr;n="function"==typeof n?n():n,1==t.length?Modernizr[t[0]]=n:(!Modernizr[t[0]]||Modernizr[t[0]]instanceof Boolean||(Modernizr[t[0]]=new Boolean(Modernizr[t[0]])),Modernizr[t[0]][t[1]]=n),a([(n&&0!=n?"":"no-")+t.join("-")]),Modernizr._trigger(e,n)}return Modernizr}var r=[],l=[],f={_version:"3.3.1",_config:{classPrefix:"",enableClasses:!0,enableJSClass:!0,usePrefixes:!0},_q:[],on:function(e,n){var A=this;setTimeout(function(){n(A[e])},0)},addTest:function(e,n,A){l.push({name:e,fn:n,options:A})},addAsyncTest:function(e){l.push({name:null,fn:e})}},Modernizr=function(){};Modernizr.prototype=f,Modernizr=new Modernizr;var u=n.documentElement,c="svg"===u.nodeName.toLowerCase();Modernizr.addTest("inlinesvg",function(){var e=i("div");return e.innerHTML="","http://www.w3.org/2000/svg"==("undefined"!=typeof SVGRect&&e.firstChild&&e.firstChild.namespaceURI)});var p;!function(){var e={}.hasOwnProperty;p=t(e,"undefined")||t(e.call,"undefined")?function(e,n){return n in e&&t(e.constructor.prototype[n],"undefined")}:function(n,A){return e.call(n,A)}}(),f._l={},f.on=function(e,n){this._l[e]||(this._l[e]=[]),this._l[e].push(n),Modernizr.hasOwnProperty(e)&&setTimeout(function(){Modernizr._trigger(e,Modernizr[e])},0)},f._trigger=function(e,n){if(this._l[e]){var A=this._l[e];setTimeout(function(){var e,t;for(e=0;e<A.length;e++)(t=A[e])(n)},0),delete this._l[e]}},Modernizr._q.push(function(){f.addTest=s}),Modernizr.addAsyncTest(function(){function e(e,n,A){function t(n){var t=n&&"load"===n.type?1==o.width:!1,a="webp"===e;s(e,a?new Boolean(t):t),A&&A(n)}var o=new Image;o.onerror=t,o.onload=t,o.src=n}var n=[{uri:"data:image/webp;base64,UklGRiQAAABXRUJQVlA4IBgAAAAwAQCdASoBAAEAAwA0JaQAA3AA/vuUAAA=",name:"webp"},{uri:"data:image/webp;base64,UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAABBxAR/Q9ERP8DAABWUDggGAAAADABAJ0BKgEAAQADADQlpAADcAD++/1QAA==",name:"webp.alpha"},{uri:"data:image/webp;base64,UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA",name:"webp.animation"},{uri:"data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAAAAAAfQ//73v/+BiOh/AAA=",name:"webp.lossless"}],A=n.shift();e(A.name,A.uri,function(A){if(A&&"load"===A.type)for(var t=0;t<n.length;t++)e(n[t].name,n[t].uri)})}),o(),a(r),delete f.addTest,delete f.addAsyncTest;for(var d=0;d<Modernizr._q.length;d++)Modernizr._q[d]();e.Modernizr=Modernizr}(window,document);

  3. if you don’t use lossless compression or alpha you can strip more the above code and save some more bytes

  4. updated css filter to solve issue in edge browser:

    @media screen and (-webkit-min-device-pixel-ratio:0) and (min-resolution:.001dpcm){
    }

Comments are closed.