Thursday, April 25, 2013

CSS image sprite for high resolution retina display - iPad 3

iPad 3 has an incredible 2048 × 1536 pixels high-resolution retina display. If we serve it the same images we used for PC or even for iPad 2, all the images/icons are gonna look blurred on this high resolution iPad 3. Reason is its high resolution.

In order to make our icons look better on high resolution we have to use different background image for high resolution devices with the help of CSS Media Query. I will call the image as: image-2x.png

What is image-2x.png?
Suppose we are using 36x36 size icon for regular screen resolutions, the same icon has to be 72x72 pixels for high resolution. Twice the size of normal resolution. If we are using sprite image for our project and the size is 200x200 for regular screen with all the icons in it, the same image for high resolution devices has to be 400x400 pixles.

How to use it separately for high resolution devices?
CSS Media Query:
/*For regular screen resolutions*/
  background: url(SpriteImg.png) no-repeat left top;
/*For high resolution screens*/
@media (-webkit-device-pixel-ratio: 2){ 
        background: url(SpriteImg-2x.png) no-repeat left top;
} }

Note: The -webkit-device-pixel-ratio: 2 will change in future depending on the screen resolutions. Here pixel-ratio 2 is used for iPad 3

Ok - what is the problem?
If we use the 2x background image and background-position based on what it is in that large image, nothing will work.

The HTML container we are serving the large background image remains the same size, for instance: 36x36. How will I fit 72x72 background image in 36x36 size container? Especially with image sprite.

CSS3 background-size: property to rescue.

What does background-size do?
The background-size CSS property specifies the size of the background images.

The solution:
Consider my hi-res image for iPad 3 has 200x400 dimensions. When I am defining the background-size of this image for hi-res devices I will write it as –
background-size: 100px 200px;

Did you see what happened above? With background-size property I already squeezed the 200x400 image to 100x200. Meaning – the pixels of hi-res image are now been packed together to half size of it, which will result in displaying better quality on high resolution devices.

Also, we have to set the background-position considering the background image size 100x200 px, not 200x400 px.

This technique is a lot more confusing in the beginning. But when you know how it works, then it’s too simple.