移动端 1px问题

1、概念:设备像素比DPR(devicePixelRatio)
DPR = 设备像素 / css像素(某一方向上)

2、什么是1px问题?
比如:iphone6的屏幕宽度为375px,设计师做的UI一般是750px,所以也就是1:2;
所以设计师在画的1px的边框,在“border-width:1px”上展示为2px,这就是移动端 retina屏 1px问题。

3、如何解决呢?
解决方案还是挺多的;媒体查询,js判断
1)媒体查询

// 正常屏幕
.border { border: 1px solid black; }
// retina屏幕使用媒体查询
@media (-webkit-min-device-pixel-ratio: 2) {
  .border { border-width: 0.5px } 
}

缺点:ios7以下和安卓设备等不支持;

2)通过 JavaScript 检测浏览器能否处理0.5px的边框,如果可以,给元素添加个class

// js代码,脚本应该放在<body>内, 如果在<head>里面运行,需要包装$(document).ready(function() {   })
if (window.devicePixelRatio && devicePixelRatio >= 2) {
  var testElem = document.createElement('div');
  testElem.style.border = '.5px solid transparent';
  document.body.appendChild(testElem);
  if (testElem.offsetHeight == 1)
  {
    document.querySelector('html').classList.add('hairlines');
  }
  document.body.removeChild(testElem);
}

// css代码
div {
  border: 1px solid #bbb;
}

.hairlines div {
  border-width: 0.5px;
}

3)边框实现利用:图片,渐变,阴影模拟

4)通过 viewport + rem 实现
将border设置为1px,然后将页面根据设备的dpr缩小相应的倍数,接着将rem放大相应的倍数,这样页面中只有1px的边框缩小了,而其他内容经过缩小和扩大,还是原来的状态。(rem元素大小不变,仅仅是px元素会根据dpr进行缩放)。

5)使用伪类 + transform实现原理是把原先元素的 border 去掉,然后利用 :before 或者 :after 重做 border ,并 transform 的 scale 缩小一半,原先的元素相对定位,新做的 border 绝对定位。

样式使用的时候,也要结合 js 代码,判断是否 Retina 屏if(window.devicePixelRatio && devicePixelRatio >= 2){
document.querySelector('ul').className = 'hairlines';
}

posted @ 2023-03-27 09:40  Math点PI  阅读(90)  评论(0)    收藏  举报