Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[css-values-4] Flawed definition of the pixel unit #5221

Closed
vwkd opened this issue Jun 16, 2020 · 4 comments
Closed

[css-values-4] Flawed definition of the pixel unit #5221

vwkd opened this issue Jun 16, 2020 · 4 comments

Comments

@vwkd
Copy link
Contributor

vwkd commented Jun 16, 2020

There is a logical flaw in the mathematical definition of the pixel unit in css-values-4. I assume not a lot of people have taken math, but I'm surprised it hasn't been found after it's been in the spec for years since CSS2. I'll try to be as non-mathematical as possible in deriving the pixel unit. But I'll use some basic mathematical notation to describe the flaw, since sentences are inherently vague when describing mathematical relations.


For continuous media the spec defines (or rather recommends) the pixel unit to be

the whole number of device pixels that best approximates the reference pixel.

Good, so the question remains, what is this "reference pixel"? The reference pixel is defined as

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.

This is wrong. The first hint is to notice that an angle is not a length.

According to Wikipedia the visual angle V (deg) is related to the linear size S (in) and the viewing distance D (in) by

V = 2 arctan(S / (2D))

diagram

You don't need to know where the formula is coming from. All you need to understand is the meaning of the variables as seen in the diagram and their units.

Just by logical reasoning, the reference pixel can not be the visual angle since it has the unit length instead of angle. What's it then? Well it can't be the viewing distance for pretty obvious reasons. So what variable is left? Yes, the linear size S. The reference pixel is the linear size for a specific given viewing angle and viewing distance. Mathematically, one could define the reference pixel RP as follows

RP = 2D * tan(V / 2)

The pixel unit is then the whole number of device pixels that closest approximate this reference pixel.

1px = ⌊RP / DP⌋dp

where ⌊⌋ is just the notation to round to the nearest integer.


Now, what values are used for D and V? The spec mixes up the definition of the reference pixel with the derivation of the correct values of D and V. I'll try to motivate where the correct values come from.

Historically 1 pixel was defined as 1 device pixel. Back then, most screens were 96 DPI, and 1 pixel would be 1/96 in. Simple. But since then screen DPI increased rapidly, meaning 1px would get increasingly smaller as the DPIs grows (see the nice pictures in the spec). Hence the need for a pixel unit that is not relative to DPI. It could have been fixed at 1/96 like a physical unit (and is in fact what is recommended for printed media), but screens started being consumed at different viewing distances, e.g. phones vs. projectors. It was desired to make the pixel a unit that also looks the same on any device at its recommended viewing distance. Hence the linear size was used.

But to not change formatting on old 96 DPI screens, we needed to make the new pixel unit the same as 1 device pixel on a 96 DPI screens. This the constraint needed to be able to determine the correct D and V, much like defining the constant term in a polynomial by knowing its y-intercept.

By the formula, a linear size of S = 1/96 in (size of 1 device pixel on a 96 dpi screen) at the viewing distance D = 28 in (arm's length) corresponds to the viewing angle of V = 0.0213 deg.

This value V = 0.0213 deg can be used to determine the size of the reference pixel S for any viewing distance D. And by means of its definition, the it makes sure the reference pixel matches the device pixel on a 96 DPI screens at an arm's length viewing distance (D = 28 in).


The main issue is the flawed definition of the reference pixel as visual angle instead of as linear size, as derived above.

Additionally, the choice of the V value and any recommended D values (e.g. desktops should use D = 28 in, phones maybe half of it, etc.) currently pretty much "fall from the sky" instead of being motivated.

I'm happy to provide a concrete PR, if a fix is desired.


Below are some additional fixes I'd suggest, which appear after reading all of the above. I want to stress, that these are not the main point of the issue and should only be secondary in any considerations (see above).

  1. [Moved above for clarification]

  2. The "recommendation" to define the pixel unit as the closest integer to the reference pixel should be a definition instead.

As long as it's only a recommendation, the pixel unit is strictly speaking not defined by the spec. This is worrying, since UAs could define it to be anything while still being spec compliant.

For the UA to still be able to actually change the value of the pixel unit, the viewing distance of D = 28 in (arm's length) should be made a recommendation instead of a requirement. This would make sense, since a phone isn't held at the same distance as a TV. This is probably already what UAs do, just nobody notices that this is spec in-compliant.

  1. The reason in the following historical note could be clarified.

Note: This definition of the pixel unit and the physical units differs from previous versions of CSS. In particular, in previous versions of CSS the pixel unit and the physical units were not related by a fixed ratio: the physical units were always tied to their physical measurements while the pixel unit would vary to most closely match the reference pixel. (This change was made because too much existing content relies on the assumption of 96dpi, and breaking that assumption broke the content.)

What does "content relies on [..] 96dpi" mean? The physical units could be independent from the pixel unit, no matter what DPI the screen has. I assume the reason was, that people mixed physical units and the pixel unit in their style sheets, expecting the ratio between physical units and the pixel unit to be fixed by the same ratio as on 96 DPI screens. Since the pixel unit is now DPI-relative, so must the physical to not break the constant ratio.

  1. Make physical units again physical

This is a out-of-scope and probably controversial but could join 3. The fact that physical units are actually “non-physical” on non-paged media is regrettable. They should be uncoupled from the device dependent pixel unit. If 1 cm is not 1 cm anymore the cm unit doesn’t make any sense. At least it shouldn’t be named after a worldwide scientific standard that everywhere else denotes a constant value. If you use physical units you should expect that these are physical units. Where else does 1 cm not correspond to one physical cm? I guess the only right choice here is to never ever use physical units for non-paged media and pretend that they don't exist in CSS.

@Loirooriol
Copy link
Contributor

  1. Make physical units again physical

See #614

@fantasai
Copy link
Collaborator

Historically 1 pixel was defined as 1 device pixel. Back then, most screens were 96 DPI, and 1 pixel would be 1/96 in.

This is historically inaccurate. The pixel has always been defined relative to a viewing angle. See the definitions of length units in CSS1 and earlier (pre-2010) versions of CSS2.

The "recommendation" to define the pixel unit as the closest integer to the reference pixel should be a definition instead.
Make physical units again physical

We can't do that.

The physical units could be independent from the pixel unit, no matter what DPI the screen has.

This was CSS's original intention, as you can see from the original texts.

What does "content relies on [..] 96dpi" mean? I assume the reason was, that people mixed physical units and the pixel unit in their style sheets, expecting the ratio between physical units and the pixel unit to be fixed by the same ratio as on 96 DPI screens.

Yes, exactly. See the thread at https://lists.w3.org/Archives/Public/www-style/2010Jan/0058.html if you want to read the actual history of this situation. None of us were pleased with the situation, mind you, but we were constrained by reality. The current spec is the compromise we ended up with.

@fantasai fantasai added the css-values-4 Current Work label Jul 23, 2020
@vwkd
Copy link
Contributor Author

vwkd commented Jul 29, 2020

@fantasai Thanks for the reply.

Interestingly you didn't touch on the main point of my issue, which is the mathematical definition of the pixel unit as linear size instead of as reference angle like it is currently.

It's fine if you disagree with all of my other suggestions how the text could be improved, but at least the (mathematical) definition of the pixel unit should be correct.

I reworded the suggestion list to make the main issue especially clear (previously, point 1), and that the others are only secondary to it (points 2, 3, 4). Also I crossed out point 4, since already from @Loirooriol's previous comment it's clear that it's off the table.

@tabatkins
Copy link
Member

Yes, the reference pixel is a viewing angle. When compared to lengths on a perpendicular surface, then, it represents the length that angle subtends on the surface, given the surface's viewing distance. This is playing slightly loose with terminology, but not in a way that causes any confusion; this sort of viewing angle/surface length comparison is rather common.

The 28" viewing distance is not in any way a requirement. It's used in the definition of the viewing angle, to give an explanation of why the angle is set to the value that it is. The very next paragraph after the reference pixel's definition shows the effect of different viewing distances on the size of the reference pixel (interpreted as a length on a perpendicular surface).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants