关于前端:前端面试CSS系列移动端1PX像素问题

35次阅读

共计 3502 个字符,预计需要花费 9 分钟才能阅读完成。

基本概念

设施像素

英文 Device Pixels,缩写为 DP,有时候也叫『物理像素』。
设施像素是咱们形容电子产品等实物的一个单位;比方咱们说相机 3000W 像素,手机 1 亿像素,电视机 4K。
在咱们形容电子设备屏幕分辨率 1920*1080 时,说的像素也是设施像素,不过通常说的是最大像素。

设施独立像素

英文 Device Independent Pixels,缩写为 DIPs,有时候也叫『逻辑像素』。
CSS、JavaScript、PS 当中咱们常说像素。比如说字体大小,图片宽高时的像素,就是设施独立像素。
在浏览器中,能够通过 screen.width 失去设施独立像素

设施像素比

英文 Device Pixels Ratio,缩写为 DPR;示意一个 设施 的物理像素与设施独立像素之比。
能够通过 window.devicePixelRatio 失去以后设施的设施像素与 CSS 设施独立像素之比。

PPI

英文 Pixels Per Inch,缩写 PPI;示意每英寸所领有的像素数量,有时候也叫『像素密度』。
当咱们形容手机、IPad,电脑显示器等电子设备屏幕尺寸大小的时,咱们通常会说 5.5 英寸,27 英寸,40 英寸。
雷同尺寸大小的屏幕,不同的分辨率下,PPI『像素密度』是不一样的。
PPI 的计算公式是:

同样是 4.3 英寸的屏幕,A 的分辨率是 480 800,B 的分辨率是 720 1280。
A 屏幕的像素密度『PPI』是 210;
B 屏幕的像素密度『PPI』是 340;
雷同屏幕尺寸,PPI 值越大画面的细节就会越丰盛,直观来讲就是 PPI 值越大,画面越清晰。

视网膜显示屏

是一种由苹果公司设计和委托制作的显示屏,具备足够高像素密度,而使得人体肉眼无奈分辨其中独自像素点的液晶屏幕。
简略了解就是雷同屏幕尺寸的显示屏,视网膜显示屏 PPI 值更大了。

为什么会有 1PX 的问题

在 Retian 屏上,DPR 不再是 1,而是大于 1,比方 2、3 或者非整数。IPhone 6 的设施像素『物理像素』是 750 1334,它的设施独立像素『逻辑像数』是 375 667,依据公司计算出 DRP = 2。
你想画个 1PX 的下边框,手机屏幕实际上给调配了 2 个设施像素『物理像素』。

1PX 边框问题实现计划

border-image 图片

.border-image-1px {
  border-width: 1px 0px;
  -webkit-border-image: url("data:image/png;base64,xxx") 2 0 stretch;
}

background-image 突变

.border {background-image:linear-gradient(180deg, red, red 50%, transparent 50%),
    linear-gradient(270deg, red, red 50%, transparent 50%),
    linear-gradient(0deg, red, red 50%, transparent 50%),
    linear-gradient(90deg, red, red 50%, transparent 50%);
  background-size: 100% 1px, 1px 100%, 100% 1px, 1px 100%;
  background-repeat: no-repeat;
  background-position: top, right top,  bottom, left top;
  padding: 10px;
}

viewport + rem + js 实现

<html>  
    <head>  
        <title>1 像素问题 </title>  
        <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">  
        <meta name="viewport" id="WebViewport" content="initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">       
        <style>  
          html {font-size: 1px;}
          * {
            padding: 0;
            margin: 0;
          }
          .bds_b {border-bottom: 1px solid #ccc;}
          .a,
          .b {
            margin-top: 1rem;
            padding: 1rem;
            font-size: 1.4rem;
          }
          .a {width: 30rem;}
          .b {
            background: #f5f5f5;
            width: 20rem;
          }
        </style>  
        <script>  
          
            var 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');  
            }  
            var docEl = document.documentElement;  
            var fontsize = 10 * (docEl.clientWidth / 320) + 'px';  
            docEl.style.fontSize = fontsize;  
              
        </script>  
    </head>  
  
    <body>  
        <div class="bds_b a"> 上面的底边宽度是虚构 1 像素的 </div>  
        <div class="b"> 下面的边框宽度是虚构 1 像素的 </div>  
    </body>  
  
</html>

box-shadow 实现

div {-webkit-box-shadow: 0 1px 1px -1px rgba(0, 0, 0, 0.5);
}

transform:scale(0.5)实现

办法 1
用 height:1px 的 div,而后依据媒体查问设置 transform: scaleY(0.5);

div {
  height: 1px;
  bakcground: #000;-webkit-transform: scaleY(0.5);
  -webkit-transform-origin: 0 0;
  overflow: hidden;
}

办法 2
用::after 和::before 伪类,设置 border-bottom: 1px solid #000,而后再缩放 -webkit-transform: scaleY(0.5);能够实现两根边线的需要

div::after {
  content: '';
  width: 100%;
  border-bottom: 1px solid #000;
  transform: scaleY(0.5);
}

办法 3
用::after 设置 border:1px solid #000;width:200%;height: 200%;,而后再缩放 scale(0.5);

.div::after {
  content: '';
  width:200%;
  height: 200%;
  position: absolute;
  top: 0;
  left: 0;
  border:1px solid #bfbfbf;
  border-radius: 4px;
  -webkit-transform: scale(0.5, 0.5);
  transform: scale(0.5, 0.5);
  -webkit-transform-origin: 0 0;
}

参考

挪动 H5 开发中 1 像素边框问题
把握 web 开发根底系列
视网膜显示屏
挪动端 web 页面常识小结之像素、物理像素、逻辑像素
Mobile physical pixels and device independent pixels
CSS 布局根底之一设施像素,设施独立像素,设施像素比,css 像素之间的关系
设施像素比
挪动端高清、多屏适配计划
iPhone 6 屏幕揭秘
挪动端 1 像素边框问题的解决方案

正文完
 0