前端常見問題——一像素顯示

關於一像素顯示的問題能夠參考 從1px像素問題剖析像素及viewportiPhone 6 屏幕揭祕javascript

解決方案

如何解決一像素顯示問題能夠參考博客 7種方法解決移動端Retina屏幕1px邊框問題css

方案/優缺點 兼容性 顏色 圓角 總結
0.5px 邊框 沒法兼容安卓設備、 iOS 8 如下設備 支付 支持 簡單,不須要過多代碼
使用 border-image 修改顏色麻煩,須要替換圖片 圓角須要特殊處理,而且邊緣會模糊 能夠設置單條,多條邊框,且沒有性能瓶頸的問題
使用background-image實現 修改顏色麻煩, 須要替換圖片 圓角須要特殊處理,而且邊緣會模糊 能夠設置單條,多條邊框,沒有性能瓶頸的問題
多背景漸變實現 多背景圖片有兼容性問題 支持 不支持 能夠實現單條、多條邊框,邊框的顏色隨意設置,可是代碼量很多
使用 box-shadow 模擬邊框 邊框有陰影,顏色變淺 支持 代碼裏少,能夠知足全部場景
viewport + rem 實現 支持 支持 全部場景都能知足,一套代碼,能夠兼容基本全部佈局,可是老項目修改代價過大,只適用於新項目
僞類 + transform 實現 支持 支持(僞類和本體類都須要加border-radius) 全部場景都能知足,對於已經使用僞類的元素(例如clearfix),可能須要多層嵌套

測試示例

最佳實踐

若是公司內部已經有成熟的 「viewport + rem」 實現方案,那就不須要考慮一像素問題了。對於沒有采用該方案的項目,能夠結合 」0.5px 邊框「 和 「僞類 + transform 實現」 的實現方案。java

  1. HTML 的 header 標籤里加入 0.5 像素檢測腳本(放在頭部可避免屏幕出現閃爍問題)git

    var docEl = document.documentElement;
    var fakeBody = document.createElement('body');
    var testElement = document.createElement('div');
    testElement.style.border = '.5px solid transparent';
    fakeBody.appendChild(testElement);
    docEl.appendChild(fakeBody);
    if (testElement.offsetHeight === 1) {
      docEl.classList.add('hairlines');
    }
    docEl.removeChild(fakeBody);
  2. 根據選擇器 .hairlines 和設備像素比來設置預約義的公共樣式github

    /* 分割線 */
    .line-bottom,
    .line-left,
    .line-right,
    .line-top {
      position: relative;
    }
    .line-top::before,
    .line-bottom::after {
      content: '';
      position: absolute;
      left: 0;
      height: 1px;
      width: 100%;
      background-color: #e8e8e8;
    }
    .line-left::before,
    .line-right::after {
      content: '';
      position: absolute;
      top: 0;
      width: 1px;
      height: 100%;
      background-color: #e8e8e8;
    }
    .line-top::before {
      top: 0;
    }
    .line-bottom::after {
      bottom: 0;
    }
    .line-left::before {
      left: 0;
    }
    .line-right::after {
      right: 0;
    }
    .hairlines .line-top::before,
    .hairlines .line-left::before,
    .hairlines .line-right::after,
    .hairlines .line-bottom::after {
      transform: none;
    }
    .hairlines .line-top::before,
    .hairlines .line-bottom::after{
      height: 0.5px;
    }
    .hairlines .line-left::before,
    .hairlines .line-right::after{
      width: 0.5px;
    }
    @media (-webkit-min-device-pixel-ratio: 2) {
      .line-top::before,
      .line-bottom::after {
        transform: scaleY(0.5);
      }
      .line-left::before,
      .line-right::after {
        transform: scaleX(0.5);
      }
    }
    /* 因爲部分顏色比較淡,按實際比例縮放可能致使看不清分割線,因此可根據具體需求來決定是否按照實際像素比縮放 */
    /*@media (-webkit-min-device-pixel-ratio: 3) {
      .line-top::before,
      .line-bottom::after {
        transform: scaleY(0.333333);
      }
      .line-left::before,
      .line-right::after {
        transform: scaleX(0.333333);
      }
    } */
    /* 邊框 */
    .border {
      position: relative;
    }
    .border::after {
      content: " ";
      position: absolute;
      top: 0;
      left: 0;
      border: 1px solid #e8e8e8;
      box-sizing: border-box;
      width: 100%;
      height: 100%;
      transform-origin: left top;
    }
    .hairlines .border::after {
      display: none;
    }
    .hairlines .border {
      border: 0.5px solid #e8e8e8;
    }
    @media (-webkit-min-device-pixel-ratio: 2) {
      .border::after {
        width: 200%;
        height: 200%;
        transform: scale(0.5);
      }
    }
    /*@media (-webkit-min-device-pixel-ratio: 3) {
      .border::after {
        width: 300%;
        height: 300%;
        transform: scale(0.333333);
      }
    } */

一像素顯示-最佳實踐web

參考文獻

相關文章
相關標籤/搜索