物理像素
含义: 设备屏幕实际拥有的像素点,屏幕的基本单元,是有实体的。
比如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 实现
同时通过设置对应viewport
的rem
基准值,这种方式就可以像以前一样轻松愉快的写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
个伪元素, border
为1px
, 再以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
)要多层嵌套。
参考:https://www.cnblogs.com/AhuntSun-blog/p/13581877.html
标签:scale,0.5,transform,细线,1px,像素,border From: https://www.cnblogs.com/zzzlight/p/16628523.html