209

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

}
ilyo
  • 35,851
  • 46
  • 106
  • 159

5 Answers5

208

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:

res_p/res_l

Where res_p is the physical linear resolution, and res_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 there is a reference pixel, which is a non-linear angular measurement of 0.0213° viewing angle. This is approximately 1/96 of an inch. 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 or the HTML picture Element 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.

Matthias
  • 13,607
  • 9
  • 44
  • 60
Anders Marzi Tornblad
  • 18,896
  • 9
  • 51
  • 66
  • 1
    thanx, so if i make a css file for iphone 4 and give the page CSS measurements of 480 x 320 and `width=device-width` i'll have it stretched to full screen? – ilyo Jan 09 '12 at 08:44
  • 1
    Exactly. And if you are using high-resolution pictures for `background-image`, you can combine it with `-webkit-background-size:50%`, because otherwise, the image size will follow the **logical** pixel count. http://www.w3.org/TR/2002/WD-css3-background-20020802/#background-size – Anders Marzi Tornblad Jan 09 '12 at 10:41
  • 1
    And how do I make the logical and physical pixels to be the same on the iphone 4? – ilyo Jan 09 '12 at 12:06
  • 2
    You can't. You'll need to layout your elements using logical pixels, and use higher-resolution images and the `background-size` trick for using the display optimally. – Anders Marzi Tornblad Jan 09 '12 at 12:37
  • so the `device-width` in iphone 4 is 320? do you know what is the case in the android browser? – ilyo Jan 10 '12 at 08:10
  • 2
    I have no idea about the android case. It could be that different manufacturers have different ideas about logical and physical pixels... Try it out yourself on a couple of hundred different devices... Or simply assume that the values reported by the device are correct. Don't design for specific devices, but design for value ranges using media queries! – Anders Marzi Tornblad Jan 10 '12 at 08:52
  • @atornblad as recent Androids have very high densities, they report a high pixel ratio. Xperia Z1 (1920*1080, 5.1") reports a ratio of 3 for instance – Rayjax Jun 18 '14 at 15:39
  • That is true, @Rayjax , but how does that make anything different? – Anders Marzi Tornblad Jul 17 '14 at 11:07
  • I was simply giving some hints on "the android case" about which ilyo was talking – Rayjax Jul 17 '14 at 12:14
  • As he said, iphone 4 has a device-width of 320. xperia Z1, Z2, and Galaxy S4 for example have logical widths of 360 (1080/3). Logical width is always related to the device's screen size – Rayjax Jul 17 '14 at 12:26
  • What happens, for example, when a device reports a ratio of say x1.8... Will the device use the nearest media query of x2 or x1.5, or will it simply revert to the default? – remarsh Dec 14 '14 at 00:25
  • 1
    @remarsh : This is where `min-*` and `max-*` comes in. You can use those constructs to specify ranges of values of media query properies. – Anders Marzi Tornblad Dec 15 '14 at 13:21
  • 2
    @atornblad I think it should be ".. between *physical* and *logical* pixels" – Ilya Buziuk Dec 18 '14 at 12:09
  • 1
    Thank you very much! In a couple rows, you have explained something that other persons TRY to explain in hundreds of rows. – Marian07 Nov 10 '15 at 19:39
  • One more question. Lets say I had a 600x600 px image and I set its size to 300x300px in CSS. Would this mean that on a device with a pixel ratio of 2 it would display all the pixels in the 600x600 image ? – DollarAkshay Jun 26 '16 at 08:00
  • Yes, on a display with at least 2x ratio. Try it!! – Anders Marzi Tornblad Jun 26 '16 at 08:54
  • @AndersTornblad You say that `px` in CSS operates on the *logical* pixels, which are already an abstraction of the *physical* pixels (as defined by the device pixel ratio). As far as I know, a CSS pixel (`px`), is [recommended](https://www.w3.org/TR/css3-values/#absolute-lengths) to be a multiple of device pixels. So are you saying that the "device pixels" taken into account by CSS to determine the size of a `px` are the logical pixels and not the device's physical pixels? CSS doesn't even know that the device has a physically higher resolution than the logical one that it sees? – weibeld Oct 10 '17 at 23:32
  • "You need to start thinking about SVG, which scales beautifully to all resolutions." Except vector art does not scale well when targeting 24x24 icons or smaller. Each browser will do its own drawing/scaling of a color SVG and generally produce garbage. PNG offers precision pixel placement. The downside with that is mobile devices with higher pixel densities will bicubic scale up a small PNG designed to be shown at a very specific size and produce a blurry mess. It can be offset somewhat with the `image-rendering` CSS attribute but the results are less than ideal with some jaggy edges. – CubicleSoft May 30 '20 at 00:23
192

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/

Jake Wilson
  • 88,616
  • 93
  • 252
  • 370
  • Wikipedia article has been deleted. :-( Is this information available anywhere else? – Simon East Sep 10 '14 at 14:06
  • 1
    So images are streched to match high dpi or physical pixels. Say image is 300px, logical/css px is 300 too but physical px is 600 then setting image width would mean image got stretched.. i also heard that sometimes images show smaller on high dpi , why? – Muhammad Umer Jun 09 '15 at 22:31
  • 2
    @MuhammadUmer In your example a 300px image with `width: 100%` will be the full width of the display. It will not be stretched. The screen "thinks" it's a 300px display. Images are displayed according to the logical/css resolution. Now, in your example you could also instead serve a 600px image. It will be the full width of the logical 300px display, but since your display is native 600px the image will look twice as sharp as your original 300px image. Bigger image, but it looks better since the display has all those extra pixels. This is the idea behind "Retina Displays". – Jake Wilson Jan 06 '16 at 18:37
  • @JakeWilson: This is a new topic for me and I don't fully understand it. In the example CSS pixel ratio=2. The picture is 300 physical pixels wide, in css we set it to 100%, so it will become 300 CSS pixels wide. Since the CSS px ratio is 2, it will become 600 physical pixels wide and its width will match the display's width exactly. But how come it is not stretched if its original width is 300 physical px and now it's 600 physical px? My understanding is its quality is lower because it got physically stretched from 300 to 600px. Can you elaborate on this a bit more, please? – Peter Mar 19 '16 at 06:48
  • 1
    If a device is 600 physical pixels wide with CSS pixel ratio = 2, then your CSS thinks the screen is only 300px wide. For example, if you set an image to 150px wide it will take up 1/2 the screen. Regarding quality, if you provide a 600px wide image the image will be twice as sharp as a 300px wide image since there are 600 physical pixels. – Jake Wilson Mar 19 '16 at 07:16
  • @JakeWilson: If you provide a 600 physical px wide image you have to set in css or html it's 300px wide(because html and css use css pixels), right? When displaying the image it will become 300(css px)*2(css ratio)=600 physical pixels wide. So, it will not get stretched because originally it was 600 physical px wide and so is now and this is why it's sharp. Is my understanding correct? – Peter Mar 19 '16 at 09:24
  • Just set it to 100% width and you'll be fine. – Jake Wilson Mar 19 '16 at 20:27
  • Does a device come up with a defined device pixel ratio and then the logical resolution is calculated or is it the other way round? – Anuj Jul 09 '16 at 23:01
  • 1
    @Anuj I don't know and it doesn't really matter how it's defined in the hardware/software. One is calculated from the other either way you cut it. – Jake Wilson Jul 10 '16 at 01:04
  • The entire reason of cramming another layer of indirection between device and CSS implementation, where pixels are no longer just pixels, is because everyone jumped on the wrong bandwagon up to and around the turn of the millenium where they thought that 14 pixels of document font size should be enough for everyone. And the rest of us are paying the price ever since. "Logical pixels" should have never existed, as they only add another variable to take care of. Em and percentage units wer perfectly capable of solving the problem the entire time. Whether you have a 320 or 32000 px wide display. – Armen Michaeli Jul 10 '16 at 18:23
  • I read a lot of articles about this topic to understand it, but only with your clear explanation I finally realized what is going on here. Thank you Jake Wilson. – GProst Apr 14 '17 at 06:14
  • Is the device pixel ratio determined by the device, or independently by each browser on the device? This [article](https://www.quirksmode.org/blog/archives/2012/07/more_about_devi.html) suggests that each browser determines the device pixel ratio independently. – weibeld Oct 10 '17 at 23:08
  • That's a great question and I've never seen an article other than this one suggest that. But near the end the article also says "That’s perfectly fine as long as they (the browsers) report the correct `devicePixelRatio`." So that gives some conflicting information for sure. I'm honestly not sure what the correct answer is here. – Jake Wilson Oct 11 '17 at 02:34
12

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.

Sam Dutton
  • 14,775
  • 6
  • 54
  • 64
10

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).

oezi
  • 51,017
  • 10
  • 98
  • 115
  • 4
    how do I know if a device uses at all a virtual pixel measurement and what it is? and how do i use the device pixels in the css measurements and not the virtual? – ilyo Jan 09 '12 at 08:56
  • sadly, you have to google it or test on a real device :( – netalex Feb 19 '16 at 09:53
0

Device Pixel Ratio has direct correlation with Pixel density of the device.

Best concise description I could find:

Purpose of DPR is to keep consistent size of CSS pixels and therefore consistent size of letters, symbols, images and everything else on screen, across a variety of devices with different physical pixel densities.

Source: screenresolutiontest

DarkestOne
  • 49
  • 8