Introduction – the real world
The definition of a pixel is straightforward. It lives in the physical world and is the smallest addressable component of any digital screen. Its job is to emit light – specifically, colour. Screens are made up of thousands of these dots of light and each can be individually assigned a different colour such that when viewed together, the screen displays something that makes sense. A photo, or video for example.
An inch is a similarly simple concept to understand. A standard physical unit of measurement. So standard in fact that you can actually see it using a ruler, in exactly the same way as anybody else with a ruler can.
The challenge – pixel density
So why is it that when I define the length of an on-screen element in pixels using CSS, it doesn’t match the number of aforementioned physical pixels? And why is it that if I define a length in inches and then measure the result with a ruler, that doesn’t match either? The reason is pixel density.
First things first, a pixel resolution is the number of pixels that a display comprises. It’s usually expressed as two numbers – the number of pixels on the horizontal axis, and the number of pixels on the vertical axis. For example, 1920 x 1080 is 2,073,600 pixels. This happens to be the industry accepted number of pixels required for high definition (HD) content. The more pixels a screen has the better its definition, or clarity, will be.
Pixel density refers to the number of pixels that fit into a physical inch of a display. It’s (shockingly) measured in pixels per inch (ppi). As you might infer, all pixels are therefore not the same physical size – otherwise the measure would be redundant. The number of pixels that fit inside one inch would always be the same. In recent years, smartphone manufacturers have fit increasingly large numbers of pixels into devices that aren’t physically too much bigger. The pixel density has increased without the form factor changing a great deal.
Devices of the same size with different pixel densities pose a problem for designers and developers. This is because 200 pixels (or any other number) will look visibly much smaller on a device with a higher pixel density than that of one with a lower pixel density. The difference is so stark in fact that it would render text illegible on newer devices where it was perfectly acceptable on older ones. So, what to do?
A solution – the CSS reference pixel
The World Wide Web Consortium (W3C) identified this challenge very early on. In 1996 in fact (+100 points for forward thinking). For this reason, it recommends in its CSS specification that one CSS pixel does not automatically map directly to one physical pixel, but in fact represents an entirely abstract unit of measurement. When declaring a length in pixels in CSS you are in fact using the CSS pixel unit (px), which might as well be called a yazoo, yellowberry or any other random word. It isn’t directly related to physical pixels at all.
The idea behind the CSS pixel unit is to create consistency across devices with different pixel densities, to solve the 200-pixel problem outlined earlier in this post. The aim is that creating an object of length 200px will just look right on any screen it encounters. How it achieves that is very clever, and hinges on the CSS reference pixel. As you might expect, it has to take into account the physical properties of the display – i.e. how large it is, and in this case also how close to the eye it is held.
It’s beautifully relative – relative to you. Which is ironic considering it’s arguably the primary so-called “absolute” unit of measurement in CSS. The reference pixel is based on a 96ppi display held at arm’s length, assumed to be 28 inches (about the same size as a Flemish Ell – I know you were wondering). This is adjusted for the device you’re using at the time. For example, a computer screen will typically be larger, have a lower pixel density, and be viewed from a further distance than a smartphone will. This makes the reference pixel on the monitor visibly bigger. The illustration below visualises this well.
(Taken from creativepro.com)
If you held the smartphone directly next to the monitor, you would see for yourself that the same number of pixels appears larger on the latter. For those who yearn for a more in-depth understanding, read the next paragraph. If you’re content, feel free to gloss over it.
The CSS reference pixel is actually an angular measurement (see picture below). Specifically, it’s the visual angle of one pixel under the aforementioned conditions – a 96ppi display, at a distance of 28 inches away from the eye.
(Taken from www.w3.org)
A tangent – defining CSS units
So why is a pixel called an absolute measurement in CSS? Well, it is anchored to a fixed reference defined using real world constraints – the reference pixel. Just as inches would be anchored to real world inches, if that’s how they were implemented (you can sense another explanation coming later). In contrast, relative units in CSS are meaningless without another dimension being given. 90% has to be 90% of something to meaning anything. One em has to be based on a font size to mean anything, even if that font size is the default one defined by the browser.
An example – implementing the CSS pixel
But back to pixels. Now we have the CSS reference pixel, we have an anchor for the CSS pixel unit. In reality it means that for devices with higher pixel densities, one CSS pixel maps to multiple physical pixels – and exactly how many is governed by a scaling factor called the device pixel ratio.
By means of an example, I use a OnePlus 2 smartphone. It has a physical pixel resolution of 1080 x 1920. However, if I put this to the test, I see a report of 360 x 640. The device pixel ratio is therefore 3. (360 x 3 = 1080 and 640 x 3 = 1920). My resolution has been scaled by this ratio to implement the CSS reference pixel ideal most closely. And thus, 200 pixels will look correct on my device in just that same way as they would for a device of a much lesser pixel density. Brilliant.
Physical measurements – not what you might think
So what about inches? Well, it turns out that inches aren’t (usually) inches either in CSS. Now, you’d be forgiven for thinking at this point that whoever is naming these things is being intentionally irritating, but things will become clearer in the points that follow.
W3C has specified that if you are viewing your CSS inches on a sufficiently high resolution display (meaning high quality printed output as far as I can prove) then they should indeed reflect reality. And they do – print your web page including a measurement in inches and get that ruler out again. However, if your display is not sufficiently high resolution (meaning anything else including screens, as far as I can tell) then they will not. Instead, one inch will equal 96 pixels. 96 CSS pixel units, that is. Exactly what that magic “high” resolution is doesn’t appear to be openly revealed.
In fact, all physical measurements in CSS are defined in relation to each other, in a fixed ratio. 96 pixels is equal to one inch, which is equal to 2.54cm and so on. For a full rundown have a look at the W3C specification itself.
Another way – density independent pixels
Before we end, it’s worth harnessing this new understanding to examine density independent pixels (dp). This is a different mechanism to the CSS reference pixel, designed for the Android operating system, to solve exactly the same problem – achieving consistency on screens of different pixel densities. It’s simply a different abstraction.
In this case, one dp is defined as looking visually the same as one physical pixel on a screen with a density of 160ppi. A simpler definition, but using exactly the same logic. I.e. set a reference pixel based on constant real world measurements, and then scale displays appropriately to most closely imitate this ideal.
Because the definition is simpler, the implications are a little simpler to understand. For example, 160ppi is considered the baseline (and is called mdpi*). At 240ppi (i.e. 1.5 times the baseline – called hdpi) the scaling factor is 1.5. At 320ppi (i.e. two times the baseline – called xhdpi) the scaling factor is two.
*“mdpi” stands for “medium dpi”, “hdpi” for “high dpi”, “xhdpi” for “extra high dpi” and so on until “xxxhdpi” at the point of writing. Surely not the most sensible naming convention in hindsight. But infinitely scalable in theory I suppose.
Again, this system is put in place to enable Android developers to go about their business without worrying about the hundreds of different pixel density screens their applications may be used on. Android’s very own design guidelines use this same system to provide context.
We’re at the end of our meandering tale of pixels at this point (many congratulations for getting this far). Hopefully its cleared up to some extent why pixels are often not pixels, and in fact the reality that you don’t have to worry about it too much. The sooner you stop worrying the sooner your head will stop hurting. I promise.