Pixel densities
Devices of many different screen dimensions dominate today's mobile landscape. Some are small with 4.5-inch screens and others are quite large with 6-inch screens. Tablets, of course, are even larger at 7 inches, 8.9 inches, 10 inches, and so on (the recently released iPad Pro is 12.9 inches).
To further complicate matters, the resolutions of these screens are also very different. The physical dimension of a screen tells you very little about how many pixels it contains—a 4.5-inch screen might have a resolution of 320 x 480 pixels or it might be 640 x 960, or 1280 x 800. Slightly larger screens may have significantly more pixels – a 6-inch phone may have a resolution of 2560 x 1600.
Most developers are used to thinking about pixels as discrete units over which they have direct control. In other words, the developer has the idea that they can determine the color and brightness of each and every pixel on the screen inpidually. While it is indeed possible to control each pixel inpidually, one quickly encounters problems with regard to the size of text and other elements when it comes to rendering web content. There weren't any problems as long as devices used large pixels (corresponding to a low pixel density). But the moment high density displays became popular, web browsers had a real problem. If browsers enforced a 1:1 pixel mapping, then any content that would be easy to read on a desktop display of 1440 x 900 pixels would be exceedingly small on a smaller mobile device with a much higher pixel density. This might not seem like much for very young eyes, but it is usually difficult to read lots of text at extremely small point sizes for extended periods, regardless of how clear or sharp the rendering may be.
Mobile browsers faced a conundrum. They could require users to scale their web pages up to whatever they found comfortable or the mobile browser could scale the site automatically. Mobile browser vendors chose the latter. In order to ensure that websites still rendered with the same layout, mobile browsers also lied to the site by indicating that the screen contained fewer pixels than in reality. The ratio of reported pixels to the actual pixels is called a "scaling factor". Most devices would report an integer scaling factor, often 2:1. Newer devices have such high-density displays that they report 3:1.
This scaling factor or scaling ratio indicates the number of physical pixels contained within each logical pixel. A logical pixel is simply a group of physical pixels combined together into one addressable unit. The developer doesn't necessarily have control over every pixel in the group—this is the device's responsibility. This makes it easy for new devices with different scaling factors to render content reasonably close to how the designer wants it. Text and vector graphics can automatically benefit from the higher density screens, maintaining sharpness. Images, in the worst case, appear a little blurrier (since the device must up-sample the image to fit it on more pixels). Once a pixel density becomes popular enough, the designer can generate a higher resolution image for these particular devices.
Okay, enough words. Some of us are visual learners, so here's a diagram on how this works out:
Note that, at the top, there are three different pixel densities represented by the scaling factor. @3x (alternatively 3:1) indicates the ratio of nine physical pixels to one logical pixel (3 x 3). @2x (2:1) maps four physical pixels to a single logical pixel (2 x 2). Finally, @1x (1:1) indicates that there is a direct one-to-one mapping between the physical and logical pixels.
While working with CSS and HTML, in nearly every case, we'll be working with logical pixels, not physical pixels. The only times when this doesn't completely apply are when we're working with images or when we're working with the HTML5 canvas. We aren't going to be discussing the HTML5 canvas in this book, but we will have to render sharp images on screens with many different pixel densities.
Unfortunately, not all the scaling factors are integers. This means that one logical pixel may not always completely align with the discrete physical pixels. Consider the following image:
Notice how the physical pixels don't fit entirely within the logical pixel? This means that there is no way to ensure pixel perfection; you'll always have some degree of blending, where one physical pixel blends the colors from two logical pixels. On high-density displays (such as the iPhone 6s+), this isn't very obvious, because the physical pixels themselves are very small. But on other displays (such as the 2012 Nexus 7), this becomes very obvious due to the larger physical pixel size. It is at this point that you should recognize that any hope of achieving true pixel perfection is gone, and that you should lay that dream aside. HTML was never about pixel perfection anyway.
Note
This isn't to say that there are no ways of addressing each and every physical pixel—there are. This usually requires a good deal of hard work. It's important to note that even Apple's iPhone 6s+ doesn't render pixel perfect while using native user interface widgets. You have to fall back on OpenGL in this specific example.
The previous image isn't a perfect representation of how the device blends logical pixels into physical pixels. It depends on the device and what logical pixel one is addressing. So, sometimes, it will appear as if a particular line or border isn't being blended, while another line or border will. It just depends on where the logical pixels happen to fall on the physical pixel grid Take a look at the following image – although each line is drawn with a single pixel stroke, depending upon where the line is drawn, different physical pixels are used to render the final result. If the pixels are large, this is pretty obvious.