First, causes

As web projects on mobile become more numerous, designers are becoming more demanding. When you implement a 1-pixel line with 1px on the mobile end, it’s not really a 1-pixel line, it’s a little bit thicker than a real 1-pixel line. 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.

Second, solutions

2.1 Use decimal point

.border { border: 1px solid #999 }@media screen and (-webkit-min-device-pixel-ratio: 2) {. Border {border: 0.5px solid#999 }} @media screen and (-webkit-min-device-pixel-ratio: 3) {. Border {border: 0.333333px solid#999 }
}
Copy the code
  • Advantages: more convenient
  • Cons: supports iOS 8+, not Android.

2.2 Using pseudo-elements

<span class="border-1px"</span> // less. Border-1px {position: relative; &::before{ content:"";
    position: absolute;
    left: 0;
    top: 0;
    width: 200%;
    border:1px solid red;
    color: red;
    height: 200%;
    -webkit-transform-origin: left top;
    transform-origin: left top;
    -webkit-transform: scale(0.5);
    transform: scale(0.5);
    pointer-events: none; /* 防止点击触发 */
    box-sizing: border-box;
    @media screen and (min-device-pixel-ratio:3),(-webkit-min-device-pixel-ratio:3){
      width: 300%;
      height: 300%;
      -webkit-transform: scale(0.33);
      transform: scale(0.33);
    }
  }
}
Copy the code
  • Advantages: Directly through CSS, whether rounded corners or right angles can be achieved.
  • Disadvantages: more code, the possession of the pseudo-element.

Note: Empty elements (elements that cannot contain content) are not supported ::before, ::after

  • Elements not supported by IE include: img, input, SELECT, textarea.
  • Elements not supported by FireFox include input, SELECT, and Textarea.
  • Chrome does not support elements such as input[type=text], textarea.

2.3 use box – shadow

<span class="border-1px"</span>. Border-1px {box-shadow: 0px 0px 1px 0px red inset; }Copy the code
  • Advantages: Directly through CSS, whether rounded corners or right angles can be achieved.
  • Cons: Border lines are lighter than real colors due to the way they are shaded.

2.4 use the border – image

Creating a 1px border is essentially creating a 0.5px border, so we can take an image like this and make “border-image-slice” 2, so that half of the border is actually transparent and we get the “1px border” we want.

<div class="test">1像素边框</div>
.test{
    border: 1px solid transparent;
    border-image: url('./border-1px.png') 2 repeat;
}
Copy the code
  • Pros: Not really…
  • Disadvantages: Modify color trouble, need to replace the picture; Rounded corners require special treatment and the edges can be blurred

2.5 Setting the ViewPort scale Value

Set the viewport according to the device pixel, and the code only needs to write normal pixels.

<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]"); // Set the viewPort according to the device pixelif (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, the 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 a dummy 1 pixel </div> <div class="b"</div> </body> </ HTML >Copy the code
  • Advantages: compatible with all models, directly write 1px can not be more convenient
  • Disadvantages: Suitable for new projects, old projects may be changed greatly,

Three, reference

  • Mobile 1PX solution
  • Summary of 1px border solution
  • Solution to 1-pixel border problem on mobile end