Processing
 

Getting the physical screen dimensions / dpi / pixel density in Chrome on Android

10/02/2014 10:56#1

matanster

Member

Joined at: 11 months ago

Post: 7

Thank: 0

Thanked: 0

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 but Chrome is using blink for a while already, so those are not very relevant too.

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.

Update:

Well, I bumped into the following new property pair: screenPixelToMillimeterX, screenPixelToMillimeterY, which spit out some numbers in latest version Chrome, and is documented for IE and Firefox (e.g. https://developer.mozilla.org/en/docs/Web/API/SVGSVGElement). Not sure if it's useful, it can't know anything unless the OS can tell.

13/02/2014 23:00Top#2

Kinlan

Member

Joined at: 11 months ago

Post: 188

Thank: 0

Thanked: 0

You can't really get the real physical dimensions or the actual DPI and even if you could, you can't do anything with them.

This is a pretty long and complex story, so forgive me.

The web and all browsers define 1px as a unit called a CSS pixel. A CSS pixel is not a real pixel, rather a unit that is deemed to be 1/96th of an inch based on the viewing angle of the device. This is specified as a reference pixel.

The reference pixel is the visual angle of one pixel on a device with a pixel density of 96dpi and a distance from the reader of an arm's length. For a nominal arm's length of 28 inches, the visual angle is therefore about 0.0213 degrees. For reading at arm's length, 1px thus corresponds to about 0.26 mm (1/96 inch).

In 0.26mm of space we might have very many real device pixels.

The browser does this mainly for legacy reasons - most monitors were 96dpi when the web was born - but also for consistency, in the "old days" a 22px button on a 15 inch screen at 800x600 would be twice the size of a 22px button on a 15 inch monitor at 1600x1200. In this case the DPI of the screen is actually 2x (twice the resolution horizontally but in the same physical space). This is a bad situation for the web and apps, so most operating systems devised many ways to abstract pixel values in to device independent units (DIPS on Android, PT on iOS and the CSS Pixel on the web).

The iPhone Safari browser was the first (to my knowledge) to introduce the concept of a viewport. This was created to enable full desktop style applications to render on a small screen. The viewport was defined to be 960px wide. This essentially zoomed the page out 3x (iphone was originally 320px) so 1 CSS pixel is 1/3rd of a physical pixel. When you defined a viewport though you could get this device to match 1 CSS pixel = 1 real pixel at 163dpi.

By using a viewport where the width is "device-width" frees you up from having to set the width of the viewport on a per device basis to the optimal CSS pixel size, the browser just does it for you.

With the introduction of double DPI devices, mobile phone manufacturers didn't want mobile pages to appear 50% smaller so they introduced a concept called devicePixelRatio (first on mobile webkit I believe), this lets them keep 1 CSS pixel to be roughly 1/96th of an inch but let you understand that your assets such as images might need to be twice the size. If you look at the iPhone series all of their devices say the width of the screen in CSS pixels is 320px even though we know this is not true.

Therefore if you made a button to be 22px in CSS space, the representation on the physical screen is 22 * device pixel ratio. Actually I say this, it is not exactly this because the device pixel ratio is never exact either, phone manufacturers set it to a nice number like 2.0, 3.0 rather than 2.1329857289918....

In summary, CSS pixels are device independent and let us not have to worry about physical sizes of the screens and the display densities etc.

The moral of the story is: Don't worry about understanding the physical pixel size of the screen. You don't need it. 50px should look roughly the same across all mobile devices it might vary a little, but the CSS Pixel is our device independent way to build consistent documents and UI's

Resources:

31/07/2014 21:16Top#3

trusktr

Member

Joined at: 11 months ago

Post: 18

Thank: 0

Thanked: 0

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.

18/09/2014 15:30Top#4

zehelvion

Member

Joined at: 11 months ago

Post: 14

Thank: 0

Thanked: 0

tl;dr You can get that info with WURFL:

Device display properties

The attributes are called:

resolution_(width|height)  physical_display_(width|height) 

Long version:

The best and most reliant strategy to achieve this is to send the user agent string from the browser to a DB like WURFL (or another) up to date DB that can provide the needed information.

User Agent string

This is a piece of information that all modern browsers can provide; it exposes information about the device and it's OS. It is just not meaningful enough to your application without the help of a dictionary like WURFL.

WURFL

This is a database commonly used to detect device properties.

With it, you may be able to accurately support most of the popular devices on the market. I would post a code demo but one is available with the download on the WURFL site. You can find such a demo on the examples/demo folder that is downloaded with the library.

Download WURFL

Here is more information and explanation about checking the physical size and resolution: http://www.scientiamobile.com/forum/viewtopic.php?f=16&t=286

25/03/2015 10:14Top#5

Mike

Member

Joined at: 11 months ago

Post: 566

Thank: 0

Thanked: 0

You can create any page element and set it's width using real physical units. For example

<div id="meter" style="width:10cm"></div> 

And then get it's width in pixels. For example html code below (i used JQuery) shows device screen width in centimeters

<script> var pixPer10CM = $('#meter').width(); var CMPerPix = 10 / pixPer10CM; var widthCM = screen.width * CMPerPix;  alert(widthCM); </script> 
19/02/2014 19:35Top#6

Joined at: 7 months ago

Post: 3

Thank: 0

Thanked: 0

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

16/07/2014 12:14Top#7

matanster

Member

Joined at: 11 months ago

Post: 7

Thank: 0

Thanked: 0

I bumped into the following property pair: screenPixelToMillimeterX, screenPixelToMillimeterY, which surprisingly spit out some numbers in latest version Chrome. https://developer.mozilla.org/en/docs/Web/API/SVGSVGElement. Not sure if it's useful, it can't know anything unless the OS can tell it. Maybe this provides accurate results reasonably across OS's and hardware.

13/09/2014 09:37Top#8

Pilo

Member

Joined at: 5 months ago

Post: 1

Thank: 0

Thanked: 0

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> 
02/05/2016 15:11Top#9

jonarnes

Member

Joined at: 5 months ago

Post: 1

Thank: 0

Thanked: 0

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.

17/02/2014 19:43Top#10

danny117

Member

Joined at: 5 months ago

Post: 1

Thank: 0

Thanked: 0

JqueryMobile width of element

$(window).width();   // returns width of browser viewport $(document).width(); // returns width of HTML document 

JqueryMobile Height of element

$(window).height();   // returns height of browser viewport $(document).height(); // returns height of HTML document 

Good Luck Danny117

25/05/2016 20:10Top#11

Joined at: 9 months ago

Post: 2

Thank: 0

Thanked: 0

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.

04/07/2016 23:45Top#12

Kus

Member

Joined at: 8 months ago

Post: 2

Thank: 0

Thanked: 0

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/

Similar articles

Chrome, THREE.js: Cross-origin image load denied

5 years ago - Reply: 5 - Views: 269

Prevent Google Chrome Log XMLHttpRequest

3 years ago - Reply: 5 - Views: 276

How can I include ChromeDriver in a JAR?

3 years ago - Reply: 3 - Views: 81

Chrome geolocation not working on any site

3 years ago - Reply: 1 - Views: 46

wrong borders' width in android browser

3 years ago - Reply: 4 - Views: 206

Uncaught SyntaxError: Unexpected token < On Chrome

3 years ago - Reply: 10 - Views: 468

Flashdata not getting cleared in Codeigniter

3 years ago - Reply: 5 - Views: 57

Illegal access Javascript error in Chrome

3 years ago - Reply: 1 - Views: 51

ng-repeat not updating in Chrome

3 years ago - Reply: 1 - Views: 81

Applying border to a checkbox in Chrome

4 years ago - Reply: 2 - Views: 118

open browser plugin using access vba

3 years ago - Reply: 1 - Views: 25

vé máy bay vé máy bay giá rẻ ve may bay ve may bay gia re vé máy bay vé máy bay giá rẻ ve may bay ve may bay gia re vé máy bay vé máy bay giá rẻ ve may bay ve may bay gia re vé máy bay vé máy bay giá rẻ ve may bay ve may bay gia re vé máy bay vé máy bay giá rẻ ve may bay ve may bay gia re vé máy bay vé máy bay giá rẻ ve may bay ve may bay gia re vé máy bay vé máy bay giá rẻ ve may bay ve may bay gia re