Question

I've been trying to find a good approach to solve a very commmon problem in the retina era.

Lets say the following is given:

  • Create a website with responsive images
  • No CSS background images
  • Websites basic functionality must be working without JS
  • The websites images must be optimized for retina displays.

An easy way to solve this could be something like this: 

<img src="img.jpg" data-highres="img@2x.jpg" />

and write some kind of js to swap out img.jpg with img@2x.jpg if retina device is detected. This would work, but if I enter the website on a retina device both img.jpg and img@2x.jpg would be loaded. Not very bandwidth friendly :(

Is it possible somehow to intercept and change the src of the image before the original src is loaded?

Or do any of you have another approach in solving the problem?

Was it helpful?

Solution

In the future, you might be able to use the picture element. In the meantime, the only approach I've seen that might work is to:

  1. Put a div or span where you want the image. Style it to have the dimensions and layout of the image. Add some kind of identifying mark to it so you can find it (e.g. class="retina-image")
  2. Store information about the different sizes of images you have on or in the element (e.g. using data-something attributes)
  3. Put a <noscript><img src="..." alt="..."></script> inside the div
  4. On DOM ready:
    1. use JS to find all the elements with the identifier from step 1
    2. detect the type of image you want
    3. find the attribute that tells you what URL to use for that image
    4. add the image to the DOM inside the container from step 1

This is the approach used by the picturefill library.

OTHER TIPS

This will probably be flame-bait, but here's my two cents:

The concern over bandwidth is largely a mobile platforming issue. Considering that most modern mobile platforms now adopt high pixel density displays, the demand for high res images from these devices is going to be pretty high. Why serve 3 times the image resolution 90% of the time (a low res and high res image) when you can server 2 times the resolution 100% of the time?

Hence, in some scenarios, it may be easier to just serve up the higher resolution images (halving their width/height styles) and leave it at that - thereby saving (expensive) time and energy elsewhere. In an industry where everything seems to be a compromise, this sometimes makes the most sense as an approach.

I think Quentin essentially answered your question.

What I can add is that while having an img element without a src it technically not per spec, omitting it won't break your code and you'll avoid pre-loading. Then you can just have <img data-src="" data-src2=""> and swap images in/out using JavaScript. The <noscript> element is probably the "correct" way of doing this but it makes code really verbose and I've heard some browsers will pre-load <noscript> images as well.

One service I've come across which makes images responsive (including Retina displays) is Pixtulate. They also provide the JavaScript to correctly size and replace your img.src url before the page has finished loading. Should be pretty simple to drop in.

If you do something with window.devicePixelRatio and loop through images that have data-highres attribute.

This is quite rough, but you get my drift.

 $(document).ready(function() {
     if (window.devicePixelRatio > 1) {
         // retina
     } else {
         // default
     }
 });

Use a blank/clear 1px gif

<img src="clear.gif" data-basesrc="img1" />

Then use basesrc atttribute and append the appropriate filename in your JS.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top