The basic concept

Physical pixels, device-independent pixels, CSS pixels, resolution, PPI, and devicePixelRatio differences

  • Physical pixels, also known as device pixels
    • The smallest physical unit of a display. The size does not change, the physical pixels do not change from the moment the display comes out of the factory.
    • The iPhone 6 has a resolution of 750 x 1334, so 750 is the physical pixel of 750, which has not changed since the phone left the factory. 750 is the width of the phone 750px. This should make a little bit of sense.
  • Device independent pixel
    • Device-independent pixels, also known as logical pixels, are relative in size. Is a physical unit of measurement based on a computer-controlled coordinate system and abstract pixels.
    • A device may contain one or more physical pixels in individual pixels, and the more pixels there are, the clearer the screen looks.
  • Pixel resolution
    • Taking the mobile phone screen as an example, the pixel resolution of iphoneX is 1125×2436, which means that the screen can display 1125 physical pixels horizontally and 2436 vertically. A 4K display is usually referred to as 4096×2160.
  • PPI
    • Number of physical pixels per inch. The screen size is 5.8 inches (diagonal length) and the resolution is1125x2436Take the iphonex for example.Ppi = math.sqrt (1125*1125 + 2436*2436) / 5.8, a value of 463 ppi
  • CSS pixel
    • A pixel is a unit, not a point
  • devicePixelRatio
    • Window. devicePixelRatio refers to the ratio of device physical pixels to device-Independent pixels (DIPs).Window.devicepixelratio = Physical pixels/device-independent pixels (DIps). The iPhone X’s devicePixelRatio is calculated to be 3.

Size difference

Get screen size (device-independent pixel value) :

screen.width
screen.height
Copy the code

For example: iPhoneX: 375 * 812 Get window size (CSS pixels) : for example: iPhoneX: 375 * 812 include scroll bar

window.innerWidth
window.innerHeight
Copy the code

Does not contain scroll bars

document.documentElement.clientWidth
document.documentElement.clientHeight 
Copy the code

Take the HTML element size (content) :

document.documentElement.offsetWidth 
document.documentElement.offsetHight
Copy the code

1px

In HD, 1px on mobile will be thick. For example, this is a fake 1 pixel

This is real 1 pixel

The reasons causing

So why is this a problem? It has to do with one thing, DPR(devicePixelRatio), which is the ratio of device pixels to CSS pixels when the default scaling is 100%.

Window. devicePixelRatio= Physical pixel /CSS pixelCopy the code

The current mainstream screen DPR=2 (iPhone 8), or 3 (iPhone 8 Plus). For a 2x screen, the physical pixel of the device needs to be 1 pixel and the DPR=2, so the CSS pixel can only be 0.5. The 1px is 750, and the CSS style is 375, so we should write 0.5px. IOS 8+ is supported, Android is not.

The solution

1. WWDC’s overall plan for iOS

Recommended index :**

At WWDC, the 1px scheme was given, and when written at 0.5px, a physical pixel-width border was displayed instead of a CSS pixel border. So on iOS, you can write it like this.

Border: 0.5 px solid # E5E5E5Copy the code

You might ask why it’s not 0.3333px at 3 times? In my tests, I simulated the iPhone 8Plus on Chrome and found that it didn’t show up below 0.46px.

Conclusion:

  • Advantages: Simple, no side effects
  • Cons: supports iOS 8+, not Android. Later Android Follow is good.

2. Use border images

Recommended index :**

border: 1px solid transparent; border-image: url('./.. /.. /image/96.jpg') 2 repeat;Copy the code

The color of the image is the color of the border thereafter

Examples of this method on W3CPlus speak very detailed www.w3cplus.com/content/css… .

Conclusion:

  • Advantages: No side effects
  • Disadvantages: border color changes, need to rework the image; Rounded corners tend to blur.

3. Use box-shadow

Recommended index :***

For a review of box-shadow, check out this article on MDN developer.mozilla.org/zh-CN/docs/… . And let’s see what happens

How does the code work?

box-shadow: 0-1px 1px 1px #e5e5e5, // Top line 1px 0 1px -1px #e5e5e5, // right line 0 1px 1px -1px #e5e5e5, // bottom line -1px 0 1px -1px #e5e5e5; / / the left lineCopy the code

The first two values x and y mainly control which edge to display, while the latter two values control the shadow radius and extension radius. Actually the method can go to this address line to try.

conclusion

  • Advantages: Easy to use, rounded corners can also be achieved
  • Disadvantages: analog implementation method, look carefully who can’t see that this is a shadow not a border.

4. Use pseudo-elements

Recommended index: ****

This method is the one I use the most, and the result is very good, directly into the code.

Article 1 the border

.setOnePx{ position: relative; &::after{ position: absolute; content: ''; background-color: #e5e5e5; display: block; width: 100%; height: 1px; / * no * / transform: scale (1, 0.5); top: 0; left: 0; }}Copy the code

As you can see, set the pseudo element to be absolutely positioned and aligned with the top left corner of the parent element, set width to 100%, height to 1px, and then shrink it by 0.5 times in the Y direction.

Article 4 the border

``` .setBorderAll{ position: relative; &:after{ content:" "; position:absolute; top: 0; left: 0; width: 200%; height: 200%; The transform: scale (0.5); transform-origin: left top; box-sizing: border-box; border: 1px solid #E5E5E5; border-radius: 4px; }} ' 'also sets absolute positioning for the pseudo-element, and aligns it with the upper-left corner of the parent element. First enlarge the length and width of the pseudo-element by 2 times, then set a border, with the top left corner as the center, and scale to the original '0.5 times'Copy the code

Conclusion:

  • Pros: Full compatibility, true 1px, and rounded corners.
  • Disadvantages: Temporary after pseudo-element, may affect cleanup float.

5. Set the viewport scale value

Recommended index: *****

This solution is implemented using ViewPort + REM + JS. Refer to an example on the Internet mobile terminal 1 pixel border problem solution, their own manual implementation.

It worked well. In the code

<html> <head> <title>1px question</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="viewport" id="WebViewport" content="initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"> <style> html { font-size: 1px; } * { padding: 0; margin: 0; } .top_b { border-bottom: 1px solid #E5E5E5; } .a,.b { box-sizing: border-box; margin-top: 1rem; padding: 1rem; The font - size: 1.4 rem; } .a { width: 100%; } .b { background: #f5f5f5; width: 100%; } </style> <script> var viewport = document.querySelector("meta[name=viewport]"); Viewport if (window.devicepixelRatio == 1) {viewport.setattribute ('content', 'width=device-width,initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no'); } if (window.devicepixelRatio == 2) {viewport.setattribute ('content', 'width=device-width,initial-scale=0.5, Maximum - scale = 0.5, the minimum - scale = 0.5, user - scalable = no "); } if (window.devicePixelRatio == 3) { viewport.setAttribute('content', 'width = device - width, initial - scale = 0.3333333333333333, the maximum - scale = 0.3333333333333333, Minimum - scale = 0.3333333333333333, user - scalable = no "); } var docEl = document.documentElement; var fontsize = 32* (docEl.clientWidth / 750) + 'px'; docEl.style.fontSize = fontsize; </script> </head> <body> <div class="top_b A "> The bottom width is virtual 1 pixel </div> <div class="b">Copy the code

conclusion

  • Advantages: compatible with all models, write directly1pxCouldn’t be more convenient
  • Disadvantages: suitable for new projects, old projects may be changed

conclusion

To sum up, the best new project to use is to set the scale value of the viewport, this method is good compatibility, easy to write later. For the old project, it may be a lot of changes, and the most common method is the pseudo-element +transform method. Other background images, the shadow method is still not flexible, and compatibility is not good.

The original