移动端开发时总会存在各种各样样式不兼容的问题。

物理像素与逻辑像素

物理像素(设备像素)是指手机屏幕上实际呈现画面的像素点,比如iPhone6水平方向对应的750个像素点,物理像素是固定的,是根据屏幕大小和类型决定的
逻辑像素(设备独立像素)是虚拟的像素,它是操作系统定义的像素单位,在画面呈现时,操作系统会将逻辑像素转化成物理像素,在开发设置样式时,rem、px都对应的是逻辑像素
dpr是设备像素比,即一个逻辑像素对应多少物理像素,可以用window.devicePixelRatio获取
一般手机屏幕会分为1倍屏、2倍屏、3倍屏,指的就是1个逻辑像素对应几倍的物理像素,对于图片来说,图片也分为1倍高清图,2倍高清图,3倍高清图,说的也是1个逻辑像素对应1个、2个、3个物理像素,如果将1倍高清图放在3倍屏上展示,由于原本的1个物理像素的信息需要放到3个物理像素上展示,图片会出现拉伸模糊的相关,如果将3倍高清图放在1倍屏上展示,则会有部分像素信息丢失,图片会失真

0.5px细边框实现

在实际开发过程中,设计稿一般以750px宽度为标准,对应的是iPhone6的物理像素,设计稿经常有1px的边框,但实际iPhone6的屏幕只有375px,所以我们代码中1px其实对应了2px的物理像素,那要实现1px的物理像素,就要设置为0.5px逻辑像素
有些操作系统不支持0.5px,chorme会根据四舍五入设置为1px,Android系统会默认为0px,IOS系统<8时也不支持0.5px,所以需要有一个兼容多系统的0.5px方案

检测是否支持0.5px,

首先检测系统是否支持0.5px,如果支持添上hairlines样式,之后元素都可在该样式下设置0.5px

  1. // js代码,脚本应该放在<body>内, 如果在<head>里面运行,需要包装$(document).ready(function() { })
  2. if (window.devicePixelRatio && devicePixelRatio >= 2) {
  3. var testElem = document.createElement('div');
  4. testElem.style.border = '.5px solid transparent';
  5. document.body.appendChild(testElem);
  6. if (testElem.offsetHeight == 1)
  7. {
  8. document.querySelector('html').classList.add('hairlines');
  9. }
  10. document.body.removeChild(testElem);
  11. }
  12. // css代码
  13. div {
  14. border: 1px solid #bbb;
  15. }
  16. .hairlines div {
  17. border-width: 0.5px;
  18. }

viewport+rem

viewport+rem全局解决方案,判断dpr>=2,如果是,则代表页面可以缩放,即可以在手机中设置viewport

  1. <meta name="viewport" content="width=device-width, initial-scale=0.5, minimum-scale=0.5, maximum-scale=0.5, user-scalable=no, viewport-fit=cover">

viewport会整体缩放页面,0.5表示缩小一倍,实现了0.5px,同样,对于其他内容的实际大小也会被缩放,正常情况下10px的宽度会变为5px,所以这样方法需要与rem进行配合,将rem放大为相应的倍数,即将html对应的font-size设置为原来的dpr倍,当不需要缩放时,使用rem设置元素宽度高度,当需要缩放时,使用px来设置宽度或高度

0.5px的图片

可以使用0.5px的图片作为背景来实现边框

  1. .border{
  2. background: url(repeat-x-bootom.png) 0 bottom repeat-x;
  3. }

repeat-x-bootom.png是2*2的0.5px细线,使用background不断重复
缺点:需要实现圆角或者别的颜色的细线需要更换新的图,图片多了之后资源加载浪费时间

linear-gradient

也可以使用线性渐变来实现,50%的宽度是透明的

  1. .visual {
  2. background: linear-gradient(0, black, black 50%, transparent 50%) bottom right / 100% 1px no-repeat;
  3. }

缺点:在手机上比真正0.5px的线虚很多,而且无法实现圆角
image.png

伪元素+transform

使用transform对伪元素1px进行缩放,这样不会影响正常元素,但是伪元素依旧会触发事件,所以需要阻止鼠标点击事件

  1. .visual {
  2. position: relative;
  3. &::after {
  4. content: '';
  5. position: absolute;
  6. background: #fff;
  7. bottom: 0;
  8. height: 1px;
  9. width: 100%;
  10. transform: scaleY(0.5);
  11. pointer-events: none;
  12. }
  13. }

与正常0.5px实现一样不会发虚,且可以实现圆角(给伪元素添加border-radius)

参考