首页 > 其他分享 >物理像素,逻辑像素,1px细线问题

物理像素,逻辑像素,1px细线问题

时间:2022-08-26 18:12:34浏览次数:51  
标签:scale 0.5 transform 细线 1px 像素 border

物理像素

含义: 设备屏幕实际拥有的像素点,屏幕的基本单元,是有实体的。

 

比如iPhone 6的屏幕在宽度方向有750个物理像素点,高度方向有1334个物理像素点,所以iPhone 6 总共有750*1334个物理像素点。

逻辑像素

含义: 称为设备独立像素(Device Independent Pixel,DIP),也称为CSS像素CSS里定义像素点,比如1px表示逻辑像素为1

详解: 默认情况下1物理像素 = 1逻辑像素, 在高像素密度的设备上1物理像素 = 多个逻辑像素, 比如: 以iPhone6为例,设计稿给出一个图片的宽高为40*40,在实际开发中要除以2,宽高要写成20*20,因为从iPhone4开始, 苹果公司为其产品mac、iPhone以及iPad的屏幕配置了Retina高清屏,在Retian屏上,即 DPR===2。然后现在比较近的,比如iPhone12 mini的DPR是3。

 

用户缩放浏览器也会引起css中px的变化

  • 当用户把页面放大一倍,那么css中1px所代表的物理像素也会增加一倍;
  • 把页面缩小一倍,css中1px所代表的物理像素也会减少一倍;

即如果发生缩放或者放大,虽然默认情况下一个CSS像素应该是等于一个物理像素的宽度的,但是浏览器的放大操作让一个CSS像素等于了两个设备像素宽度(这时效果就和前面举例iphone中DPR为2一样,放大使得1个CSS的像素px这时变为了两倍)。 从上面的例子可以看出,CSS像素从来都只是一个相对值。

 

 

1px细线问题

在上文我们已经知道,CSS像素为1px宽的直线,对应的物理像素是不同的,在不同DPR下,可能是会有实际2倍或者3倍粗,而设计师想要的1px宽的直线,其实就是1物理像素宽,而不是设置1px后被转换成2-3个物理像素。

对于CSS而言,可以认为是border: 0.5px;这是多倍屏下能显示的最小单位。然而,并不是所有手机浏览器都能识别border: 0.5px,有的系统里,0.5px会被当成为0px处理,那么如何1px细线问题呢?

 

首先可以说一下怎么画一条1像素细线

直接写 0.5px,即通过缩放解决

  • 采用transform: scale()的方式,该方法用来定义元素的2D 缩放转换:
transform: scale(0.5,0.5);

注意scale(0.5,0.5)也可以写(0.2,0.2)画0.2的细线,实际上这个就是用的缩放,所以可以设置其他非0.5

  • 采用meta viewport的方式
<meta name="viewport" content="width=device-width, initial-scale=0.5, minimum-scale=0.5, maximum-scale=0.5"/>

 

因此很多解决1px问题的话一个常用办法就是缩放

1.viewport 缩放

viewport + rem 实现

同时通过设置对应viewportrem基准值,这种方式就可以像以前一样轻松愉快的写1px了。
devicePixelRatio = 2 时,输出viewport

<meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">

devicePixelRatio = 3 时,输出viewport

<meta name="viewport" content="initial-scale=0.3333333333333333, maximum-scale=0.3333333333333333, minimum-scale=0.3333333333333333, user-scalable=no">

这种兼容方案相对比较完美,适合新的项目,老的项目修改成本过大。

优点:

  • 所有场景都能满足
  • 一套代码,可以兼容基本所有布局

缺点:

  • 老项目修改代价过大,只适用于新项目

2.伪元素+transform

构建1个伪元素, border1px, 再以transform缩放到50%

对于老项目,有没有什么办法能兼容1px的尴尬问题了,个人认为伪类+transform是比较完美的方法了。
原理是把原先元素的 border 去掉,然后利用 :before 或者 :after 重做 border ,并将 transform 的 scale 缩小一半,原先的元素相对定位,新做的 border 绝对定位。
单条border样式设置:

.scale-1px{
  position: relative;
  border:none;
}
.scale-1px:after{
  content: '';
  position: absolute;
  bottom: 0;
  background: #000;
  width: 100%;
  height: 1px;
  -webkit-transform: scaleY(0.5);
  transform: scaleY(0.5);
  -webkit-transform-origin: 0 0;
  transform-origin: 0 0;
}

 

四条boder样式设置:

 
.scale-1px{
  position: relative;
  margin-bottom: 20px;
  border:none;
}
.scale-1px:after{
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  border: 1px solid #000;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  width: 200%;
  height: 200%;
  -webkit-transform: scale(0.5);
  transform: scale(0.5);
  -webkit-transform-origin: left top;
  transform-origin: left top;
}

最好在使用前也判断一下,结合 JS 代码,判断是否 Retina 屏:

if(window.devicePixelRatio && devicePixelRatio >= 2){
  document.querySelector('ul').className = 'scale-1px';
}

优点:可以满足所有场景,且修改灵活。缺点:对于已使用伪类的元素(例如clearfix)要多层嵌套。

然后,还有许多其他办法,比如:使用box-shadow模拟边框,使用border-image,使用background-image,使用box-shadow模拟边框,这些效果都不太好,略。主要还是使用缩放这类比较有效。

 

参考:https://www.cnblogs.com/AhuntSun-blog/p/13581877.html

 

 

标签:scale,0.5,transform,细线,1px,像素,border
From: https://www.cnblogs.com/zzzlight/p/16628523.html

相关文章