I met a 1 px
It has been a while since I learned the front end direction. At the beginning, I did some projects, but I always found that my frame would be thicker after I finished it. After browsing some materials, I gradually understood this problem and listed several solutions.
Cause the border is thicker
There is a devicePixelRatio property in the Window object, which reflects the ratio of pixels in the CSS to pixels on the device. However, 1px is equal to 1px on any mobile device, because different mobile devices have different pixel densities. The official definition of this property is: the ratio of device physical pixels to device independent pixels, i.e
DevicePixelRatio = Physical pixels/individual pixelsCopy the code
Remember the header of HTML on mobile
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">Copy the code
This defines the width of the viewport of the page to be the width of the device, the initial and maximum scaling values to be 1, and disallows user scaling. There is an ideal viewport for mobile phones that can be perfectly adapted. The ideal viewport width of mobile phones with very different resolutions may be the same. The purpose of this is to ensure that the same CSS is displayed consistently on different screens. The meta above actually sets the width of the Ideal ViewPort. For example, the screen width of iphone3 and iphone4 is 320px and 640px respectively, but their Ideal Viewport width is 320px. After setting the device width, 320px elements can fill 100% of the screen width. The ideal Viewport width is 320px, 360px and 384px for different mobile phones. For iPhone series, the ideal viewport is 320px before 6. The advantage of controlling viewport is that one set of CSS can be used for multiple models.
For those of you who can read it, you can already see why 1px is thicker. The viewPort Settings are proportional to the screen’s physical resolution, not the same. The window object on the mobile side has a devicePixelRatio property, which represents the ratio of the physical pixels of the device to the CSS pixels. On a Retina iPhone, the value is 2 or 3, and the 1px length in the CSS is mapped to 2px or 3px on the physical pixels. At this point one might ask, what are the solutions?
1px solution
Pseudo-classes +transform
implementation
Personally, I think the perfect solution to the 1px border problem is pseudo-class +transform. Principle: 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 absolutely positioned.
-
Single border style set
.scale{ position: relative; border:none; } .scale:after{ content: ''; position: absolute; bottom: 0; background: #000; width: 100%; height: 1px; - its - transform: scaleY (0.5); The transform: scaleY (0.5); -webkit-transform-origin: 0 0; transform-origin: 0 0; }Copy the code
-
Four Boder style Settings:
.scale{ position: relative; margin-bottom: 20px; border:none; } .scale: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%; - its - transform: scale (0.5); The transform: scale (0.5); -webkit-transform-origin: left top; transform-origin: left top; }Copy the code
-
It is also best to judge before using it, in combination with JS code, whether it is Retina display
if(window.devicePixelRatio && devicePixelRatio >= 2){ document.querySelector('ul').className = 'scale'; }Copy the code
flexible.js
This is taobao mobile terminal to take the program, github address :github.com/amfe/lib-fl… If you can set the viewport width to the actual physical width of the device, 1px in CSS will be 1px in length.
The scale value refers to the scale of the Ideal Viewport. Flexible. Js will calculate scale = 1/devicePixelRatio when detecting IOS models and set viewPort
metaEl = doc.createElement('meta');
metaEl.setAttribute('name', 'viewport');
metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');Copy the code
DevicePixelRatio =2 outputs meta as follows, so the viewPort ratio to ideal Viewport is 0.5, which is consistent with the device’s physical pixels
<meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">Copy the code
With devicePixelRatio = 3, viewPort is output
< meta name = "viewport" content = "initial - scale = 0.3333333333333333, the maximum - scale = 0.3333333333333333, Minimum - scale = 0.3333333333333333, user - scalable = no ">Copy the code
Use box-shadow to simulate borders
Use CSS to create a 0.5px shadow effect
.box-shadow-1px {
box-shadow: inset 0px -1px 1px -1px #c8c7cc;
}Copy the code