前言

说明 : 在移动端项目中,1px的边框在高清屏下,会显得很粗

基本概念

物理像素:即设备像素,是显示设备中一个最微小的物理部件
设备独立像素(逻辑像素):也称为密度无关像素,比如说css像素,然后由相关系统转换为物理像素
css像素(虚拟像素):抽象单位,用在浏览器上,用来精确度量web页面上的内容
屏幕密度:指一个设备表面上存在的像素数量,通常以每英寸多少像素计算(PPI)
设备像素比:DPR
设备像素比 = 物理像素 / 设备独立像素
理解:当逻辑像素是1pt时,在DPR为2的设备上显示为2px的物理像素

各种类型的 iphone 手机屏幕设备的参数
1px(像素)问题 - 图1

理解:一般我们设计稿是7501334。那么这个750对应的就是物理像素,比如说以ipone6为例,dpr=2,那么我们写的逻辑像素也就是css像素就是375667,写代码时就会将宽度设置为375px

产生原因

DPR(devicePixelRatio) 设备像素比,它是默认缩放为100%的情况下,设备像素和CSS像素的比值,即

  1. window.devicePixelRatio=物理像素 /CSS像素

目前主流的屏幕DPR=2 (iPhone 8),或者3 (iPhone 8 Plus)。拿2倍屏来说,设备的物理像素要实现1像素,而DPR=2,所以css 像素只能是 0.5。一般设计稿是按照750来设计的,它上面的1px是以750来参照的,而我们写css样式是以设备375为参照的,所以我们应该写的0.5px就好了啊! 试过了就知道,iOS 8+系统支持,安卓系统不支持。

注: 但是在蓝湖上如果用 375 px 模式进行写页面,1px的问题不会出现

解决方案

一:利用css的伪元素::after + transform 进行缩放

原理:伪元素::after或::before是独立于当前的元素,可以单独对其缩放而不影响元素本身的缩放

伪元素大多数浏览器默认单引号也可以使用,和伪类一样形式,而且单引号兼容性(ie)更好

1条border实现

将伪元素设置绝对定位,并且和父元素的左上角对齐,将width设置100%,height设置为1px,然后进行在Y方向缩小0.5倍。

**

  1. .border-1px{
  2. position: relative;
  3. &::after{
  4. position: absolute;
  5. display: block;
  6. top: 0; //上面的1px
  7. left: 0;
  8. content: "";
  9. width: 100%;
  10. height: 1px; /*no*/
  11. background: #000;
  12. transform: scale(1, 0.5);
  13. }
  14. }

4条border实现

同样为伪元素设置绝对定位,并且和父元素左上角对其。将伪元素的长和宽先放大2倍,然后再设置一个边框,以左上角为中心,缩放到原来的0.5倍

  1. .border-1px-all{
  2. position: relative;
  3. &::after{
  4. position: absolute;
  5. top: 0;
  6. left: 0;
  7. content: "";
  8. width: 200%;
  9. height: 200%;
  10. transform: scale(0.5);
  11. transform-origin: left top;
  12. box-sizing: border-box;
  13. border: 1px solid black;
  14. border-radius: 4px;
  15. }
  16. }

二:根据媒体查询分别对不同的DPR设备进行不同的缩放

上述方案的升级版

  1. .border-1px {
  2. position: relative;
  3. }
  4. .border-1px::after {
  5. position: absolute;
  6. display: block;
  7. top: 0;
  8. left: 0;
  9. content: "";
  10. width: 100%;
  11. border-top: 1px solid black;
  12. }
  13. @media (-webkit-min-device-pixel-ratio: 2),(-min-device-pixel-ratio: 2) {
  14. .border-1px::after {
  15. transform: scaleY(0.5)
  16. }
  17. }
  18. @media (-webkit-min-device-pixel-ratio: 3),(-min-device-pixel-ratio: 3) {
  19. .border-1px::after {
  20. transform: scaleY(0.33)
  21. }
  22. }
  1. stylus 语法
  2. @media (-webkit-min-device-pixel-ratio: 1.5), (-min-device-pixel-ratio: 1.5)
  3. .border-1px
  4. &::after
  5. -webkit-transform: scaleY(0.7)
  6. transform: scaleY(0.7)
  7. @media (-webkit-min-device-pixel-ratio: 2), (-min-device-pixel-ratio: 2)
  8. .border-1px
  9. &::after
  10. -webkit-transform: scaleY(0.5)
  11. transform: scaleY(0.5)

三.总结

新项目: 媒体查询方法
老项目: 伪元素+transform的方法

文章

https://www.yuque.com/doraemon-g9kzm/dv46m2/bzlwuh#wyT4r
https://github.com/jawil/blog/issues/21
https://juejin.im/post/5d19b729f265da1bb2774865
https://juejin.im/post/5df3053ce51d45583d425ada