Sunday, August 12, 2012

Scale Background Image only with CSS

Have you ever wondered how to scale background image directly in browser?

A day ago I had to do optimization of an application for a client. At some point I found that major lag was caused when PHP code checks whether product image exists or not. Here's example how it was done:

$file_headers = @get_headers($d->picture);
if($file_headers[0] == 'HTTP/1.1 404 Not Found' || $file_headers[0] == 'HTTP/1.1 403 Forbidden' || $file_headers[0] == 'HTTP/1.1 301 Moved Permanently') {
    // show no-image IMG
}
else {
    //  echo $d->picture;
}


For every image there was a HTTP call to check whether the image is there or not. This works fine but is rather slow and also loads the server in a silly way.

After a little bit of a thinking over the problem I came with an elegant solution.
What I did is I made two HTML elements one over the other. The first one holds the "no-image" image and the second one placed above the first one with a higher z-index hold the actual product image BUT (the catch is here) image is set as a background-image CSS.
This way when the product image is missing user will see "no-image" and we do not need functionality to check whether product image exists or not.

So our server is unloaded from this silly task. :)

Here's an example code:


.no-image {
background-position: middle center;
position: absolute;
width: 195px;
height: 150px;
}
a.product-image {
background-position: middle center;
background-repeat: no-repeat;
position: absolute;
width: 195px; height: 150px;
display: block;
-moz-background-size: cover;
background-size: cover;
}
<div class="no-image" style="background-image: url('/upload/no-image.jpg');"></div>
<a href="'.$d->item_link.'" target="_blank" class="product-image" style="background: #000 url('<?php echo $d->pictures; ?>'); filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='<?php echo $d->pictures; ?>', sizingMethod='scale'); -ms-filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='<?php echo $d->pictures; ?>', sizingMethod='scale');"></a>


But I needed scale product image right in the browser. You might have already noticed the code that makes this trick:
CSS3 for Firefox, Safari and all WebKit browsers:

-moz-background-size: cover;
background-size: cover;

and code for IE6/7/8:
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='pictures; ?>', sizingMethod='scale');
-ms-filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='pictures; ?>', sizingMethod='scale');

That's it!
Enjoy your great optimization.