Getting the physical screen dimensions / dpi / pix

2019-01-02 20:04发布

Question

Is there a safe way to get the actually correct screen physical dimensions in Chrome, on Android? If necessary, old versions of Chrome and Android can be left out of scope.

Prior research

There are numerous dead-end questions on stackoverflow about getting the actual physical screen dimensions of a device from within javascript (or css). It seems there is no convergence between html api standardization and actual browser implementations in that, not to mention the browser implementation relies on OS api's which in turn rely on hardware providing the right information.

Some prior answers by the way are arcane (year 2011 and the like) in assuming a certain pixel density that prevailed at that time, and therefore useless. Others relate to webkit whereas Chrome blink may have superseded webkit in chrome (?).

I would like to explore the existence of a simple solution by constraining things to only Chrome on Android.

Note

This is all about a javascript (or css) solution inside the browser, not a solution for a native app.

11条回答
谁念西风独自凉
2楼-- · 2019-01-02 20:34

As a response to zehelvion reply about using WURFL to find the resolution, it is also worth mentioning that WURFL is also available as a JavaScript snippet.

In the free edition offered at wurfl.io, you won't get information about the screen and resolution though (only device name, form factor and mobile/not mobile), but there is also a commercial version with more capabilities available here.

查看更多
墨雨无痕
3楼-- · 2019-01-02 20:36

You can get a rough estimation of size, but it's not accurate.

I've put together an example which I've tested on a couple devices to see what the results were. My iPhone 6 returns values about 33% larger. My 27" desktop monitor on my Mac reported as a 30" monitor.

var $el = document.createElement('div');
$el.style.width = '1cm';
$el.style.height = '1cm';
$el.style.backgroundColor = '#ff0000';
$el.style.position = 'fixed';
$el.style.bottom = 0;
document.body.appendChild($el);
var screenDiagonal = Math.sqrt(Math.pow((window.screen.width / $el.offsetWidth), 2) + Math.pow((window.screen.height / $el.offsetHeight), 2));
var screenDiagonalInches = (screenDiagonal / 2.54);
var str = [
  '1cm (W): ' + $el.offsetWidth + 'px',
  '1cm (H): ' + $el.offsetHeight + 'px',
  'Screen width: ' + window.screen.width + 'px',
  'Screen height: ' + window.screen.height + 'px',
  'Browser width: ' + window.innerWidth + 'px',
  'Browser height: ' + window.innerHeight + 'px',
  'Screen available width: ' + window.screen.availWidth + 'px',
  'Screen available height: ' + window.screen.availHeight + 'px',
  'Screen width: ' + (window.screen.width / $el.offsetWidth).toFixed(2) + 'cm',
  'Screen height: ' + (window.screen.height / $el.offsetHeight).toFixed(2) + 'cm',
  'Screen diagonal: ' + screenDiagonal.toFixed(2) + 'cm',
  'Screen diagonal: ' + screenDiagonalInches.toFixed(2) + 'in',
  'Device Pixel Ratio: ' + (window.devicePixelRatio || 1)
].join('\n');
var $pre = document.createElement('pre');
$pre.innerHTML = str;
document.body.appendChild($pre);

http://codepen.io/kus/full/xOAPYB/

查看更多
皆成旧梦
4楼-- · 2019-01-02 20:41

CSS pixels aren't really our "device independent pixel". Web platform consists of variety of device types. While CSS pixel seem to look pretty consistent on handhelds, it will be 50% bigger on a typical 96dpi desktop monitor. See my question . This is really not a bad thing in some cases, e.g. fonts should be larger on a larger screen, since distance to the eye is bigger. But ui element dimensions should be pretty consistent. Let's say your app has a top bar, you would rather want it to be the same thickness on desktop and mobiles, by default it will be 50% smaller, which is not good, because touchable elements should be bigger. The only workaround I have found is to apply different styles based on device DPI.

You can get screen DPI in JavaScript with window.devicePixelRatio . Or CSS query:

@media  only screen and (-webkit-min-device-pixel-ratio: 1.3),
    only screen and (-o-min-device-pixel-ratio: 13/10),
    only screen and (min-resolution: 120dpi)
    {
     /* specific styles for handhelds/ high dpi monitors*/
    }

I don't know how applying this would work on a high dpi desktop monitor though. Perhaps elements would be too small. It is really a shame that the web platform doesn't offer anything better. I guess that implementation of dip wouldn't be too hard.

查看更多
ら面具成の殇う
5楼-- · 2019-01-02 20:51

I tackled this problem with one of my web projects http://www.vinodiscover.com The answer is that you can't know for certain what the physical size is, but you can get an approximation. Using JS and / or CSS, you can find the width and height of the viewport / screen, and the pixel density using media queries. For example: iPhone 5 (326 ppi) = 320px by 568px and a 2.0 pixel density, while a Samsung Galaxy S4 (441ppi) = 360px x 640px and a 3.0 pixel density. Effectively a 1.0 pixel density is around 150 ppi.

Given this, I set my CSS to show 1 column when the width is less than 284px, regardless of pixel density; then two columns between 284px and 568px; then 3 columns above 852px. It's much more simple then it seems, since the browsers now do the pixel density calculations automatically.

http://www.quirksmode.org/blog/archives/2010/04/a_pixel_is_not.html

查看更多
不流泪的眼
6楼-- · 2019-01-02 20:52

Based on Matt's answer, I made a test:

// on Macbook Pro Retina (2880x1800, 15.4"), is the calculated diagonal size
// approximately 15.4? Let's see...

var svgEl = document.createElementNS("http://www.w3.org/2000/svg", "svg");
var screenWidthMillimeters = svgEl.screenPixelToMillimeterX * 2880;
var screenHeightMillimeters = svgEl.screenPixelToMillimeterY * 1800;
var screenDiagonalMillimeters = Math.sqrt(Math.pow(screenWidthMillimeters, 2) + Math.pow(screenHeightMillimeters, 2)); // pythagorean theorem
var screenDiagonalInches = (screenDiagonalMillimeters / 10 / 2.54); // (mm / 10mm/cm) / 2.54cm/in = in

console.log("The calculated diagonal of the screen is "+screenDiagonalInches+" inches. \nIs that close to the actual 15.4\"?");

This is the output:

The calculated diagonal of the screen is 35.37742738560738 inches. 
Is that close to the actual value of 15.4?

Nope.

So there seems to be no way to get real physical values in a web browser yet.

查看更多
后来的你喜欢了谁
7楼-- · 2019-01-02 20:52

Using the getPPI() function (Mobile web: how to get physical pixel size?), to obtain a one inch id use this formula:

var ppi = getPPI();
var x   = ppi * devicePixelRatio * screen.pixelDepth / 24;
$('#Cubo').width (x);
$('#Cubo').height(x);

<div id="Cubo" style="background-color:red;"></div>
查看更多
登录 后发表回答