Why images appear blurry on mobile devices

mobile-web

You may have noticed when browsing the web on your new smartphone or other such small screen, that despite its otherwise gorgeous screen, images on websites often appear blurry. And there is a very simple reason why, which I hope to explain, as well as discuss some possible solutions.

DPI for dummies

DPI, or Dots-per-Inch, is a measurement for print quality, with the more dots printed in each square inch increasing the quality of the image produced. When looking at screens, DPI usually means pixels-per-inch, but the “more is better” paradigm still applies, and I will use the two interchangeably.

To give you an idea of the values involved, here are the specifications for some devices you may have seen hipsters using on the train:

Device Screen size Screen Resolution Pixels-Per-Inch
HTC Pyramid 4.3″ 960×540px 256
Samsung Galaxy S2 4.37″ 800×480px 218.501
iPhone 4 3.5″ 960×640px 326
iPad 2 9.7″ 1024×768px 132
Motorola Xoom 10.1″ 1280×800px 160

Clearly the pixel-densities of the devices are as varied as the devices themselves, but generally the higher the screen resolution, the lower the PPI. Now compare the above to the following common computer displays:

Screen size Screen Resolution Pixels-Per-Inch
15.4″ 1280×800px 95
17″ 1280×1024px 96.42
21″ 1600×1200px 95
23″ 1920×1080px 96

The reason they're so much smaller? Simple, you use your monitor from further away than your phone. Likewise, a 40′ HDTV only has a PPI of 55.07, whereas my 17′ laptop has 129.58.

Compensating for something

Since mobile devices have a much higher PPI, under normal conditions text and images scaled for desktop would be too small to see clearly. To illustrate this, on a 96PPI display 16px text would appear about 2.6/16ths of an inch tall. On a 265PPI display, the same text would appear 1/16th of an inch tall. Clearly, this is too small to read comfortably.

The solution? Mobile browsers compensate by zooming in on the page. The end result is still smaller than on your monitor, but again, your monitor is probably further away, so it’s all relative.

The problem? Now your nice crisp image have been zoomed in too, which causes them to appear blurry.

Delivering clear images for unclear DPI's

1. The SVG Method

SVG, or Scalable Vector Graphics, is as the name suggests, a vector image format. This means that instead of telling you where each pixel is like a raster image, the image is closer to a set of instructions to draw it. This means an SVG or other vector can be redrawn at any size without losing quality, whilst a raster can only be resized by degrading the quality.

SVG can be used as a background image or images in Safari and Opera, but unfortunately do not work in the Android browser or Windows Phone 7. Apparently Honeycomb will bring this functionality to 'droid, and the next version of WP7 will include IE9 instead of IE7, which has great support for SVG.

SVG also does not render crisply in Opera Mobile. I could be wrong, but I assume this is because of the browsers zoom value — so it renders the page, crisp SVG and all, then zooms in on it, making the image blurry once more.

You can use jQuery to test for SVG support with the following, then script a replacement accordingly, but your raster images will still be blurry.

function supportsSVG() {
    	return !!document.createElementNS && !!document.createElementNS('http://www.w3.org/2000/svg', "svg").createSVGRect;
}

Google activates 350,000 Android devices each day. Therefore a solution that does not work in Android is not a solution.

2. The double-size image method

An alternative to vectors is simply providing a higher-resolution image to match the higher-resolution of the device, then scaling it down. So you serve a larger picture, tell it to be smaller, the phone is smaller, so tells the page to be larger, and everything sort of balances out.

The default zoom multiplier for most high-DPI phones is between 1.5 and 1.6, so making your images double the size should easily be enough to keep them crisp.

On images themselves you can do this easily with the height and width properties. So for example, if you wanted a 32px image, save it as 64px and set height and width to 32.

<img src="example.png" height="64" width="64" alt="Example of image height and width" />

On your screen you mightn't see any difference from a 32px image, but on your device the extra pixels will sneak in when the browser zooms the page, and your image is sharp again. The only downside from this technique is that there is no way to deliver a smaller image on low-DPI displays without scripting.

But what about backgrounds?

Of course, this would be too good to be true, so the kicker comes with sizing background images. Whilst CSS3 introduces the background-size property, it doesn't work on Opera Mini or IE.

.example {
	background: url('example.png') no-repeat top left;
	background-size: 32px 32px;
	-webkit-background-size: 32px 32px;
}

IE has an easy workaround — because it doesn't support multiple backgrounds either, you can serve a low and high-quality image separately with the following snippet:

.example { background-image: url('example.png'); background-image: none, url('example-hq.png'); }

Unfortunately, Opera Mini does support multiple backgrounds, but not background sizing, so will deliver your image at its original double-size.

Using @media queries

You probably also want to use media-queries to only serve the high-res image to high-DPI devices, and not every user. For the sake of inconvenience, both Webkit and Opera support only their own vendor prefixes and format (ratio vs fraction), so you'll have to define this twice.

@media screen and (-webkit-min-device-pixel-ratio: 1.5) { background-image {[...}}
@media screen and (-o-min-device-pixel-ratio: 3/2) { background-image {[...}}

An easier method might be combining your high-DPI styles into separate stylesheet, then use an @import to attach this to the page. You will create an extra network request, but will save yourself doubling up on your styles.

@media screen and (-webkit-min-device-pixel-ratio: 1.5) { @import url('high-dpi.css');
@media screen and (-o-min-device-pixel-ratio: 3/2) { @import url('high-dpi.css');

Not a perfect world

So far, both techniques involve providing additional assets, and neither works across the field. SVG can still appear blurred in Opera Mobile, and won't appear in Webkit or Windows Phone, and background-size doesn't work in Mini or Windows Phone.

Furthermore, any media queries have to be defined twice to work in both Opera and Webkit browsers, so having created two images, you must declare them twice as well!

Summary

So what have we learnt and where does this leave us?

  1. Images can be upsized and scaled back by setting a height and width
  2. You can use SVG if you’re comfortable scripting a fallback for Android and WP7
  3. You can use background-size if Opera Mini isn’t a concern
  4. Media Queries are a must to save bandwidth

Today, there are a plethora of articles about designing for the iPhone, and some even have the courtesy of mentioning Android. Opera is worldwide the most popular mobile browser and runs on any phone. Unfortunately, at present there is no infallible method I know of to deliver high-quality images to all three, and Windows Phone really throws a spanner in the works when it comes to standards support. For the time being, the best option is probably to go with media-queries and background-sizing, and settle with the fact that, whilst popular, Opera Mini is not a default browser, so if a page does display incorrectly, more users will be able to simply try again in another browser, as long as your content is engaging enough to have spurred their interest in spite of any presentational glitches.

Which leads me to my final point; on high-DPI devices, content is still king. A mobile device is still no comparison to desktop browsing, and mobile connections are no match for land-line ADSL, so only use images where you have to

Android Safari Opera Mobile Opera Mini WP7
SVG No Yes Yes, blurry Yes No
background-size Yes Yes Yes No No

One Response

    • matt sambellMatthew Sambell
      on the 8th of September, 2011 9:54 am

    Such a nice read Chris well done. In time you’ll find developers landing on this as they begin to get serious about their mobile interfaces. It was not easy task getting our mobile interface looking crisp. The amount of research you did really paid off. Thanks for a great read and looking forward to more advanced facts from you.

    WD GG WP

    Reply to this comment

Leave a Reply