解决flexible.js 在安卓中1px问题

1.Flexible原理

  • 1.1设置viewport
    通过设置scale将viewport宽度设置为实际的设备物理宽度, css里的1px就等于实际物理设备1px。
    例如iphone6 设备像素比devicePixelRatio=2,flexible设置的meta信息如下:

iphone6没有设置scale之前(375px) x (667px),1个css像素由2 x 2个物理像素构成,设置scale之后viewport大小为(750px) x (1334px),iphone6是二倍屏,从而实现css1px等于实际1px。1px就是设备展示的最小单位了。通常ui给的1px就是物理设备的最小单位(下图中红色部分标注的部分),flexible很好的实现了在iphone上的1px线条,直接设置height: 1px即可。


image.png
  • 1.2 设置rem
    Flexible将屏幕宽度等分10份,html元素上的font-size设置为1rem, 1rem = 屏幕宽度 / 10, 例如iphone6中1rem = 750px / 10 = 75px, css需要将px转化为rem, 从而实现不同屏幕的适配。

2. 安卓下1px问题

Flexible只处理了IOS机型,非iOS机型还是采用传统的scale=1.0,原因是在于安卓手机不一定有devicePixelRatio属性,以及devicePixelRatio的不规范,导致Flexible放弃治疗。所以在安卓的高清屏幕上1px显示比较粗,例如安卓3倍屏,1px会用3行物理像素点展示如下图所示。比ios的1px宽了许多。


image.png

解决方案:判断若为安卓机型,给html添加样式如下

// flexible.js
function retina () { // android高分辨率屏幕处理
    if (navigator.userAgent.toUpperCase().indexOf('IPHONE OS') !== -1) return; 
    var classNames = [];
    var pixelRatio = window.devicePixelRatio || 1;
    classNames.push('pixel-ratio-' + Math.floor(pixelRatio));
    if (pixelRatio >= 2) {
        classNames.push('retina');
    }
    var html = document.getElementsByTagName('html')[0];
    classNames.forEach(function (className) {
        html.classList.add(className);
    });
  }

...
// css文件
.border {
   ...
   height:1px;
   html.pixel-ratio-2 & {
     transform: scaleY(0.5)
   }
   html.pixel-ratio-3 & {
      transform: scaleY(0.3)
   }
}

ps:在iphone下设置0.5px(小于最小的物理像素单位)依然有线条展示,在android下设置0.5px是不会展示的。
为什么小于最小的物理像素单位还会展示线条呢?
其实展示的依然是最小的物理像素单位,不同的浏览器处理小于1px的方式不同,有些采用四舍五入,有些大于某个值展示1px否则就不展示,有些只是线条的颜色变浅了,从视觉上看就变细了。对比处理效果如下图所示。

image.png

你可能感兴趣的:(解决flexible.js 在安卓中1px问题)