1

I need to be able to work with real length units for any display device and have to be able to rely on them. So I made myself a little ruler. On my laptop screen it comes out way too small. On my cellphone even smaller.

How can one calibrate this? I imagine the display device should have its physical dimension and then the resolution determines the distance of pixels. How can I do this?

        div {
          margin: 0 0 0 0;
          padding: 0 0 0 0;
        }
        div.ruler {
          counter-reset: major -1;
          width: 10cm;
            white-space: nowrap;
            font-size: 0;
        }
        div.number::after {
            content: counter(major);
          counter-increment: major;
          font-size: 3mm;
        }
        div.major {
          width: calc(1cm - 1px);
          height: 5mm;
          text-align: left;
          border-left: 1px solid black;
            display: inline-block;
            font-size: 0;
        }
        div.minor {
          width: calc(1mm - 1px);
          height: 1mm;
          border-right: 1px solid black;
            display: inline-block;
        }
        div.half {
          height: 2mm;
        }
<html>
    <head>
        <title>Screen Geometry and Gestures</title>
    </head>
    <body>
        <main>
            <h1>Screen Geometry and Gestures</h1>
            <section>
                <h2>Length Units</h2>
                <p>Let's make a ruler!</p>
                <div class="ruler">
                    <div class="major">
                        <div class="number"></div>
                        <div class="minor"></div>
                        <div class="minor"></div>
                        <div class="minor"></div>
                        <div class="minor"></div>               
                        <div class="minor half"></div>
                        <div class="minor"></div>
                        <div class="minor"></div>
                        <div class="minor"></div>               
                        <div class="minor"></div>               
                    </div>
                    <script type="text/javascript">
                        const self = document.currentScript;
                        const div = self.previousElementSibling;
                        for(let i = 0; i < 20; i++) {
                          const newdiv = div.cloneNode(true);
                          self.parentElement.insertBefore(newdiv, self);
                        }
                    </script>
                    <div class="major"></div>
                </div>
            </section>          
        </main>
    </body>
</html>
Gunther Schadow
  • 1,490
  • 13
  • 22

2 Answers2

1

CSS "real world" units are based on the size in pixels of an inch, and an inch is always 96 pixels on any device. Thus "1cm" always means 37.8 pixels, and that does not depend on the actual size of the pixels. In addition, a "pixel" on modern displays is not necessarily one actual pixel on the display hardware. Most phones use more than one physical pixel to implement a single pixel as far as browser software is concerned; in other words, your screen size may be reported as 420x1080 pixels, but there may be many more physical pixels.

Think about it: I might have two monitors, each 1920x1080 pixels. One might be the size of a wall, and one might fit on a desk comfortably. There's no way the computer plugged into the monitors can know what "1in" should look like on each one. (Well, it's not an impossibility; the protocol by which monitors communicate their pixel dimensions could — and, as far as I know, actually may — also report physical dimensions, but inside the environment of a browser window, code only sees the pixel dimensions.)

Especially for high-resolution screens in phones and tablets, the way things are supposed to work is that a length like 10 pixels for example, a good length for padding a paragraph of text on its left and right sides, should look good relative to the size of the screen no matter how big the screen is or how tiny the physical pixels are. The device manufacturer is supposed to ensure it works that way. That doesn't always work out (hello, iPad Mini) but fighting against it is tilting at windmills.

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • That's a pretty big bummer. Amazingly silly. They make all these CSS units and then define them in a fixed number of pixels. Don't get me wrong, I am not bashing you, the messenger, but it's really inexcusable. As you say, monitors can report their size even through a VGA cable, let alone a USB or HDMA, and a laptop or phone or tablet know exactly what their physical dimensions are! Nobody will complain about projector dimensions not being fixed (doesn't matter anyway as view angle is more important there). This needs some serious fixing! – Gunther Schadow Oct 12 '22 at 15:40
  • @GuntherSchadow well with print media, the "real world" units work a lot better. On the other hand, browser support for print media CSS is basically terrible across the board. – Pointy Oct 12 '22 at 17:19
  • A long time ago I wrote a TeX DVI driver for my Star Writer needle printer and with that printed a ruler written in TeX and the result was perfectly exact. It can be done. It's a real shame that Knuth's perfect work never made it into the Web world. – Gunther Schadow Oct 12 '22 at 17:46
1

CSS has units of absolute length

For example: CSS supports the inch as a unit of measurement, written as in, e.g.:

.foot { width: 12in; }

The problem, as explained so well by Pointy, is that the pixel is not an absolute unit of length in the real world, because different devices have different pixel densities. (BTW: variable pixel density is a good thing, not a bad thing that must be "fixed.")

This does not mean you can't define a layout that has the same real-world dimensions across all devices. It just means you can't mix-and-match unit types.

This probably means you must avoid using units of length such as pixel, em, rem, vw, vh, etc. You probably need to stick to the units of length that a carpenter would recognize: millimeters, centimeters, and inches.

For something that's visually intricate, like a length scale (aka "ruler"), it will be much easier to create it as an SVG and then set the overall dimension in once place. It is unlikely there is any way to do that with semantic HTML, and in any case that is the hard way.

svg.ruler {
    width: 12in;
    height: 1in;
}
Tom
  • 8,509
  • 7
  • 49
  • 78
  • I think you are not responding to my question. You speak the easy to gather theory from what is printed in the specs, but as I show you with my demonstration, that cm, mm ruler does not even close to match real centimeters on my Lenovo screen. Let alone on my Xiaomi phone. And it would be quite easily possible if only the screen resolution and real screen dimension were being queried by the browser talking through the OS to the device. – Gunther Schadow Oct 12 '22 at 17:49