Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serving high res images to retina display

how to detect, in a cross-browser compatible way, the pixel density of the device visiting a webpage so that one can either serve standard or highres images without forcing doubled images to any device?

Is there any javascript library that automates this?

like image 359
pistacchio Avatar asked Nov 17 '12 13:11

pistacchio


2 Answers

Why setting for Retina

iPhone 4s, iPhone 5, iPad3, iPad4, Macbook 15", Macbook 13" all use Retina display.

Android also support high resolution display, as well as Windows 8(Lumia 920) as mentioned by @JamWaffles.

Adding high resolution support is good for user experience but it definitely add load for developer, as well as bandwidth for mobile. Somebody don't suggest doing that.(Peter-Paul Koch, see the bottom "further reading")

Breifing

There are two methods to implement this function. One is Javascript and the other is CSS. All current solutions are for Retina, but could extend to Android high resolution easily.

CSS solution is about Media Query and -webkit-min-device-pixel-ratio or -webkit-device-pixel-ratio

  • Simple to use.
  • Apply to all browsers.
  • Disadvantage: Good for background. Harder for <img> tag

Javascript solution is about window.devicePixelRatio property.

  • Advantage: Javascript could manipulate image source. So, if you are going to serve direct image instead of background, better to use Javascript
  • Could not apply to all browsers but current support is good enough. See below for list.
  • Need a bit more setting.

CSS Solution

For normal images, say an icon

.sample-icon {
    background-image: url("../images/sample-icon.png");
    background-size: 36px 36px;
}

For Retina, add those below

@media only screen and (-webkit-min-device-pixel-ratio: 2), /* Webkit */
    (min-resolution: 192dpi) /* Everyone else */ {
    .sample-icon {
        background-image: url("../images/sample-icon-highres.png");
        background-size: 18px 18px;
}

You can use min-resolution: 2dppx to replace min-resolution: 192dpi, for those who don't want to remember numbers

Note the difference:

  1. Two different icons, one normal, one high res. High res icon is double size than normal one.
  2. The background size. The later is half. But you need test it in your real use.

Resource: + http://www.w3.org/blog/CSS/2012/06/14/unprefix-webkit-device-pixel-ratio/ + http://view.jquerymobile.com/master/demos/widgets/buttons/#CustomIcons

Javascript Solution

Use window.devicePixelRatio property to detect resolution.

if (window.devicePixelRatio >= 2) {
  alert("This is a Retina screen");
  //Do something to manipulate image url attribute
  //for example add `@2x-` before all image urls
}
Browser Support

Safari, Android WebKit, Chrome 22+ and on Android, Opera Mobile, BlackBerry WebKit, QQ, Palm WebKit, Ref: http://www.quirksmode.org/blog/archives/2012/06/devicepixelrati.html

For Android

Android device use 1.5 as high resolution instead of 2 in Retina. http://developer.android.com/guide/webapps/targeting.html --#Targeting Device Density with CSS, #Targeting Device Density with JavaScript

Further Good Reading

http://www.quirksmode.org/blog/archives/2012/07/more_about_devi.html "I’m not a big fan of serving special retina images because it makes the web too heavy — especially over a mobile connection. Nonetheless people will do it." -- Peter-Paul Koch

Update 2013-04-18 Update jQuery mobile link

like image 133
Billy Chan Avatar answered Oct 27 '22 13:10

Billy Chan


I found this:

var retina = window.devicePixelRatio > 1;

this should make retina return true, which you could use an if function to serve the right images.

Source: http://briancray.com/posts/detect-retina-displays-with-javascript

-InfiniDaZa

like image 25
InfiniDaZa Avatar answered Oct 27 '22 15:10

InfiniDaZa