Javascript – Programmatically determine DPI via the browser

dpijavascriptmootools

I would like to programmaticaly determine the DPI of a user's display in order to show a web page at a precise number of units (centimeters/inches). I know it a weird request: it's for a visualization research project and it's kind of a control. We currently do it by having the user place a credit card to the screen and match a resizable div (via Mootools) to the real credit card, and voila we can get the DPI and display the page correctly.

Can anyone think of a programmatic way to do this?

Best Answer

If you're doing this in javascript/mootools, CSS units are your friend. You can specify sizes in inches or centimeters, or even points (1/72 of an inch). If you absolutely need DPI for whatever reason even though you can specify sizes in those units, simply size the "resizable" div you are using to a known size and calculate from the translated pixel size.

Edit:

Unfortunately, the CSS units of points, cm, and in are not physically correct. They are only relatively correct. This was the first thing I tried until I realized it wasn't working and checked the CSS spec.. to my dismay.Brandon Pelfrey

That's a good point; browsers tend to fake it by assuming a default DPI (I think 72 or 96) and going with that.

Well, if you need precision sizing like you're asking for, you're out of luck. You'll never be able to get it without being able to read both the current resolution of the monitor the browser is on and the "viewable screen area" of that monitor. Ain't no way you're gonna get that via Javascript.

I suggest that you make the default assumption that browsers do and size according to the CSS units. You can then allow your users to "adjust the sizing" using the method you mentioned, but only if it's necessary. Do this with on a separate page with the DPI calculation stored as part of the users session or as a cookie.

Alternatively, once Microsoft fixes this bug, you could use Silverlight's "device independent units" for accurate scaling.