<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          如何解決移動端 Retina 屏 1px 像素問題 ?

          共 6426字,需瀏覽 13分鐘

           ·

          2021-08-10 01:45


          點擊上方 三分鐘學(xué)前端,關(guān)注公眾號

          回復(fù)交流,加入前端編程面試算法每日一題群


          面試官也在看的前端面試資料

          什么導(dǎo)致了 1px 問題?

          在移動端 Web 開發(fā)中,UI 設(shè)計稿中設(shè)置邊框為 1 像素,前端在開發(fā)過程中如果出現(xiàn) border:1px ,測試會發(fā)現(xiàn)在 Retina 屏機型中,1px 會比較粗,即是較經(jīng)典的移動端 1px 像素問題。

          以 iphone6 為例,iphone6 的屏幕寬度為 375px ,設(shè)計師做的視覺稿一般是750px ,也就是 2x ,這個時候設(shè)計師在視覺稿上畫了 1px 的邊框,于是你就寫了 border:1px ,so...1px邊框問題產(chǎn)生了。

          對設(shè)計師來說它的 1px 是相對于 750px 的(物理像素),對你來說你的 1px 是相對于 375px 的(css像素),實際上你應(yīng)該是 border:0.5px 。

          如何解決?

          方案優(yōu)點缺點
          0.5px實現(xiàn)代碼簡單,使用css即可IOS及Android老設(shè)備不支持
          border-image實現(xiàn)兼容目前所有機型修改顏色不方便
          viewport + rem 實現(xiàn)一套代碼,所有頁面和0.5px一樣,機型不兼容
          偽元素 + transform實現(xiàn)兼容所有機型不支持圓角
          box-shadow模擬邊框?qū)崿F(xiàn)兼容所有機型box-shadow不在盒子模型,需要注意預(yù)留位置
          svg 實現(xiàn)實現(xiàn)簡單,可以實現(xiàn)圓角需要學(xué)習(xí) svg 語法

          0.5px 實現(xiàn)

          .border-1px { border1px solid #999 }
          @media screen and (-webkit-min-device-pixel-ratio: 2) {
              .border-1px { border0.5px solid #999 }
          }
          /* dpr=2 和 dpr=3 情況下 border 相差無幾,下面代碼可以省略*/
          @media screen and (-webkit-min-device-pixel-ratio: 3) {
              .border-1px { border0.333333px solid #999 }
          }

          但在 IOS7 及以下和 Android 等其他系統(tǒng)里,0.5px 將會被顯示為 0px 。所以我們需要通過 JS 檢測瀏覽器能否處理 0.5px 的邊框

          if (window.devicePixelRatio && devicePixelRatio >= 2) {
            var testElem = document.createElement('div');
            testElem.style.border = '.5px solid transparent';
            document.body.appendChild(testElem);
          }
          if (testElem.offsetHeight == 1) {
            document.querySelector('html').classList.add('hairlines');
          }
            document.body.removeChild(testElem);
          }
          • 優(yōu)點:簡單,沒有副作用
          • 缺點:支持 iOS 8+,安卓待兼容

          使用 border-image 實現(xiàn)

          基于 media 查詢判斷不同的設(shè)備像素比給定不同的 border-image

          .border-1px{
              border-bottom1px solid #000;
          }
          @media only screen and (-webkit-min-device-pixel-ratio:2){
              .border_1px{
                  border-bottom: none;
                  border-width0 0 1px 0;
                  border-imageurl(../img/1pxline.png) 0 0 2 0 stretch;
              }
          }

          缺點:更換顏色需要更換圖片,圓角模糊

          viewport + rem 實現(xiàn)

          通過設(shè)置縮放,讓 CSS 像素等于真正的物理像素。

          const scale = 1 / window.devicePixelRatio;
          const viewport = document.querySelector('meta[name="viewport"]');
          if (!viewport) {
              viewport = document.createElement('meta');
              viewport.setAttribute('name''viewport');
              window.document.head.appendChild(viewport);
          }

          viewport.setAttribute('content''width=device-width,user-scalable=no,initial-scale=' + scale + ',maximum-scale=' + scale + ',minimum-scale=' + scale);

          // 設(shè)置根字體大小
          var docEl = document.documentElement; 
          var fontsize = 10 * (docEl.clientWidth / 320) + 'px'
          docEl.style.fontSize = fontsize;

          // 在CSS中用rem單位就行了

          缺點:

          • 通過 JS 對文檔進行修改,所以性能上有一定影響
          • 會對項目中所有使用 rem 單位的對象進行影響。如果是老項目,則會全部更改 css 樣式(不適合老項目改造)

          偽元素 + transform 實現(xiàn)

          為什么用偽元素? 因為偽元素 ::after 或 ::before 是獨立于當(dāng)前元素,可以單獨對其縮放而不影響元素本身的縮放

          基于 media 查詢判斷不同的設(shè)備像素比對線條進行縮放:

          .border-1px:before{
              content'';
              position: absolute;
              top0;
              height1px;
              width100%;
              background-color#999;
              transform-origin50% 0%;
          }
          @media only screen and (-webkit-min-device-pixel-ratio:2){
              .border-1px:before{
                  transformscaleY(0.5);
              }
          }
          @media only screen and (-webkit-min-device-pixel-ratio:3){
              .border-1px:before{
                  transformscaleY(0.33);
              }
          }

          注意如果需要滿足圓角,需要給偽類也加上 border-radius

          優(yōu)點:兼容性好,無副作用,推薦使用

          box-shadow 模擬邊框?qū)崿F(xiàn)

          box-shadow: 0  -1px 1px -1px #999
                      1px  0  1px -1px #999
                      0  1px  1px -1px #999
                      -1px 0  1px -1px #999;

          缺點:邊框有陰影,顏色淺,同樣也有兼容性問題,Safari 不支持 1px 以下的 box-shadow。

          svg 實現(xiàn)

          因為 svg 是矢量圖形,它的 1px 對應(yīng)的物理像素就是 1px

          可以搭配 PostCSS 的 postcss-write-svg 使用:

          @svg border-1px { 
            height: 2px
            @rect { 
              fillvar(--colorblack); 
              width: 100%; 
              height: 50%; 
              } 
            } 
          .svg { 
              border1px solid transparent; 
              border-imagesvg(border_1px param(--color #00b1ff)) 2 2 stretch; 
          }

          編譯后:

          .svg { border1px solid transparent; border-imageurl("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' height='2px'%3E%3Crect fill='%2300b1ff' width='100%25' height='50%25'/%3E%3C/svg%3E"2 2 stretch; }
          • 優(yōu)點:實現(xiàn)簡單,可以實現(xiàn)圓角,
          • 缺點:需要學(xué)習(xí) svg 語法

          總結(jié)

          綜上,推薦使用:

          • 偽元素 + transform 實現(xiàn)
          • svg 實現(xiàn)
          • 新項目可以嘗試使用 viewport 方案

          解決移動端 Retina 屏 1px 像素問題

          來自:https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/513

          最后

          歡迎關(guān)注「三分鐘學(xué)前端」,回復(fù)「交流」自動加入前端三分鐘進階群,每日一道編程算法面試題(含解答),助力你成為更優(yōu)秀的前端開發(fā)!

          號內(nèi)回復(fù):

          網(wǎng)絡(luò)」,自動獲取三分鐘學(xué)前端網(wǎng)絡(luò)篇小書(90+頁)
          JS」,自動獲取三分鐘學(xué)前端 JS 篇小書(120+頁)
          算法」,自動獲取 github 2.9k+ 的前端算法小書
          面試」,自動獲取 github 23.2k+ 的前端面試小書
          簡歷」,自動獲取程序員系列的 120 套模版
          》》面試官也在看的前端面試資料《《
          “在看和轉(zhuǎn)發(fā)”就是最大的


          瀏覽 27
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日韩精品大香蕉 | 可以免费看的A片 | 毛片中文电影 | 色之综合天天综合色天天棕色 | 色就是色欧美自拍 |