Writing in the front

As the title, first to a wave of “soul torture”, PC side also have “1px” question? We usually hear and talk about “1px” issues on mobile, but is there a similar issue on PC? If you can’t answer it right away, or are not sure of your answer, or you have experienced and solved the mobile terminal “1PX” problem, let’s talk about it again from a different Angle today

What is a “1px” question

When developing with a design (usually 2x, or double) and setting a 1px border, the actual display will look thicker than the design (actually twice 1px) and usually appear on mobile

The reasons causing

In short, this is due to the inconsistency between the CSS pixels on the hd screen and the physical pixels (the pixels on the design are the physical pixels)

A concrete analysis

What is HD screen?

What is DPI?

Dots per inch is the number of physical pixels on a screen, so DPI is the same as pixel per inch.

calculation

Ppi = Total diagonal pixels of screen/total diagonal inches of screen (i.e. screen size)

For example, the resolution of the 13-inch MacPro Retina screen is 2560 * 1600, which means the number of horizontal physical pixels is 2560 and the number of vertical physical pixels is 1600. The screen size is 13inch, which means the diagonal is 13inch

Therefore, the screen diagonal total pixel/screen diagonal total inch = (2560 * 2560 + 1600 * 1600) ^ 0.5/13 ≈ 232PPI The figure above shows that the 13-inch MacPro Retina screen is HDPI, which is often referred to as the HIGH-DEFINITION screen

Why is the CSS pixel inconsistent with the physical pixel on the HD screen?

What are CSS pixels?

Let’s start with a quote from the definitive guide to CSS

The CSS specification recommends that if a display type is set differently than 96ppi, the user agent should scale the pixel measure to a “reference pixel.” CSS2.1 recommends 96PPI

When the screen ppi is much larger than 96ppi (as in hd and uhd devices, including most mobile devices and some PCS), the browser scales the display to get the CSS pixel ppi close to 96ppi

Back to the example of the 13-inch Pro, the ppi of the physical pixels on the screen is about 232PPI, and the browser finds that the PPI is much larger than 96PPI, so it scales, and the browser uses 4 physical pixels to display 1 CSS pixel (the ratio can be obtained through windower. devicePixelRatio. This is known as DPR, which in this case is 2), so the PPI of CSS pixels is close to 96 when scaled

So, when we set 1px in the CSS, the 13-inch Pro retina display will be 2 physical pixels wide (4 physical pixels for 1 CSS pixel, pixels are square, so both width and height are 2 physical pixels). However, 1px on the design corresponds to one physical pixel, so the final display effect is thicker than the design, resulting in the “1px” problem

Is there a “1px” problem on PC?

From the above analysis, it can be seen that the root cause of the “1PX” problem is that the PPI of the display device is much higher than the 96PPI indicated in the CSS standard. So obviously there is a “1px” problem on PC, as long as the screen also meets the requirement that ppi is much higher than 96 (like the Retina display in the previous example).

I think there are two main reasons why “1PX” adaption is generally mentioned for mobile devices

  • Modern mobile devices generally use HD screens, a higher proportion than PC devices
  • The total visual area of the mobile device is much smaller than that of the PC, so the visual impact of the 1px display of the design is more obvious than that of the PC

Common Solutions

There are plenty of articles online about specific solutions to the 1PX problem. This article will not go over the details, but will briefly discuss some common solutions and their principles

First of all, it is clear that the browser does not zoom on the non-HD screen (basically 96PPI), so there is no “1px” problem. Therefore, part of the solution needs to perform CSS media query on demand, and determine whether the “1PX” problem needs to be solved according to the device DPR

0.5 px.

The principle of this scheme is relatively simple, mainly depends on whether the browser supports and can accurately display small values. This scheme has poor compatibility, and the actual rendering may still be 1px

Pseudo-element + Transform Scale

The principle of analysis

Border cannot be directly scaled using transfrom, so instead of “masquerade” the border by adding a 1px width or height pseudo-element on the element where the border would have been needed, the pseudo-element is scaled as a whole

div::after {
    display: block;
    content: '';
    height: 1px;
    // 通过scale变换,元素整体缩小一半
    transform: scale(.5);	
}
Copy the code

Pseudo element + gradient background color

The principle of analysis

Again, you “fake” the border by adding a fake element, and then setting the background of the fake element to a gradient from transparent to colored, using the transparent part of the background to narrow the overall look of the element

div::after { display: block; content: ''; height: 1px; // Background: Linear-gradient (#000 50% transparent 50%); }Copy the code

Viewport property for meta tags (mobile)

The principle of analysis

Adding meta tags for mobile devices and setting the viewport’s initial-scale will cause the browser to scale again, so that CSS pixels and physical pixels are regaining

< meta name = "viewport" content = "initial - scale = 0.5" >Copy the code

Scale everything to 0.5 times, and on a device with a DPR of 2, the CSS 1px will change from the corresponding 4 physical pixels to 1px