Dealing with high resolution displays on mobile websites

Mobile devices currently have increasingly higher resolution displays. For example: you have the iPhone retina screens and there are several Android devices with HD and even full HD screens. Since websites usually are created for desktops (with a much smaller amount of pixels per inch), the device pixel ratio was invented. For example: the iPhone 4+ has a device pixel ratio of 2, which means when you specify something to have a width of 200 pixels, it will actually be rendered 400 pixels wide.

However, this also applies to images. With the same retina based iPhone, if you specify an image to be 200 pixels wide, it will actually be rendered 400 pixels wide. This way, your high resolution display isn’t producing any sharper images. Let’s find out a way to fix this:

Option 1: always use higher resolution images

The first option is the simplest one: simply always use a higher resolution image. For example: specify the width and height of the image to 200 pixels, but actually point to an image with a width and height of 400 pixels. As mobile phones usually scale images pretty well, this will also look good on mobile phones without a high resolution display. The downside is obvious though: users without a high resolution display will download a high resolution image they don’t need. Because mobile internet connections often aren’t very fast, this could be an undesirable situation. However, this is a valid option when you are using images with a very low file size (like icons). Also, if the current trend continues, high resolution screens will become the standard which removes the need to make exceptions for low resolution devices.

Option 2: media queries

You can use media queries in order to use different CSS depending on how high resolution your screen is and select the correct image there:
@media (-webkit-min-device-pixel-ratio: 2),(min-resolution: 2dppx)
{
    .testDiv{
        background-image: url("highres.jpg") !important;
        background-size: 100%;
    }
}
@media (-webkit-min-device-pixel-ratio: 1.5),(min-resolution: 1.5dppx)
{
    .testDiv{
        background-image: url("midres.jpg") !important;
        background-size: 100%;
    }
}
.testDiv{
    background-image: url("lowres.jpg");
}
I have tested this with several iPhones and 2 different browsers on an android device. By looking at the access logs, I found out that in all cases only one image was loaded. Therefore I think it is safe to assume that (at least in most cases), only the correct image will be loaded.

Option 3: JavaScript

We could use JavaScript to detect the device pixel ratio by using window.devicePixelRatio and display the correct image accordingly:
<img id="myImage" width="240" height="207" style="display:none" />
<script type="text/javascript">
if(window.devicePixelRatio >= 2)
{
    document.getElementById("myImage").setAttribute("src","highres.jpg");
    document.getElementById("myImage").style.display="inline";
}
else if(window.devicePixelRatio >= 1.5)
{
    document.getElementById("myImage").setAttribute("src","midres.jpg");
    document.getElementById("myImage").style.display="inline";
}
else
{
    document.getElementById("myImage").setAttribute("src","lowres.jpg");
    document.getElementById("myImage").style.display="inline";
}
</script>

<noscript>
    <img src="lowres.jpg" width="240" height="207"/>
</noscript>

Option 4: SVG

SVG was meant to solve any resolution problems as an SVG image can scale to any resolution:
<img src="mysvg.svg" width="150" height="100" />

Unfortunately, while SVG is supported on iOS since day one, it the default browser of android only supports embedding SVG images at Android 3.0 and higher. Also, Internet Explorer 8 and lower doesn’t support SVG as well. In order to support these browsers, we need to provide a fallback which displays a PNG when the browser doesn’t support SVG:

<object data="mysvg.svg" type="image/svg+xml" width="80" height="29">
<img src="lowres.jpg" width="80" height="29" />
</ object>
This has just one problem: if you use a link around your image, the link won’t work with many SVG browsers. A way to use a fallback around this, is to add the following code to your SVG file.
<svg onclick="window.parent.location='/myLinkLocation';"

This works, but you have to be really careful update the URL in the SVG when you are updating the link around it. Combined with the fact that SVG is only usable for vector graphics makes SVG not a viable solution in a lot of cases.

In conclusion

All the solutions described above are valid solutions and you need to decide which one(s) is/are right for you. Please note, that in the examples above, I don’t test for a device pixel ratio higher than 2. This is because a device pixel ratio of 2 means you have the dpi of a retina iPhone, and I don’t believe providing higher resolution images will result in noticeable better looking images, while it does increases the file size. However, which device pixel ratio’s you support is entirely up to you.
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s