Hacker News new | past | comments | ask | show | jobs | submit login
In CSS, “px” is not an angular measurement and it is not non-linear (omnicognate.wordpress.com)
345 points by jipumarino on Nov 4, 2013 | hide | past | favorite | 89 comments



This article makes some good points but it's missing a bit of history. The reference pixel is defined at 96dpi because that's how Windows treated the screen in the days before high-dpi support. Mac OS treated the screen as 72dpi in the pre-retina days but most early websites were built to look correct on Windows. That's why MS Office fonts look too small on the Mac to this day: 26% too small to be precise.

This explains why CSS uses a human-eye based definition of the reference pixel: to escape from the Windows and Mac OS idea of the having a "logical dpi" which differs from the screen's actual, physical dpi. Indeed, Windows and Mac OS can not agree on what an "inch" is!

Go ahead and open up Word and Pages on the Mac and create a 12pt font - see the difference! This is the mess that the CSS reference pixel fixes.


> This article makes some good points but it's missing a bit of history. The reference pixel is defined at 96dpi because that's how Windows treated the screen in the days before high-dpi support. Mac OS treated the screen as 72dpi in the pre-retina days but most early websites were built to look correct on Windows. That's why MS Office fonts look too small on the Mac to this day: 26% too small to be precise.

The only way I can understand this is backwards -- a Windows "pixel" is 1/96 of an inch. (?) A Mac "pixel" is 1/72 of an inch; much larger. Wouldn't a windows font appear too large if displayed on a Mac?


1pt = 1/72 of an inch, therefore a 12pt font is 12 pixels high on a Mac, but 16 pixels high on a PC (12 * 96/72).


Can we abandon these inches and miles please?!


Given that 1 inch is approximately equal to the width of one's thumb, I would have thought that Imperial units are the natural ones to use in this context...


Ah yes, one seventy-twoth of the approximate width of my thumb. No need to fetch my measuring apparatus, dear!


Imperial units are not the natural choice in any case at any time.


Apparently I have very narrow thumbs...


1 cm is about one pinky width.


Do you navigate with your pinky?


Yes. When I have my phone resting on a flat surface in front of me (say, a bar) I use the outside side of my pinky to scroll. I find it very natural since when my arms are in a neutral position in front of me, my palms are facing inwards and my pinkies are therefore closest to the bar (and the phone).

Also if I am eating a sandwich, my pinkies stay the cleanest.


Only in Emacs.


whilst the detachment of 'px' and screen pixels is a no brainer in the modern world with its proliferation of pixel densities and viewing distances on different devices, the CSS standard could probably do a better job of explaining this.


Is it really the place of the CSS standard to define it? Is that even remotely necessary?

I mean, every device is different. You don't want a "px" on your phone to be the same as a "px" on your desktop, which also shouldn't be the same as a "px" on your projector.

A "px", right now, is whatever the device+OS combo wants it to be, but that works, because they all try to make things the "right size" given the device size, resolution, and distance from your eye.

And it works fine. Just accept that "px" is device-defined, and it all works, just like it does now in practice.


> Just accept that "px" is device-defined

Nope! "px" is defined by the CSS spec. The physical pixels are device-defined as is the exact anti-aliasing algorithm but the spec dictates the dimensions of a logical ("px") pixel in the real world. Devices are not free to make "px" whatever they want it to be, because "px" is a logical pixel not a physical one. (Though it is a physical length).

A classic example of why this matters is that Windows treats the screen as 96dpi but OS X treats it as 72dpi. If the CSS spec did not dictate the size of a "px" then all web pages on OS X would look 26% smaller than on Windows.


>but OS X treats it as 72dpi

I just added a 960px <hr> to this web page. On my monitor, attached to a MBP running OS 10.6, it measures about 9.5 inches (by holding up a ruler to the screen). That would indicate OS X treats my screen as about 100 dpi.

The monitor is 30" diagonal, 2560x1600. So, calculating the dpi:

    irb(main):010:0* ratio = 1600/2560.0
    => 0.625
    irb(main):011:0> width = 30.0/Math.sqrt(1 + ratio*ratio)
    => 25.4399491201526
    irb(main):012:0> dpi = 2560.0/width
    => 100.62913207527
One of these days, I'm going to get around to buying a new Retina MBP. Then, I'll try that exercise again.


Yep, that's because it's 960px in CSS pixels, which are at 96dpi. Your monitor also has it's own physical dpi so you can't just measure the length of a line on the screen to infer the OS's dpi.


The article says,

> The way the CSS authors handled this problem (again, sensibly, IMO), was to allow the user agent (ie. the browser) to choose a useful precise size for the “px” unit and then size all the other units relative to that “px” unit.

So I'm a little confused about what you mean when you say, "Nope! "px" is defined by the CSS spec."


According to the article, it's defined as an integer number of pixels approximating 0.265mm (SI). So the size will vary but this is a long way from "whatever the device+OS combo wants it to be."


These are both correct. The CSS 2.1 spec actually defines a CSS pixel ("px") as "the whole number of device pixels that best approximates the reference pixel". It's to allow a little leeway for devices with low-resolution screens. On a high-resolution screen a CSS pixel should be = the reference pixel.


To the best of my knowledge, on iOS, 1 CSS px has been 2 device pixels for a while. Might even be 4 device pixels on Retina devices.


Right, so a CSS pixel is equal to the reference pixel in size.


What would be wrong with that?

The whole point of HTML/CSS is that you don't get to design pixel-perfect layouts (use something like PDF for that). The device is free to reflow pages and layouts as it sees fit. If OSX users prefer to see web pages as smaller than windows users, why not just let them?


The px would look larger on a screen with the lower dpi


That's not the case here because we're talking about CSS pixels and not physical pixels. A CSS pixel is 0.75in and an inch on Windows is 96 physical pixels but on Mac OS it is only 72 physical pixels.


No, you said: "If the CSS spec did not dictate the size of a "px" then all web pages on OS X would look 26% smaller than on Windows"

My point is that they would look larger on OS X (lower dpi == larger pixels)


  > You don't want a "px" on your phone to be the same as a
  > "px" on your desktop, which also shouldn't be the same
  > as a "px" on your projector.
Of course you do. How will you get pixel-correct rendering when the browser is reinterpreting the meaning of a pixel?


how do you get pixel correct rendering when you dont know the pixel aspect ratio?


Accept that your site will only render correctly on devices with square pixels, and that {old TVs, mis-calibrated CRTs, fun-house mirrors} will not render your document correctly.


But pixels are not perfectly square, and not visible on >300 ppi devices? I think we should accept that you can't rely on pixels anymore, and it's a good thing, which will let us move on to better display technologies and better, vector, graphics. When you do that, and if you want, make vector squares, you can let the rendering layer 'snap to grid' for rendering your pseudo-pixels.


Vectors have to be rasterized at some point, which requires detailed knowledge of device pixels.

Furthermore, some graphics are always going to be bitmaps, such as photos. Tasks like "center this image square, but don't make it blurry" requires pixel-perfect positioning.


That's exactly my point. Only the mobile OS knows the detailed knowledge of device pixels, not a web developer. Raster graphics can utilize GPU accelerated filtering. Sharp graphics should be vector with blocky or any other kind of 'hinting' that you might want.


Then what about high-DPI devices? Should they just render it really tiny? Should your content look 25% the size on a retina MBP?


Given two displays with identical dimensions, where one has twice the DPI of the other, then a square specified to be "width: 400px" should be physically half the size on the higher-DPI screen.

Designers who want to render at a particular size (e.g. for buttons that a user will push) should specify sizes in physical dimensions, such as inches or cm.


What about the fact that we have dpi's going from 250 to 450, everywhere in between? We have color temperature problems, we have totally different screen aspects sizes. Between all the things we can't control, why is it still a good idea to render with pixel accuracy?


> specify sizes in physical dimensions, such as inches or cm.

So a one inch square button on my two inch wide phone will also be one inch wide on my 10 foot projector?


Defining dimensions in inches, cm or points for screen use is a big bag of hurt that should be avoided at all costs.


maybe it doesn't have to, but it does and does a poor job at it


px is short for pixel, and should mean pixel. (Then nobody should use it). They should have chosen a better name.


The rationale in the article was perfectly reasonable to me. A px should be a physical pixel or whatever integer multiple makes for comfortable viewing, with all the other measurements allowed to be non-integer. Anything sized in px would then be both sensibly sized and scaled with good fidelity.


I agree about the word pixel being mis-named. But what if I really do what to draw something in pixels?


HTML was never intended to let you draw with that level of precision. It should still do something more sensible than arbitrary scaling if every link in the chain implements things as intended.


Don't really understand why is it such a big deal how browsers internally define the size of pixels, do they use dpi or angles (it would be more correct to say trigonometry)? It is an interesting fact that I've never before really gave a thought, but complete irrelevant to anyone but guys building the browser rendering engines. And still now you have people calling for new "better" units and what not? Why? What am I missing?


It is really helpful if you are web developer. For instance, if you need to alter some layout that was made some other units, it is good to know how the units relate to one another.


yes, sure, but this is not about that, all CSS unit have the fixed relations clearly defined. Angular pixels are just about relative scale between the size on the screen and the real-world size (whatever that would be, because a print size is again relative to the chosen dpi, so it's not an absolute measure)


> (it would be more correct to say trigonometry)?

No


Here we go again. IMHO, we need a new unit to unambiguously describe angular measure. But also we need to start demanding resolution independent units that map to real world measurements as well.

https://news.ycombinator.com/item?id=4236429


...except you need to know how far a user's eyeballs are from the screen to do that. Each eyeball will have a different answer.


FWIW, you'd need some profile spec to constrain the problem of what eyeball distance you're looking from. One approach might be to define profiles for desktop, mobile, and projector distances. Is it meant to be accurate? No. But it can stop people from trying to munge angular measures with distance measures.


> we need a new unit to unambiguously describe angular measure.

That's a nonsense unit. You'd need to know where my eyeballs are and change the measure as I move my head around! What happens if two people are looking at the screen?

> we need to start demanding resolution independent units

That's what CSS pixels are. A pixel is 0.26 mm, period.


> That's what CSS pixels are. A pixel is 0.26 mm, period.

For some definition of "mm". Did you read the part about "anchoring"?


Right but that's just "for lower-resolution devices", i.e. devices with a resolution lower than the reference pixel. There's no use demanding to have units of measure which the device is incapable of displaying! What possible use would it serve?


So should you just use em for everything?


em or relative font-sizing seems like a good choice. Also see rem [1] which was introduced with CSS3 to combat issues with font size compounding. Use pt for print stylesheets [2].

For a bit of ancient internet history: http://style.cleverchimp.com/font_size/points/font_wars.GIF

[1] http://snook.ca/archives/html_and_css/font-size-with-rem

[2] http://www.w3.org/Style/Examples/007/units.en.html


The rem unit is awesome! All the benefits of em (relative to browser text zoom level) combined with the benefits of px (does not change depending on parent element font size).

If you don't need to support IE8 you should start using rem today.


But note that px is also relative to the zoom level, as unintuitive as that sounds.


Not to the text zoom level.


modernizr + css-remunit polyfills and you can start using rem today. :)


Not everything - this article is wrong that CSS defines em as being based on "m" [1] (includes actual quote [2] from w3c spec)

[1] http://stackoverflow.com/a/4531441/1971539

[2] The 'em' unit is equal to the computed value of the 'font-size' property of the element on which it is used. The exception is when 'em' occurs in the value of the 'font-size' property itself, in which case it refers to the font size of the parent element. It may be used for vertical or horizontal measurement.


I'm the author of the article (the reponse not the original). I didn't say em is based on "m". All I said about em is:

"(For completeness, I should mention here that the "em" and "ex" units are exceptions to the above. The lengths 1em and 1ex do vary relative to the other units, because they depend on the font in use.)"

I'll update this to say "font size" as I didn't mean to give the impression that it was dependent the choice of font.


I was nit picking to be fair. But font size certainly does clear up the ambiguity.


No. Because if you do, when you want to slightly adjust the font size, suddenly nothing fits on your page, and you have to fix the sizes of all the boxes.

Use em when you don't care about the exact size, you just want some space.

Em is also a poor choice for borders.


We spent time juggling between em and px before but from few months we are using "rem" unit.

It works nicely as we are also using font-icons everywhere.

See: http://snook.ca/archives/html_and_css/font-size-with-rem


Most of our problems would go away if mm was actually a mm and the dpi differences were taken care of by the OS + screen + browser... Ugh. Sounds like we're stuck with inconsistency for various dpi devices for many years to come still :-/


The reason the standards don't speak of 2D euclidean geometry is because they (Very sensibly, IMO) left room for yet unknown devices that might not fit that description but still are able to conform.


Key takeaway: "1px is always equal to 0.75pt."


This response is taking issue with the words used, rather than the underlying claim of the original article. In fact, this response contains a whole section and a diagram which are effectively supporting evidence for the original!

The most important thing to take away from the original is that the css unit "px" has no relationship to the actual size of a pixel on the screen, and all the physical units (inch, cm, pt) are defined in terms of the csspixel. So marking a button as "width: 1cm" will almost never render something over 1cm of the screen geometry.

Incidentally, this is why designers like device models with only a few geometries, such as the iPhone. They can do the math themselves to work out how many iphone-pixels are in a cm, and write their styles accordingly.


It doesn't seem like you've actually read the article in its entirety, then (I can't blame you, it was very long but also very well written).

The author addresses 1) the counter-argument 2) an explanation for the "angle" wording (the section with the diagrams) which did a much better job of explaining the purpose of the angle than the "px is a non-linear angular unit" article, and 3) a line-by-line reasoning for why that other article was confusing (or outright wrong).

All of these sections made more sense than the other article, and in fact established why the points made by the two articles are very different and why it would make no sense for the px unit to be either "angular" or "non-linear".


Hi, I wrote this article (the response, not the original). though I didn't post it here - I just noticed the pingback email.

I am indeed responding mainly to the wording, and you'll see at the start and end of the article statements that I think the original author does at least kind of understand what is going on (though I don't think his understanding is very solid).

Your statement that 'the css unit "px" has no relationship to the actual size of a pixel on the screen' exemplifies why I am concerned about the wording and thought it necessary to write a response. This statement is just not true!

The CSS px unit was carefully designed to embody as closely as possible the intuitive concept of a "monitor pixel", while retaining sufficient flexibility to allow implementors to accommodate a wide range of devices. The whole concept of unit anchoring was invented to support this. To pretend the px unit has no relationship to actual pixels is to waste all of this work.(*)

I would suggest people aim for one of two levels of understanding:

1. Really understand the rules. Read the standard, and/or a proper CSS book like "Cascading Style Sheets: The Definitive Guide" by Eric Meyer. Be an expert and design with confidence.

2. Altenatively, just think of 1px as a monitor pixel. The standards authors put a lot of effort in to allow people to do so.

For people that are currently in state 2 and are uneasy about retina displays, printers and the rest, my advice would be that they are going to need to go to state 1. It's not that hard. Just getting a vague idea (as many people are) that "px" is angular, or worse that it's in some way "unreliable", is not going to help anyone.

[PS. Here's an ironic aside about the lengths people have gone to to make 1px correspond as closely as possible to a real pixel: As you say, 'marking a button as "width: 1cm" will almost never render something over 1cm of the screen geometry'. But why exactly is this? It's because the whole system of units has been anchored to the screen pixel size (or a simple multiple or fraction of it). On a printer, where there is no "pixel" worth anchoring to, the units are typically anchored to physical units, and width: 1cm really does mean 1cm. The reason that on your monitor screen 1cm is not 1 real cm is because your browser is resizing everything - it's bending over backwards to make 1px match the screen pixel size! (or a simple multiple or fraction yadda yadda yadda...)]


  > The CSS px unit was carefully designed to embody as
  > closely as possible the intuitive concept of a "monitor
  > pixel", while retaining sufficient flexibility to allow
  > implementors to accommodate a wide range of devices.
The closest match to the concept of a "monitor pixel" is a unit which represents one pixel. In other words, an element styled as "width: 100px" would be 100px wide regardless of the size of each individual pixel.

The issue with declaring that one csspixel is a monitor pixel is that it's only true for a very narrow range of monitors. It's not true for my phone, or my tablet, or my laptop, or my desktop. There is not a single machine I own for which 1 css pixel is 1 monitor pixel, and that situation is unlikely to change unless I decide to start building my machines with ancient 96-DPI LCDs.

  > On a printer, where there is no "pixel" worth anchoring
  > to, the units are typically anchored to physical units,
  > and width: 1cm really does mean 1cm. The reason that on
  > your monitor screen 1cm is not 1 real cm is because
  > your browser is resizing everything - it's bending over
  > backwards to make 1px match the screen pixel size!
No, it's not. My browser is bending to make "width: 1px" match some arbitrary size defined in the CSS spec, which is nowhere near the size of a pixel on my machine.

The browser is entirely capable of rendering css pixels as screen pixels, obviously. It's also capable of rendering with real-world sizes, by querying the physical size of the display from the OS and dividing by the current display resolution. But it doesn't do any of those things, because someone on the CSS committee wrote the equivalent of "pi = 3".


HTML+CSS is designed to make things as device-independent as possible. If the definition of "width: 100px" were to be vastly different on different devices this goal would be unobtainable. As long as the definition of px is some integer multiple of device pixels I think it's a useful compromise. If you really need precision at the level of device pixels you should be writing a native app.


It's a useful compromise for the OS to make, but does not belong in CSS. If I'm running on a non-native resolution, I expect the image containers to scale on websites to fit the images, which they won't if the browser overrides my 1.4 pixel pixels.

Whatever did happen to screen pixels, anyway? Did non-native resolutions die with CRT screens? It's nice to have a unit for 0.27 mm-ish, but I'd really have more use for a pixel.


Thank you for the wonderfully well-written and thoughtfully considered article. It was a pleasure to read!


Can you give us a real world example of how this technical mis-understanding would affect my day-to-day design process? Specifically, I haven't ever encountered or designed for a screen yet that extends beyond my peripheral vision. I'm sure they are coming soon though!


It might not, TBH, but why carry around an incorrect technical notion that gives you no benefit, even if it doesn't cause you any problems in practice? Maybe my view on this is skewed by the fact that I'm a developer, not a designer...

That said, there are problems that could occur. The main reason to need pixel sizes for things (NOT fonts) is to avoid aliasing effects. For example, 1px is the smallest width you can reasonably make a border. Any smaller and on some devices you may find your border sometimes disappears entirely (aliasing) or is displayed faintly (antialiasing). Any larger and your border may be fatter than it needs to be. If you spurn px entirely (as some people appear to do) how are you going to get this magic length? By saying "0.265mm", perhaps? But that's just another way of saying "1px"!


>If you spurn px entirely (as some people appear to do) how are you going to get this magic length?

You use a high-resolution screen such that 1 pixel is too small to make a line, and on lines thick enough to be visible the effects of antialiasing are subtle enough to ignore.


This assumes that you get to choose the resolution of the screen, which is a luxury web designers don't generally have!


Well there's not really any other way to ensure crisp rendering. A user with a low resolution screen, even if 1px equates to an actual pixel on their device, might have web pages zoomed in by 15% or out by 10%, breaking all attempts to avoid antialiasing.


This happens when a developer and designer start talking about pixel sizes... ;)

I'm a developer, so: yes, zoom will break things. but the users (usually) notice this and (sometimes) know how to correct it.


How many px is 180 degrees then? or even 75 degrees? Obviously it doesn't work because degrees aren't linear and px are linear. That's the point of the article - confusing angles and px is a very bad move that might appear to work until it doesn't.


What do you mean, degrees are not linear? I'm a mathematician, and I think they are inarguably linear, so I'm assuming we're using different definitions of "degrees" or of "linear".

Edit: By any chance, do you mean "the projection of an angle measured in degrees on a straight line measured in {cm/m/whatever} is not linear"?


That is exactly what he means. I guess it might have been explained better in the comment, but that's the whole point the article is making: that the "reference pixel" for a given display is calculated by taking a certain visual angle (based on a specified DPI/distance) and projecting it onto a perpendicular surface at the expected viewing distance.

If the reference pixel is the viewing angle then multi-pixel measurements don't map linearly to on-screen sizes unless the screen they're designed for is the concave face of a sphere centred on the user's eye


As I understand this article (and my long-past reading of the spec), the only thing in the spec that talks about visual angle is the part about defining the size of one reference pixel. That's a very small angle, and at those sizes angular size is essentially linear even when projected onto a flat screen.

Nothing that I've seen in the spec ever remotely suggests using angular measurements for more than one pixel at a time, let alone enough of them for 90 or 180 degrees of the visual field.


>and at those sizes angular size is essentially linear even when projected onto a flat screen.

But not quite, and summed over many pixels, it will result in a noticeable discrepancy (which is still of no practical consequence). I wonder how it would feel to use a computer that used head tracking to dynamically transform the screen's contents so that pixels were mapped to equal angular size (from the point between the user's eyes).


That's all completely true, but the article that this linked article is a response to didn't draw that same conclusion from the spec, and that's what started this whole mess


> The most important thing to take away from the original is that the css unit "px" has no relationship to the actual size of a pixel on the screen

Did you read this article?

Did you make it to this part?

    I’ll just finish by going through a few of the explicit
    claims made in that article and correcting them:

    [...]

    2. The first sentence: “The “px” unit in CSS doesn’t really
    have anything to do with screen pixels, despite the poorly
    chosen name.” – this is obviously complete nonsense. The
    standards authors went out of their way to give browser
    authors a way to match the “px” unit up to the real-world
    device pixel
> and all the physical units (inch, cm, pt) are defined in terms of the csspixel.

Not for print and other high-res devices (like a Retina display). Did you read this excerpt quoted from the CSS spec?

    For print media and similar high-resolution devices, the
    anchor unit should be one of the standard physical units
    (inches, centimeters, etc). For lower-resolution devices,
    and devices with unusual viewing distances, it is
    recommended instead that the anchor unit be the pixel unit.


The article also mentions that on some devices, the anchor unit is cm and not px. So on those devices setting something to 1cm should render the item at an actual cm in size.


Agreed. Everyone sees the term pixel and thinks it will match a device pixel. This isn't true. The CSS pixel is sized to take up a certain amount of the visual field due to that diagram with a reference screen, distance, and density. The person writing about angular stuff is dead on target explaining to people the difference.

The author of the linked article is just nit picking word choice and confusing the issue. No one was applying this past that to then come to the claim the pixel size changed at different degrees, which is the implication that the author of this article seems so upset about. Everyone knows the CSS pixel stays the same size across the entire screen, we don't need to discuss that. We certainly don't need enormous articles like this written to correct a problem no one had.

Although overall the spec is really the offender since they never should have called this a pixel.


> No one was applying this past that to then come to the claim the pixel size changed at different degrees, which is the implication that the author of this article seems so upset about. Everyone knows the CSS pixel stays the same size across the entire screen, we don't need to discuss that. We certainly don't need enormous articles like this written to correct a problem no one had.

Actually I think this article was (re?)posted in response to another article[1] that made the front page today[2] which did claim that pixels were angular measurements. So certainly some people have had that problem

To be honest, since this article is from January this year and the other is (seemingly) from 2009 I'm not sure why it's come up today, but that's the Internet for you!

[1]: http://inamidst.com/stuff/notes/csspx [2]: https://news.ycombinator.com/item?id=6668395




Consider applying for YC's W25 batch! Applications are open till Nov 12.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: