怎么粗了?移动端1px太抢镜了,Hold住它

548 阅读2分钟

为何移动端1px抢镜(变粗)

移动端里,我们写css时写了1px,实际显示的时候比1px要粗
原因呢,其实,移动端window对象里有个 devicePixelRatios 属性,叫做 设备像数比 ,也就是设备的物理像素与逻辑像素的比值。

const dpr = window.devicePixelRatios

我们以iphone6为例子:它的物理像素是750,逻辑像素是375,所以他的 dpr 为 2,那么在css里写1px映射到物理像素就是2px了

那么如何hold它呢

一. 使用css的媒体查询

.element {
  border: 1px solid #000;
}

@media screen and (-webkit-min-device-pixel-ratio: 2) {
  .element {
    border: 0.5px solid #000;
  }
}

@media screen and (-webkit-min-device-pixel-ratio: 3) {
  .element {
    border: 0.333333px solid #000;
  }
}

根据css的媒体查询,来判断dpr,如果dpr为2,则将border改为0.5px,如果dpr为3,则border为0.333333px

二. 利用伪元素实现border

原理:把原先元素的border去掉,然后利用:before或者:after重做border,并用transform的scale缩小一半,原先的元素相对定位,新做的border绝对定位

.border-1px, .border-bottom-1px, .border-top-1px, .border-left-1px, .border-right-1px {
    position: relative;
}

/*线条颜色 黑色*/
.border-1px::after, .border-bottom-1px::after, .border-top-1px::after, .border-left-1px::after, .border-right-1px::after {
    background-color: #000;
}

/*底边边框一像素*/
.border-bottom-1px::after {
    content: "";
    position: absolute;
    left: 0;
    bottom: 0;
    width: 100%;
    height: 1px;
    transform-origin: 0 0;
}

/*上边边框一像素*/
.border-top-1px::after {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 1px;
    transform-origin: 0 0;
}

/*左边边框一像素*/
.border-left-1px::after {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    width: 1px;
    height: 100%;
    transform-origin: 0 0;
}

/*右边边框1像素*/
.border-right-1px::after {
    content: "";
    box-sizing: border-box;
    position: absolute;
    right: 0;
    top: 0;
    width: 1px;
    height: 100%;
    transform-origin: 0 0;
}

/*边框一像素*/
.border-1px::after {
    content: "";
    box-sizing: border-box;
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    border: 1px solid gray;
}


/*设备像素比*/
/*显示屏最小dpr为2*/
@media (-webkit-min-device-pixel-ratio: 2) {
    .border-bottom-1px::after, .border-top-1px::after {
        transform: scaleY(0.5);
    }

    .border-left-1px::after, .border-right-1px::after {
        transform: scaleX(0.5);
    }

    .border-1px::after {
        width: 200%;
        height: 200%;
        transform: scale(0.5);
        transform-origin: 0 0;
    }
}

/*设备像素比*/
@media (-webkit-min-device-pixel-ratio: 3)  {
    .border-bottom-1px::after, .border-top-1px::after {
        transform: scaleY(0.333);
    }

    .border-left-1px::after, .border-right-1px::after {
        transform: scaleX(0.333);
    }

    .border-1px::after {
        width: 300%;
        height: 300%;
        transform: scale(0.333);
        transform-origin: 0 0;
    }
}

三. 利用viewport + js + 使用rem实现

html元素的head中存在这样一个元素:

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
  • name="viewport" content="width=device-width: 本页面的 「viewport」 的宽度为设备宽度。
  • initial-scale=1.0: 初始缩放值为 1,
  • maximum-scale=1.0: 最大的缩放值为 1。
  • user-scalable=no: 禁止用户进行页面缩放。

那么通过设置viewport的initial-scale,就可以轻松实现:

  • 当dpr = 1 时,initial-scale = 1
  • 当dpr = 2 时,initial-scale = 0.5
  • 当dpr = 3 时,initial-scale = 0.33333333333
<html>
  <head>
    <title></title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
    <style></style>
    <script>
      let viewport = document.querySelector("meta[name=viewport]");
      //下面是根据设备像素设置viewport
      if (window.devicePixelRatio == 1) {
        viewport.setAttribute('content', 'width=device-width,initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no');
      }
      if (window.devicePixelRatio == 2) {
        viewport.setAttribute('content', 'width=device-width,initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no');
      }
      if (window.devicePixelRatio == 3) {
        viewport.setAttribute('content', 'width=device-width,initial-scale=0.3333333333333333, maximum-scale=0.3333333333333333, minimum-scale=0.3333333333333333, user-scalable=no');
      }
      let docEl = document.documentElement;
      let fontsize = 32* (docEl.clientWidth / 750) + 'px';
      docEl.style.fontSize = fontsize;
    </script>
  </head>
</html>