Real World Absolute Length Units Evaluation

An important link to read is CSS Values and units: lengths at MDN. We can take from that: The definition of Absolute length units is bound to physical/real world measurements of length:

1 in = 2.54 cm = 96 px

Even the size of a pixel is bound to a real world physical size, 1 px ~ 0.0265 mm (2.54 / 96).

However, there is a fundamental problem, as old as computer displays. Browser CSS-units don't relate to physical units as defined by the International System of Units (SI). Wikipedia discusses some of it in Dots per inch. NOTE: for computer displays some prefer talking about PPI (pixels per inch) rather than DPI (dots per inch), which often is interchangeable in meaning. The root lies in different pixel densities per display and becomes more apparent since more and more "high DPI" displays are around.

Essentially, CSS absolute length units are fantasy units that don't have anything to do with physical real world units. Each device with a different PPI will have a different manifestation of e.g. a centimeter, unless it has been calibrated/compensated in some way.

What the display "knows" about the world:

A LED-panel can inform the computer of its PPI, in my case on a GNU/Linux:


$ xrandr | grep -w connected
eDP-1 connected primary 3200x1800+0+0 (normal left inverted right x axis y axis) 293mm x 165mm

This is enough information to calculate a PPI of 277.41 ( ~ 3200 / (29.3 / 2.54))

However, a digital projector usually can't tell: its PPI changes with the focal length of the lens and the distance to the wall/screen and that info is usually not available (not to the projector nor to the connected computer). An example:


$ xrandr | grep -w connected
HDMI-2 connected 1920x1080+3200+0 (normal left inverted right x axis y axis) 1600mm x 900mm

The actual measurements of the projected image were: ~ 2570mm x 1430 mm (not exactly 16:9, but close enough). So, the real world measurements were ~ 1.6 (or 8/5) times bigger than the reported values.

CAVEAT: even though the operating system may know the physical display size and resolution, the browser doesn't expose that information.

How the browser compensates high DPI displays

In Javascript/DOM window.devicePixelRatio (aka. Dots Per Pixel/dppx) describes the ratio used to map CSS pixels to device/screen/physical pixels. This is how websites can be designed using pixels (or centimeters), without knowing exactly how big a pixel actually is. It also is just a really rough approximation that does not match 96 pixels = 1 inches in real world units on most devices . On my Laptop in front of me the window.devicePixelRatio is 2, which is caused by having set a scale of 200 % for my display in the Gnome 3 settings menu. zooming into the web page also changes this number. At 150 % browser zoom, I get a devicePixelRatio of 3, this matches real world units to CSS units a bit better.

The limits of control

To decide my scale factor in Gnome 3, I just used a setting that suited me, 100 % being too small to read comfortably. I never measured any real values, nor can I set other values than 100 % or 200 % (there's a 300 % option, but it has the same effect as 200 %, probably a bug).

Experiment: calibrate to real world units

This scale is marked up to be 10 cm wide in CSS units.

Measure the scale above on your physical screen with a physical ruler.

If the measurement was correct, this scale is now 10 cm wide in real work units.

Scale Factor = CSS Value / Real World Value (the measurement)
Scale Factor = 10 cm /  cm
Scale Factor = 

With this information, we can calculate the actual device PPI fairly accurately:

CSS-PPI = 96 (constant as shown above)
Device-PPI = CSS_PPI * Scale-Factor * window.devicePixelRatio
Device-PPI = 96 *  * 
Device-PPI = 

And also we can calculate the real world display size(!):

CSS-PPCM (pixel per cm) = 96 / 2.54
CSS-PPCM (pixel per cm) = 

CSS-Display-Width (in CSS-cm) = window.screen.width / CSS-PPCM
CSS-Display-Width (in CSS-cm) =  / 
CSS-Display-Width (in CSS-cm) =  cm

Device-width = CSS-Display-Width / Scale-Factor
Device-width =  / 
Device-width =  cm

CSS-Display-Height (in CSS-cm) = window.screen.height / CSS-PPCM
CSS-Display-Height (in CSS-cm) =  / 
CSS-Display-Height (in CSS-cm) =  cm

Device-height = CSS-Display-Height / Scale-Factor
Device-height =  / 
Device-height =  cm

Conclusion

Bad: There's no relation to real world units in the browser. Operating Systems may be able to know real world measurements, depending if the display reports them correctly, but they also don't make use of it. Operating System scaling support is sketchy, but also not intended for calibration, display zoom settings are rather just used to make the screen contents readable at all on "high DPI" displays.

Good: A simple widget and a simple measurement performed by the user is enough to establish a conversion factor that is sufficient to map between the real world units and abstract computer units. That widget can be deployed on a per app or website basis. With convincing applications for real world measurements a general browser support API and even some kind of operating system support is thinkable, especially because the majority of displays already can report correct measurements.

Calibration use cases

This list unfinished, please submit suggestions via GitHub.

Calibration-Widget ideas

This list unfinished, please submit suggestions via GitHub.