In the mobile end Web development, the UI design draft sets the border as 1 pixel. If border:1px appears in the front end development process, the test will find that 1px is relatively thick on some models, which is the classic 1px pixel problem on the mobile end. First take a look at the 1px comparison between the PC era and mobile era.

First, the understanding of pixels

Pixels are the foundation of web layout. A pixel is the smallest area that a computer can display a particular color. When devices are the same size but more densely populated with pixels, the transitions on the screen are more detailed and websites look brighter.

1, the device pixels

Device pixel: The smallest physical unit of the display screen. Each DP contains its own color, height, width, etc., and cannot be subdivided. Device pixels are set at the factory, and the size and quantity of the device will not change once it is built. The official specification for the product says 1920×1080 means physical pixels.

2, dpi

Device-independent pixels: DPI (Dots Per Inch) is a measure of the number of points sampled, displayable, or output Per Inch of length. Pixels per inch is similar to density, which is the number of pixels per inch.

3, CSS pixels

It’s a unit of pixels that CSS and JS understand, and it doesn’t necessarily depend on the pixels on the screen of a device, like a Desktop monitor in Windows, and when you change the hardware resolution of the monitor, say, from 1920 to 1024, you’ll find that the graphics and fonts on a web page become very, very large, and the same monitor, Instead of displaying the entire page, it now displays only half the width, which means CSS pixels are bigger. So CSS pixels are arbitrary units that can be tuned by hardware and software. CSS pixels are device logic independent and are used to logically measure the units of pixels. CSS declarations and almost all javascript attributes use CSS pixels.

// Logical pixel pxwidth: 250px;
font-size: 22px;
Copy the code

4, DPR

DevicePixelRatio DPR = device pixel/CSS pixel (in a certain direction) you can use window.devicePixelRatio to obtain the DPR value of the device. Generally speaking, in a desktop browser, the device Pixel ratio (DPR) is equal to 1, and a CSS pixel is a physical pixel. On the mobile end, most models are not 1, and the DPR of iPhone is generally 2 and 3, so one CSS pixel is no longer corresponding to one physical pixel, but 2 and 3 physical pixels. The usual CSS width: 1px corresponds to 2px in a physical pixel. DPR may be different depending on the phone model.

Take iphone5 for example, the CSS pixel of iphone5 is 320px*568px, and the DPR is 2, so the device pixel is 640px*1136px

640(px) / 320(px) = 2
1136(px) / 268(px) = 2
640(px)*1136(px) / 320(px)*568(px) = 4
Copy the code

5, DP (device pixels)

Device pixels (physical pixels), as the name implies, the display screen is composed of physical pixels. By controlling the color of each pixel, the screen displays a different image. The physical pixels on the screen are fixed from the day the screen comes out of the factory, and the unit is PT.

Pt is a real absolute unit in the CSS. 1pt is 1/72(inch), and 1 inch is 2.54 cm.

6. Viewport

The part of the browser (or webView in your app) that displays the web page. The industry has come up with three sub-concepts.

  • Layout viewPort:

    In order to accommodate a site designed for desktop browsers, the default layout viewPort width is much wider than the width of the screen, so that users can see the whole site, small site. For example, Apple typically sets the viewPort width at 980px. The main implication is that phone makers don’t make their phones look ridiculous, and can scroll across pages larger than 980 widths without getting jammed. Through the document. The documentElement. ClientWidth to obtain.

  • Visual ViewPort:

    The viewable area of the screen, the physical pixel size, can be obtained with window.innerWidth. For iPhone 6 Plus, the value is 414px with the famous code and 980px without it. If the famous code is changed to device-width and initial-scale=1.5, the value is 276px. So it’s a variable value.

  • Ideal Viewport:

    Viewport ideal ViewPort width is equal to the screen width of the mobile device

    To make the viewPort equal to the Ideal Viewport, we usually add a meta tag. Width =device-width,initial-scale=1.0 For the iPhone 6 Plus, it’s fixed at 414px. Therefore, the ideal viewport is equal to the device width.

<meta name="viewport" content="Width = device - width, initial - scale = 1.0, user - scalable = no"/>
<! --width=device-width -->
<! --initial-scale: 1-->
<! --user-scalable=no: whether to allow user scalable scaling -->
Copy the code

Second, mobile terminal 1PX solution

1. Small value px

solution

<body>
    <div id="main" style="border: 1px solid #000000;"></div>
</body>
<script type="text/javascript">
    if (window.devicePixelRatio && devicePixelRatio >= 2) {
        var main = document.getElementById('main');
        main.style.border = '.5px solid #000000';
    }
</script>
Copy the code

Advantages:

  • Simple, easy to understand

Disadvantages:

  • Tolerance is poor, the current IOS8+ only support, in IOS7 and below, Android is display 0px.

2, the border – image

Use the background image

\

Code:

.border-image-1px {
    border-width: 1px 0px;
    -webkit-border-image: url(border.png) 2 0 stretch;
    border-image: url(border.png) 2 0 stretch;
}
Copy the code

Advantages:

  • Images can be used in GIF, PNG, base64 formats, the above is the writing method of the top, bottom, left and right four borders, need a single border as long as the definition of a single border, the code is more intuitive.

Disadvantages:

  • Inflexible size and color changes
  • The border is a bit blurry when you put it in Photoshop (since the colored part is 1px, it will definitely be blurry when stretched to 2px on retina display)

3. Background-img gradient

Set the gradient background to 1px, with 50% color and 50% transparency

.border {
    background:
    linear-gradient(180deg, black, black 50%, transparent 50%) top    left  / 100% 1px no-repeat,
    linear-gradient(90deg,  black, black 50%, transparent 50%) top    right / 1px 100% no-repeat,
    linear-gradient(0,      black, black 50%, transparent 50%) bottom right / 100% 1px no-repeat,
    linear-gradient(-90deg, black, black 50%, transparent 50%) bottom left  / 1px 100% no-repeat;
}
Copy the code

4, CSS 3 box – shadow

.shadow {
    -webkit-box-shadow:0 1px 1px -1px rgba(255.0.0.0.5);
    box-shadow:0 1px 1px -1px rgba(255.0.0.0.5);
}
Copy the code

Simulation effect: do not think this method is easy to use, the simulation effect is not satisfactory, color is not recommended

5. Combine ViewPort and REM

Viewport and REM solve the pixel ratio problem

For example, set meta on devicePixelRatio=2

<meta name="viewport" content="Initial - scale = 0.5, the maximum - scale = 0.5, the minimum - scale = 0.5, user - scalable = no">
Copy the code

Set meta on devicePixelRatio=3

<meta name="viewport" content="Initial - scale = 0.3333333333333333, the maximum - scale = 0.3333333333333333, the minimum - scale = 0.3333333333333333, user - scalable = no">
Copy the code

This scheme uses Flexible to achieve terminal adaptation of H5 page

6, :before:after and transform

The principle is to remove the border of the original element, then use :before or :after to redo the border, and reduce the scale of the transform by half. The original element is positioned relative to the original element, and the new border is positioned absolutely.

Single border style set:

.scale-1px{
     position: relative;
     border:none;
 } 
.scale-1px:after{
     content: ' ';
     position: absolute; 
     bottom: 0; 
     background: # 000; 
     width: 100%; 
     height: 1px;
     -webkit-transform: scaleY(0.5); 
     transform: scaleY(0.5); 
     -webkit-transform-origin: 0 0; 
      transform-origin: 0 0; 
}
Copy the code

Four border style Settings:


.scale-1px{ 
    position: relative; 
    margin-bottom: 20px; border:none;
} 
.scale-1px:after{ 
    content: ' '; 
    position: absolute;
    top: 0; 
    left: 0;
    border: 1px solid # 000; 
    -webkit-box-sizing: border-box; 
    box-sizing: border-box; 
    width: 200%; 
    height: 200%; 
    -webkit-transform: scale(0.5); 
    transform: scale(0.5); 
    -webkit-transform-origin: left top; 
    transform-origin: left top; 
}
Copy the code

Combine js code to determine if it’s Retina

if(window.devicePixelRatio && devicePixelRatio >= 2) {document.querySelector('div').className = 'scale-1px';
}
Copy the code

Advantages:

  • All scenarios can be satisfied
  • Support the rounded

Disadvantages:

  • For elements that already use pseudo-classes, multiple levels of nesting may be required

conclusion

  1. 0.5px, I believe browsers will support it slowly; For now, hack if you can;
  2. Shadow, border-img scheme is not recommended
  3. Background images and zooming can be used together in a project, for example, a single line can be zoomed, and four boxes can be simulated with a background image
  4. Transform and pseudo-classes are recommended