Retina and high-res displays are a challenge when
you want to do them correctly - but we discovered a very simple solution
to this about 2 years ago, and I never got around to blogging about it.
So please apologize that I've been keeping this secret from you. It
will make your work much better with minimum effort.
Why care? What is this about?
Basically most tiny devices
(Apple, Android, Windows-Phones and tablets) have high-resolution displays. This means they behave like they have a
"normal" resolution (like 320px on an iPhone 4S held vertically) but in
reality have more pixels than that (640 on the iPhone 4S). This is great
for text because the fonts are smoother, but pictures can't benefit
from this unless the server also sends more pixels as well.
So we want the normal screens to work with this (42k):
While we want the high-res screens to work with the larger one like this (113k):
…but of course displayed like this - I'll frame all high-res images here in magenta (113k):
So our Goal is…
- To have images appear great normal screens
- …and on high-resolution screens like a modern mobile device
- …while optimizing for file-size (shouldn't be too heavy)
- …and still showing the proper image when the screen changes (device rotation without re-load!)
- …all this with minimal work for the designer/developer
- …and the content-editor should not have to do anything special (because that would usually fail)
Retina on Samsung, Nokia and all other devices
I've
heard people think that this is an Apple-only phenomenon. This is not
the case - all modern mobile devices and tablets have high-resolution
displays, as well as some notebooks and desktops. They usually use
different terms. There are even higher multipliers - so apple usually
uses factor 2 - but other devices have 2.7, 3 or any other arbitrary
number.
Let's solve this!
The 3 common Strategies for Retina and High-Resolution Displays
If you do some research you'll quickly find various ways to solve this. Here just a short run-down
- Server-Side Adaptive strategies, where the server detects what device is visiting, and either…
- …changes the HTML to load a different picture
- …keeps the same HTML but sends a different picture from the same image-URL
- Client-Side strategies to request a different URL
- …based
on new tags in HTML5, where the page contains many different URLs for
different scenarios and the browser picks the one it believes fits
- …based
on JavaScript, also using different URLs which the script will then try
to request the correct one based on screen size or something similar
- One-Size fits all strategies, where the same picture is used on all devices
Best Solution: Keep it simple!
We'd reviewed all options
extensively two years ago and decided to go with option 3 - "One Size
fits all" because of it's elegance and simplicity. The other strategies
work as well, but are much harder to implement, need more tweaking and
break rather more easily (for example if the device rotates or if you
have to support older browsers as well). The other solutions also cause
trouble with SEO / Google-Image-Search and have further side-effects when your
layout gets more complicated or you have animations.
The secret behind One-Size-Fits-All
I'm
just giving you the short version, if you doubt anything I write please
read the blog of Daan of Netvlies as they created many
experiments to test this solution.
The System: Just deliver the largest image to every device, by default 2x wider/higher then the largest size in the mobile device.
This
may sound bonkers at first, because everybody automatically assumes
that the larger image is also heavier (has more kb) than the smaller
image. But…
The secret: Because the image is larger, you can use a higher compression to get the same quality! So instead of a 90% JPG you can use 70% or sometimes as little as 50%.
Just
make sure that the image you're sending is perfect for the largest
to-be-expected use-case, either the largest
retina-size-multiplied-by-two or the largest desktop size. Because most devices held sideways have similar resolutions as a small desktop, the the
retina resolution will be larger.
The High-Res Image can be as Light as the Low-Res image!
This
is really amazing and it's mostly thanks to the magic of modern
compression algorithms. And believe me - this works well on logos,
photos and more. So with the image above, I'll just add a &quality=60 and now it's only 55k instead of 113k!
Original 42k with ?w=500
|
High-Res 55k instead of 113k with ?w=1000&quality=60
|
|
|
For the normal viewer, the quality is comparable or better on a desktop, and it's much better on a high-res display :)
Here are some sites that successfully implement this
strategy 1, 2. Go ahead and resize the browser, look at the
logos, the content images etc.
Implementing this on your web site content
Basically
you need an automatic image-resizer-and-cropping-tool + a
content-layout-tool. All this is packaged in 2sxc (download from the forge or codeplex). With 2sxc
you'll simply create content-templates like "image on the left" which
contains a URL for the image, automatically cropping and resizing it
exactly as you need it. So a typical content template will retrieve the
image like this:
<img style="width: 100px; height: 100px" src="[Content:Image]?w=200&h=200&quality=70&format=jpg" />
Note that the real size is usually not inline, because the real size will often change in a responsive design.
As you can see, this solution is super-easy to implement, the content-editor doesn't need to understand it at all!
You
can find an example of this in the Employee-Directory App (download here) or in many of the responsive web sites we (2sic) created during
the last 2 years.
Note on Disadvantages to this strategy
This strategy works for just about everything including CSS-Sprites. But there are two known cases which are not perfect:
- PNG
images don't compress as well as JPG, so the compression factor won't
help much. This means the resulting file will be larger. In most cases
you can mitigate this:
- If you have a
PNG because it's a logo and you thought it's a better quality - think
again. Don't take my word for it - try to create a JPG twice as large
with comparable file size and you'll probably discover that it's
perfect.
- If you know that transparency won't be an
issue (like in a gallery), then you should auto-convert to JPG. This is
a always a good idea, because PNGs are heavier. When you use 2sxc just
add the parameter format=jpg and you're good to go
- Old
Internet-Explorers have a lousy image-rendering if the displayed image
is not a 1:1 or 2:1 match of the pixels. You'll note this if your image
is 300px wide and you're showing it at 230px or another non-multiple. So
if you're targeting stone-age systems, do a few tests to see if the
result is acceptable. We usually believe that stone-age-users don't
expect the crispest visuals in the first place, so we find this problem
acceptable.
PNG Standard (6.4k)
|
PNG High-Res (12.9k)
|
JPG Standard &format=jpg (6.1k)
|
JPG High-Res &quality=70 (8.4k)
|
|
|
|
|
How much work is this?
On
simple sites the web designer usually needs 1-2 hours to implement
this. On standard-sites we usually charge 4h work extra, on complex sites with animations etc. it can be 1-2 days extra work. There may also be some extra
Photoshop work to prepare the images in the larger version, because the
screen-design may not have prepared the visuals in the correct size.
For the content-editor: he should not feel a thing. We always tell them to "just
upload it much larger than you need" and the system takes care of
everything automatically because all our content uses professional templates and runs the images through the resizer.
With love from Switzerland,
Daniel
Daniel Mettler grew up in the jungles of Indonesia and is founder and CEO of 2sic internet solutions in
Switzerland and Liechtenstein, an 20-head web specialist with over 600
DNN projects since 1999. He is also chief architect of 2sxc (2SexyContent - see forge), an open source module for creating attractive content and DNN Apps.