前端面試CSS系列——移動端1PX像素問題

基本概念

設備像素

英文Device Pixels,縮寫爲DP,有時候也叫『物理像素』。
設備像素是咱們描述電子產品等實物的一個單位;好比咱們說相機3000W像素,手機1億像素,電視機4K。
在咱們形容電子設備屏幕分辨率1920*1080時,說的像素也是設備像素,不過一般說的是最大像素。css

設備獨立像素

英文Device Independent Pixels,縮寫爲DIPs,有時候也叫『邏輯像素』。
CSS、JavaScript、PS當中咱們常說像素。好比說字體大小,圖片寬高時的像素,就是設備獨立像素。
在瀏覽器中,能夠經過screen.width獲得設備獨立像素html

設備像素比

英文Device Pixels Ratio,縮寫爲DPR;表示一個設備的物理像素與設備獨立像素之比。
能夠經過 window.devicePixelRatio獲得當前設備的設備像素與CSS設備獨立像素之比。git

PPI

英文Pixels Per Inch,縮寫PPI;表示每英寸所擁有的像素數量,有時候也叫『像素密度』。
當咱們描述手機、IPad,電腦顯示器等電子設備屏幕尺寸大小的時,咱們一般會說5.5英寸,27英寸,40英寸。
相同尺寸大小的屏幕,不一樣的分辨率下,PPI『像素密度』是不同的。
PPI的計算公式是:
PPI計算公式
一樣是4.3英寸的屏幕,A的分辨率是480 800,B的分辨率是720 1280。
A屏幕的像素密度『PPI』是210;
B屏幕的像素密度『PPI』是340;
相同屏幕尺寸,PPI值越大畫面的細節就會越豐富,直觀來說就是PPI值越大,畫面越清晰。github

視網膜顯示屏

是一種由蘋果公司設計和委託製造的顯示屏,具有足夠高像素密度,而使得人體肉眼沒法分辨其中單獨像素點的液晶屏幕。
簡單理解就是相同屏幕尺寸的顯示屏,視網膜顯示屏PPI值更大了。web

爲何會有1PX的問題

在Retian屏上,DPR再也不是1,而是大於1,好比二、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);iphone

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);能夠實現兩根邊線的需求移動端web

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);wordpress

.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像素邊框問題的解決方案佈局

相關文章
相關標籤/搜索