今天在工作中需要到了一个很奇怪的问题。iphone上可以正常显示0.5px的border,但是安卓设备并不显示。当时第一想到的解决方法就是border-width:1px,这样确实可以解决安卓不显示border问题,但是实际看到border总感觉比1px宽。第一次接触toC的移动端开发,经验不足,这时候就去查了一些资料。
google一下0.5px之后,发现好多前辈早已经都给出来各种各样的解决方案。在解决问题之后还是看看为什么需要0.5px,上面说了设置成1px之后,肉眼感觉比1px宽。为什么呢?看下面console上面打印的结果
这个devicePixelRatio怎么算出来?在w3c的drafts上这样解释的:The devicePixelRatio attribute must return the result of the following algorithm:If there is no output device, return 1 and abort these steps.
Let CSS pixel size be the size of a CSS pixel at the current page zoom scale factor and at a pinch zoomscale factor of 1.0.
Let device pixel size be the vertical size of a device pixel of the output device.
Return the result of dividing CSS pixel size by device pixel size.
这里面的device pixel就是实际的值,css pixel 是自己写css 设定的值。看第4条其实就是说
devicePixelRatio = device pixel / css pixel
那么得到device pixel的计算公式:
device pixel = devicePixelRatio * css pixel
这就解释了一开始我设定1px的时候,感觉比1px宽一些。 我们可以利用上面的公式算一下实际是多宽:
devicePixelRatio = 2
css pixel = 1 (css设定的值)
device pixel = 2 * 1 = 2 (实际显示的值)
所以当设置border:1px的时候,实际大小是2px(简单了解devicePixelRatio看这篇文章)。
1px虽然和2px就差一点,但是肉眼看到的感觉完全不一样,真是量变引起了质变。于是怎么把显示1px呢。css设定0.5px,那么实际就是1px,但是安卓设备不显示0.5px(这个方案解决不了实际问题)
border采用image(这个方案可以解决,但是维护成本太大了,比如改个border的颜色)
box-shadow解决(这个方案挺好的,就是颜色处理上要小心一些。。。),看下图实例:
伪类和transform scale一起解决(这个方案也是最后我所采用的)
&:after
content ''
position absolute
width 200%
height 200%
top 0
left 0
transform-origin 0 0
transform scale(0.5, 0.5)
box-sizing border-box
z-index 1
解决思路就是先构造一个比本身大一倍的元素,然后缩小一倍。
这样整个问题基本解决了。最好的方案最后两种选一种你能hold住的。