Making a retina/high resolution image toggle for websites
Here is the pickle. It’s one you may find yourself in:
- We want to provide high resolution inline images to users of retina/HD displays where possible.
- Just because users can see retina/HD images, doesn’t mean they want to (massive bandwidth hit if they are on a cellular connection).
- We therefore need to provide users with an option to view retina/HD images but it should be ‘opt in’.
- Once selected, their preference should be ‘remembered’ around the site until they ‘opt out’.
So, I decided to try something out on this site. If you view the site on an iPhone 4S/new iPad (or another HD device if reading this in the future), you’ll see this in the menu bar:
Select the tick box and you should get high resolution versions of images (where they exist). Try it out here: http://benfrain.com/playground At present, I’ve added high resolution versions of the main images on my home page too.
To achieve this effect I’ve done a few things. First off, the HTML:
Want retina/HD images? better quality images but longer page loads.
It’s a simple input box (the stuff before is merely styling/preference related) which I’ve hidden with CSS by default:
#container #banner nav ul li#hdToggle { width: 95%; display: none; }
Then, I’ve chosen to show the toggle only to users with a retina display using the following media query:
@media all and (-webkit-min-device-pixel-ratio : 1.5) { #container #banner nav ul li#hdToggle { display: block; } }
With some jQuery, alongside the jQuery cookie plugin it’s then possible to use cookies to remember a users preference and run the jQuery Retina display plugin as needed.
Warning, I’m no jQuery master – I’m sure there is a much more succinct way of writing this and feel free to point it out and I will amend to suit! However, this is working at present:
$(document).ready(function(){ // create a cookie $.cookie('hdCookie', { expires: 365, path: '/' }); // this bit changes the cookie dependant upon whether box is selected or not $('#hdToggle').bind('change', function () { if ($('#hdToggle input').is(':checked')) { $.cookie('hdCookie', 'hdYes', { expires: 365, path: '/' }); $('#container #main img.hd').retina('@2x'); } else if ($('#hdToggle input').not(':checked')) { $.cookie('hdCookie', 'hdNo', { expires: 365, path: '/' }); } }); // here is a variable, that I'm setting to be the value of the cookie var hdCookie = $.cookie('hdCookie'); // then do something based on value of cookie if (hdCookie == 'hdYes') { // if the cookie is set to 'hdYes' I want it to select the box (so it shows ticked) $('#hdToggle input').prop("checked", true); // select and act on any relevant images. $('#container #main img').retina('@2x'); // if it isn't selected do nothing. } });
Now, if I want to provide a high resolution version of an image for future posts, I can simple make two versions: a standard size one (e.g. image.png) and a high resolution one, typically double the size (e.g. [email protected]). If a user has opted to see high-resolution images, they get the good stuff, if not, they get the fast stuff!
There’s no need to change anything else markup wise, as the jQuery retina display plugin searches, finds and loads the high resolution versions if they exist.
Ben, Thank you for sharing the interesting articles. I’m in an endless debate with the web developer who is creating a new site for me, which I am planning to have as 16:10 aspect ratio, with each image to take up full screen, but not to be stretched. I am authoring my own professional images and cropping them to look widescreen. Do you think one is better off to have say, 2560 wide and around 250KB, or say, around 1700 wide at around 300KB. Both are set at the correct aspect ratio in these examples. Which do you believe would look like a sharper image, all things being equal?