移动端1px解决方案

产生原因

  • 设备像素比(window.devicePixelRatio),也就是设备的物理像素与逻辑像素的比值
  • 在retina屏的手机, dpr为2或3,css里写的1px宽度映射到物理像素上就有2px或3px宽度。

解决方案

实现1PX边框的方法有很多,各有优缺点,比如通过0.5px、背景图片实现、border-image、postcss-write-svg等实现。本文通过伪类元素+transform、viewport+rem两种方式实现,优点是可以自适应已知的各类手机屏幕,且不存在其它方法存在的变颜色困难、圆角阴影失效问题。

  • 伪类元素 + transform

    • 优点:所有场景都能满足,支持圆角(伪类和本体类都需要加border-radius)。
    • 缺点:对于已经使用伪类的元素(例如clearfix),可能需要多层嵌套。
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .box{
      width: 100px;
      height: 100px;
      position: relative;
    }
    .box::after{
      content:'';
      position: absolute;
      left: 0;
      bottom: 0;
      width: 100%;
      height: 1px;
      background: #000;
    }
    @media screen and (-webkit-min-device-pixel-ratio: 2) {
      .box::after{
         transform: scaleY(0.5);
      }
    }
    @media screen and (-webkit-min-device-pixel-ratio: 3) {
      .box::after{
        transform: scaleY(0.33333);
      }
    }
  </style>
</head>
<body>
  <div class="box"></div>
</body>
</html>
  • viewport + rem + js

    • 优点:所有场景都能满足,一套代码,可以兼容基本所有布局。
    • 缺点:老项目修改代价过大,只适用于新项目。
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>

  <style>
    .box{
      width: 0.5rem;
      height: 0.5rem;
      border-bottom: 1px solid #000;
    }
  </style>
</head>
<body>
  <div class="box"></div>

  <script>
    var dpr = window.devicePixelRatio;
    var scale = 1 / dpr;
    var width = document.documentElement.clientWidth;
    var metaNode = document.querySelector('meta[name="viewport"]')
    metaNode.setAttribute("content","width=device-width, initial-scale="+scale)

    var htmlNode = document.querySelector("html");
    htmlNode.style.fontSize = width * dpr +'px';
  </script>
</body>
</html>
posted @ 2020-11-21 11:45  十一是假期啊  阅读(196)  评论(0编辑  收藏  举报