如何解决1px问题

1px问题指的是:在一些Retina屏幕 的机型上,移动端页面的 1px 会变得很粗,呈现出不止 1px 的效果。 原因很简单——CSS 中的 1px 并不能和移动设备上的 1px 划等号。它们之间的比例关系有一个专门的属性来描 述:

 设备像素比   window.devicePixelRatio = 设备的物理像素 / CSS像素。

打开 Chrome 浏览器,启动移动端调试模式,在控制台去输出这个 devicePixelRatio 的值。这里选中 iPhone6/7/8 这系列的机型,输出的结果就是2:
在这里插入图片描述
这就意味着设置的 1px CSS 像素,在这个设备上实际会用 2 个物理像素单元来进行渲染,所以实际看到的一定 会比 1px 粗一些。
解决1px 问题的三种思路

  • 直接借助媒体查询来处理
/*这是css方式*/ 
.border { border: 1px solid #999 } 
@media screen and (-webkit-min-device-pixel-ratio: 2) { 
  .border { border: 0.5px solid #999 } 
} 
/*ios dpr=2和dpr=3情况下border相差无几,下面代码可以省略*/ 
@media screen and (-webkit-min-device-pixel-ratio: 3) { 
  .border { border: 0.333333px solid #999 } 
} 
这是目前为止最简单的一种方法。这种方法的缺陷在于兼容性不行,IOS 系统需要8及以上的版本,安卓系统则直接不兼容
  • 伪元素先放大后缩小
    这个方法的可行性会更高,兼容性也更好。唯一的缺点是代码会变多。
    思路是先放大、后缩小:在目标元素的后面追加一个::after伪元素,让这个元素布局为absolute之后、整个伸展开铺在目标元素上,然后把他的宽和高都设置为目标元素的两倍,border值设为1px。接着借助css动画中的缩放能力,把整个伪元素缩放为原来的50%。此时,伪元素的高度刚好可以和原来的目标元素对齐,而border也缩放为1px的二分之一,间接实现了0.5px的效果。
<div id="container" data-device={{window.devicePixelRatio}}></div>

#container[data-device]{
  position: relative;
}
#container[data-device="2"]::after{
  position:absolute;
  content:"";
  top: 0;
  left: 0;
  width: 200%;
  height: 200%;
  transform: scale(0.5);
  transform-origin: left top;
  box-sizing: border-box;
  border: 1px solid #333;
}
  • viewport 缩放来解决
  <meta name="viewport" content="width=device-width,initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">

这里针对像素比为2的页面,把整个页面缩放为了原来的1/2大小。这样,本来占用2个物理像素的 1px 样式, 现在占用的就是标准的一个物理像素。根据像素比的不同,这个缩放比例可以被计算为不同的值,用 js 代码实 现如下

var viewport = document.querySelector("meta[name=viewport]");
const scale = 1 / window.devicePixelRatio;
// 这里 viewport指的是 meta 标签对应的 Dom
//下面是根据设备dpr设置viewport
viewport.setAttribute('content', `width=device-width,,initial-scale=${scale},maximum-scale=${scale}, minimum-scale=${scale}, user-scalable=no`)

这样解决了,但这样做的副作用也很大,整个页面被缩放了。这时 1px 已经被处理成物理像素大小,这样的大 小在手机上显示边框很合适。但是,一些原本不需要被缩小的内容,比如文字、图片等,也被无差别缩小掉了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值