Web and physical units - javascript

Is there a way to tell/set, how many millimeters an element has, which works across various devices?
For example, I would like to create a white window which is 100 x 100 mm, with a black 10 x 10 mm square in the middle, which would have those dimensions on desktop, tablet, print, ...
I don't mind to use very latest browser but it has to use HTML/JS/CSS.
PS: Related: is there a way to tell, how many millimeters the screen has?
Edit
In other words, the problem is that using CSS units like pt, mm, cm, ... does not work as browser vendors decided to hardcode 96 DPI into the agents, according to here. Is there anything one can do to get real, physical, dimensions on web?

Not really.
In theory you can set lengths using mm units, but this requires that the browser accurately handles the DPI of the display … and browsers tend to assume a fixed value instead of getting the real one.
If that worked, you could then get the width in that unit by creating an off-screen element of known physical dimensions, reading the pixel dimensions using JavaScript and using that ratio to convert the pixel dimensions of any other element to mm.
In practice, if you need accurate measurements you are pretty much limited to drawing something on screen and asking the user to measure it with a ruler to get your ratio.
Alternatively, if you can identify the specific device in use (which the User Agent String may tell you for some devices) and you keep a database of the physical sizes of those devices (so this is limited to a subset of phones and tablets and won't work if they are connected to an external display) you could use that to determine the dimensions.

cm and mm can be used as CSS units , For more information please have a look at
http://www.w3.org/TR/css3-values/#lengths
16px == 0.17in == 12pt == 1pc == 4.2mm == 0.42cm
Im not sure how well they work in high screen density devices..

Related

How to determine how many pixels per inch (or per centimetre) do we have (in CSS/JavaScript/jQuery or other language/technology?) [duplicate]

I need to put in my site div which is exactly 25cm width ( 10 inch) in every display. How I can do it ?
You can simply use the cm unit in CSS:
#mydiv { width: 25cm; }
Note that, as others pointed out, the result still depends on the correct reading of the monitor size by the operating system.
See the spec for more information.
How I can do it ?
You can't. Update: apparently, you can on many modern systems: Check out #Tomas's answer. It seems not to be always entirely reliable, though.
Old answer: You can't. Monitors display different numbers of pixels. The pixel size varies wildly from monitor to monitor.
There are ways to interpolate the pixel size if you know the monitor size. This information is sometimes available to the operating system; however, it is impossible for a web site to get hold of this information.
The only way to go would be to have the user do a calibration. For example, ask the user to hold an A4 piece of paper to the monitor, and use a draggable ruler to determine the area it covers. Using that information, you can then calculate how many pixels you will need to show 25 centimeters.
Update: #Tomas claims in his answer that using CSS cm values works on screen.
This is in fact true on my Windows 7 and 23" Plug&Play TFT Monitor (1920x1080 Pixels): 21cm translates perfectly to the short side of a A4 sheet of paper in Chrome 7, IE6(!), IE7, Firefox 3.6.
It doesn't seem to be entirely reliable, though: #Yi Jiang can't get it to work on a TFT using Ubuntu Linux; also, older Monitors may not send through their size information so it'll be impossible for the OS to determine a correct size.
Here's a simple JSFiddle for testing.
You can't. A program can only get the true physical dimensions of a screen by interrogating EDID as values returned by the Windows API are not reliable. A program can get the true values for resolution (e.g.1280 x 1024) and screen dpi, but browsers can't do any of this by themselves.
There is a constant confusion between the "physical dpi" of a screen and "screen dpi". The physical dpi, more properly called pixels per inch, is obtained by dividing the maximum pixel width of the screen by the physical (ruler) width in inches. The pixels per inch are fixed by the manufacturing process. The screen dpi is a number that the user can set via the Control Panel and it's only purpose is to convert a value in inches into a number of pixels. The user settable screen dpi value has no direct relationship whatever with the physical dpi (pixels per inch) and is just a number with a default value of 96. There is nothing magic about 96, or 120
Number of screen pixels = number of inches x screen dpi
It's as simple as that.
The reason 21 cm on a 23 inch monitor at 1920 x 1080 "translates" to the width of an A4 sheet (21 cm) is because with a 23 inch diagonal the screen width is 20.05 inches and at 1920 pixels across the pixel density is 95.76 pixels per inch.
With screen dpi default value of 96 then for one inch: pixels = 1 x 96 = 96 pixels
The pixel density of the 23 inch screen is 95.76 pixels per inch which matches the number of pixels you get, when specifying a length of one inch, with the default screen dpi value of 96.
If screen dpi is changed in the Control Panel, or the monitor video resolution is changed, then 21 cm would not match the width of a sheet of A4.
You will need to get hold of the resolution of the display and the dot pitch of the monitor to be able to calculate this.
Given these two values you'll be able to calculate the number of pixels you need.
However, you can't get hold of this information from a web site.
Given that you state it's a <div> in a site, we know you're in a web browser environment.
Sadly for you, the web browser doesn't have any way to find out the screen's DPI. You can find out what the screen resolution is, so you'll know whether the user has 1024x760 or whatever, but you'll never know whether those 1024x768 pixels are being displayed on an iPhone sized screen or a billboard, or anything in between.
Sorry about that.
I believe the layout engine would need to know three things to make this possible:
Screen resolution
DPI
Physical monitor size
As far as I'm aware, it doesn't know all three.

Showing an image in actual size with CSS

I want to show an image in actual size(real world size). I used mm unit to show the image in actual size but it wasn't exact in my two computers.
Here is the fiddle of my code, this is a picture of a credit card. a credit card is 85.60 × 53.98 mm so if you put your credit card on screen you probably will see it's smaller.
img{
width:85.60mm;
height:53.98mm;
}
Basically the problem is mm, cm and in units are not working properly in screen. They are fine in printed version. Actually it seems those units are not made to work in the screen as what I got from W3C.
So is there any solution for this problem?
-----EDIT------
I created another fiddle that you can resize the credit card. The question could be how can I find that "Ratio" number? Please look at fiddle here and let me know what you thinking? Is there any way to find that Ratio number from user agent string or something?
There's no way to do this until operating systems, graphics cards, and display manufacturers all agree on a universal standard for converting physical dimensions into a pixels applicable to the particular set up a user is using.
The term for this concept is Resolution Independence
While there is some support for this in OSX and Windows, it's by no means complete and still takes manual intervention to set up properly.
On top of all of that, you are at the mercy of the end-user deciding to over-ride your measurements using zoom--be it on the desktop such as in Firefox or on a touch device by pinching.
So, at this point, I'm afraid there's no way to go about it.
mm and cm should not be dependant on pixels. But for it to render properly your browser has to combine screen diameter, aspect ratio and resolution.
W3C only recommends mm for print so there is probably a large difference in browser implementation for screen
http://www.w3.org/Style/Examples/007/units
BTW on my 1920x1080 (16:9) screen it works quite well
I am pretty sure that mm and cm are dependent on pixels, and pixels vary from monitor to monitor. Adjust your screen resolution and you'll see what I mean.
So, I guess the answer is a 'no'. Sorry.

Is it possible to get a users physical screen size without the use of a physical object or the diagonal measurement?

Question says it all really. I want to be able to display something at actual size, so, for example, if something is displayed in the browser as 20cm, I want to be able to measure it and it to actually be 20cm.
So far I have come across solutions which take into account the diagonal resolution of the screen (such as 21.5 inches) and the screen resolution to calculate how big a pixel is.
Another approach is to ask the user to put up a standard sized card such as a bank card to the screen and measure the edges to calculate the size.
Is there a way to do this without a physical object on the screen or without the user needing to know their diagonal screen size?
Please also let me know if you know of any different solutions other than the ones I have mentioned.
You can't do this with absolute certainty, no. For example, if the display device is not a screen, but a video projector, the effective size will depend on the distance of the projector to the wall, which can change without the operation system getting any feedback.
Most operation systems have some dpi setting (dots per inch), which might either be configured by the user or system administrator, hard-coded (if the video device is build in and can't be changed, like a laptop screen), or maybe automatically discovered (if the video protocol supports this).
Either this setting or a similar browser setting will be used by the browser to calculate absolute sizes used in CSS, like cm, mm, in, pt, and so on.
So you could simply rely on the browser to show it right, or tell your user to set the setting right. (Of course, on a video projector with projection size 3×4 m you don't really want to show a 20 cm object.)
It had been suggested in other places that making a hidden 1" div and then querying the pixel width would get a virtual DPI that you could use to calculate the size by getting the screen width and height in "pixels". I haven't tried this myself yet.

window.pixelRatio not working in Opera. Any alternative?

I have been working on making our CMS export valid content for mobile devices. One of the problems we encountered was that newer devices, like the iphone4 have a higher resolution display so we needed to find a way to render the same page correctly on older devices and newer that use a 300dpi display. So far we used javascript and window.devicePixelRatio in order to get the dpi resolution, but it turns out this is not working in opera(?) and opera mobile.
Any suggestetions or maybe a defferent approach? I researched a bit but was unable to find somethig.
Thanks
I think you might misunderstand what devicePixelRatio is really telling you — surprise, a pixel is not a pixel!
When you specify a pixel size in CSS, you're not necessarily specifying a size in physical pixels. Instead the CSS px unit is actually a "device-independent pixel" (DIP), which is relative to the device's DPI:
Pixel units are relative to the resolution of the viewing device, i.e., most often a computer display. If the pixel density of the output device is very different from that of a typical computer display, the user agent should rescale pixel values.
The reference pixel is defined as 96dpi (Windows' default DPI setting), so on your computer, it is true that 1 DIP (CSS px) = 1 physical screen pixel. Additionally, even though older iOS devices have a physical DPI of 163, they still use 1 DIP = 1 pixel. However, on iPhone 4's doubled resolution of 326 DPI, 1 DIP = 2 screen pixels, which is what devicePixelRatio = 2 is telling you.
Thus, speaking strictly of the difference between the iPhone 3 and iPhone 4, a HTML element with the style { width:100px; height:100px; } should render at roughly the same size on older devices and on the higher-DPI iPhone 4 since it rescales the pixel values.
So there is no reason you sould have to use script to account for high-DPI devices; it should just work.
Opera Mobile doesn't have devicePixelRatio yet as it is pretty much a none-standard extension added by Apple. We are considering adding this however, and may be in the next release of Opera Mobile if we do. You don't need to use JS for this however. It should work in a Media Query too with device-pixel-ratio (with vendor prefixes).
HI all,
josh3736 gave a very nice and concise answer to the css vs device pixel issue. Just wanted to add that it does seem to be an issue with large, high definition images which may need to be served more specifically for individual dpi or ppi device spec's. Searching google, I found that others are (attempting to?) using the device-pixel-ratio as a base to resize images smaller for high ppi displays, while keeping the original high def. image available for these devices and providing low def. images for mobiles without high dpi displays. That way the image is of higher quality for these devices, yet looks sized the same relative to the rest of the page across the spectrum of user devices.
The ability to zoom seems to make this more useful I gather, since a user can zoom in on high def. images and get increased detail. Of coarse this does add another layer of complexity to deal with, but it may be important to address as we have more and more new high end devices entering the markets. Still looking into this, so post back if anyone has good examples.

Programmatically determine DPI via the browser?

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?
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.
You can't. DPI is a function of the pixel resolution of the screen and the physical dimensions of the display. The latter is not available in any browser interface I am aware of.
I think that you won't get precise results - for example you can resize the picture using the monitor. I'd rather stick with the user-driven method, although you can f.e. detect screen resolution for a first estimate.
It's not possible from a browser without code running on the target computer. If you could install something on the target computer you might be able to determine enough about the monitor to calculate this.

Categories