Responsive Images for Retina Displays
When web developers speak of pixels, we are referring to CSS pixels. The default base font on a web site is 16px. When an image is loaded into a page it has a default width of so many pixels. When you use media queries you might set your breakpoint between small and medium screens at 600px. Even if you use em’s, you are basing that on the default CSS pixels reported to the browser.
When Apple released the iPhone 3 there was 320 tiny dots of light between the left and right edges of the phone. The phone screen was about 2" wide and fit nicely in your hand. When the browser asked how wide the screen was, it accurately reported 320 pixels. Life was good and everything was right in the world.
Then with the iPhone 4, Apple doubled the tiny dots of light that were displayed between the left and right side of the screen. The phone screen was still about 2" wide and still fit nicely in your hand. They use the term “retina display” to describe this new screen. Although this new display actually had 640 tiny dots of light between the left and right side of the screen, it still reported to the browser a width of 320px.
Some writers use the terms actual pixels and CSS pixels to describe these two different measurement. I find that a bit convoluted, so I am going to use the term “CSS pixels” to refer to the pixels used in our style sheets and “dots of light” to refer to the number of actual pixels between the two sides of any screen. Pixel ratio is the number of dots of light divided by the CSS pixel count. Most desktop monitors have a pixel ratio of 1 while modern phones have a pixel ratio of 2 and sometimes 3
We have the ability to deliver different images to our end uses based on the pixel density of their device. In the example below, my image is taking up 200 CSS pixels.
My desktop monitor has a pixel density of one so the 1x image at 200px wide is being shown in a 200px wide space. Everything is neat and clean!.
My iPhone 6 has a pixel density of two so the 2x image at 400px wide is being shown in a 200px wide space. Now we have doubled the width of the image but since the display has twice as many dots of light, there is a one to one ratio and the quality is great!
My iPhone 6 Plus has a pixel density of three so the 3x image at 600px wide is being shown in a 200px wide space. Now we have tripled the width of the image but since the display has three times as many dots of light, there is a one to one ratio and the quality is awesome!
Here is the code I am using.
<img src = “images/building.jpg”
srcset = “images/building-1x.jpg 1x, images/building-2x.jpg 2x,images/building-3x.jpg 3x”>
Notice above that I have a typical image tag with src=”images/building.jpg”. This is the graphic that is displayed on old browsers that do not understand srcset. Next I have src set with three different images paths followed with a pixel density designation (1x, 2x, 3x).
You can see an example of this default image below on my old iPhone 4. Because it has a pixel density of 2 it really should be showing the 2x image at 400px wide.
Now I do apologize that I am using all Apple product examples in this article but since I have a plethora of them around the office it makes sense to use them.
So is it really worth all this work to deliver a higher quality image to some phones. Here are the images and their sizes.
1X image is 14,918 bytes
2X image is 53,283 bytes
3x image is 109,818 bytes
The largest images is 7 times larger than the default image and therefore uses 7 times the data from your cell phone plan and takes 7 times longer to download.
Is this important? Perhaps we should ask the owner of the 3x phone to see if they are that we are using up their data plan so fast.