css - what exactly is device pixel ratio?


Translate

this is mentioned every article about mobile web, but nowhere I can found an explanation of what exactly does this attribute measure.
Can anyone please elaborate what does queries like this check?

@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
only screen and (min--moz-device-pixel-ratio: 1.5),
only screen and (-o-device-pixel-ratio: 3/2), 
only screen and (min-device-pixel-ratio: 1.5) {

    //high resolution images go here

}

All Answers
  • Translate

    Short answer

    The device pixel ratio is the ratio between physical pixels and logical pixels. For instance, the iPhone 4 and iPhone 4S report a device pixel ratio of 2, because the physical linear resolution is double the logical linear resolution.

    • Physical resolution: 960 x 640
    • Logical resolution: 480 x 320

    The formula is:

    linres_p/linres_l

    Where:

    linres_p is the physical linear resolution

    and:

    linres_l is the logical linear resolution

    Other devices report different device pixel ratios, including non-integer ones. For example, the Nokia Lumia 1020 reports 1.6667, the Samsumg Galaxy S4 reports 3, and the Apple iPhone 6 Plus reports 2.46 (source: dpilove). But this does not change anything in principle, as you should never design for any one specific device.

    Discussion

    The CSS "pixel" is not even defined as "one picture element on some screen", but rather as a non-linear angular measurement of 0.0213° viewing angle, which is approximately 1/96 of an inch at arm's length. Source: CSS Absolute Lengths

    This has lots of implications when it comes to web design, such as preparing high-definition image resources and carefully applying different images at different device pixel ratios. You wouldn't want to force a low-end device to download a very high resolution image, only to downscale it locally. You also don't want high-end devices to upscale low resolution images for a blurry user experience.

    If you are stuck with bitmap images, to accommodate for many different device pixel ratios, you should use CSS Media Queries to provide different sets of resources for different groups of devices. Combine this with nice tricks like background-size: cover or explicitly set the background-size to percentage values.

    Example

    #element { background-image: url('lores.png'); }
    
    @media only screen and (min-device-pixel-ratio: 2) {
        #element { background-image: url('hires.png'); }
    }
    
    @media only screen and (min-device-pixel-ratio: 3) {
        #element { background-image: url('superhires.png'); }
    }
    

    This way, each device type only loads the correct image resource. Also keep in mind that the px unit in CSS always operates on logical pixels.

    A case for vector graphics

    As more and more device types appear, it gets trickier to provide all of them with adequate bitmap resources. In CSS, media queries is currently the only way, and in HTML5, the picture element lets you use different sources for different media queries, but the support is still not 100 % since most web developers still have to support IE11 for a while more (source: caniuse).

    If you need crisp images for icons, line-art, design elements that are not photos, you need to start thinking about SVG, which scales beautifully to all resolutions.


  • Translate

    Device Pixel Ratio == CSS Pixel Ratio

    In the world of web development, the device pixel ratio (also called CSS Pixel Ratio) is what determines how a device's screen resolution is interpreted by the CSS.

    A browser's CSS calculates a device's logical (or interpreted) resolution by the formula:

    formula

    For example:

    Apple iPhone 6s

    • Actual Resolution: 750 x 1334
    • CSS Pixel Ratio: 2
    • Logical Resolution:

    formula

    When viewing a web page, the CSS will think the device has a 375x667 resolution screen and Media Queries will respond as if the screen is 375x667. But the rendered elements on the screen will be twice as sharp as an actual 375x667 screen because there are twice as many physical pixels in the physical screen.

    Some other examples:

    Samsung Galaxy S4

    • Actual Resolution: 1080 x 1920
    • CSS Pixel Ratio: 3
    • Logical Resolution:

    formula

    iPhone 5s

    • Actual Resolution: 640 x 1136
    • CSS Pixel Ratio: 2
    • Logical Resolution:

    formula

    Why does the Device Pixel Ratio exist?

    The reason that CSS pixel ratio was created is because as phones screens get higher resolutions, if every device still had a CSS pixel ratio of 1 then webpages would render too small to see.

    A typical full screen desktop monitor is a roughly 24" at 1920x1080 resolution. Imagine if that monitor was shrunk down to about 5" but had the same resolution. Viewing things on the screen would be impossible because they would be so small. But manufactures are coming out with 1920x1080 resolution phone screens consistently now.

    So the device pixel ratio was invented by phone makers so that they could continue to push the resolution, sharpness and quality of phone screens, without making elements on the screen too small to see or read.

    Here is a tool that also tells you your current device's pixel density:

    http://bjango.com/articles/min-device-pixel-ratio/


  • Translate

    https://developer.mozilla.org/en/CSS/Media_queries#-moz-device-pixel-ratio

    -moz-device-pixel-ratio
    Gives the number of device pixels per CSS pixel.

    this is almost self-explaining. the number describes the ratio of how much "real" pixels (physical pixerls of the screen) are used to display one "virtual" pixel (size set in CSS).


  • Translate

    Boris Smus's article High DPI Images for Variable Pixel Densities has a more accurate definition of device pixel ratio: the number of device pixels per CSS pixel is a good approximation, but not the whole story.

    Note that you can get the DPR used by a device with window.devicePixelRatio.