1. 程式人生 > >移動端1px問題

移動端1px問題

在移動端頁面中設定邊框為1px時,在有的裝置中可能會發現邊框比1px要粗即1培訓1px!=1px

原因裝置畫素比(devicePixelRatio)

裝置畫素比dpr = 裝置畫素 / CSS畫素(某一方向上)
當dpr為2時1px實際為2px(iphone6) dpr為3時1px為3px(inphoeX),所有看起來1px就會變粗

解決方案

.5px方案

IOS8下已經支援帶小數的px值,可以使用devicePixelRatio對應的媒體查詢

.border { border: 1px solid #999 }
@media screen and (-webkit-min-device-pixel-ratio: 2) {
    .border { border: 0.5px solid #999 }
}
@media screen and (-webkit-min-device-pixel-ratio: 3) {
    .border { border: 0.333333px solid #999 }
}

transform: scale()縮放

使用transform的scale來整體縮放,如果你想畫一條1px的線,就可以直接用

.line {
      height: 1px;
      background: #000;
      transform: scaleY(0.5);
      transform-origin: 0 0;
}

dpr=2時 縮放0.5 drp=3時縮放0.333
或和偽元素結合使用

li.flag:after {
    content: "";
    position: absolute;
    border: 1px solid #000;
    transform: scaleY(0.5);
    transform-origin: 0 0;
    bottom: 0;
    left: 0;
    width: 100%;
    height: 1px;
    color: #000;
}

改變viewport縮放

淘寶的flexible提出的解決方案
根據window.devicePixelRatio(dpr)的值動態改變viewport的縮放
其思想為:

  • 根據dpr的值來修改viewport實現1px的線
  • 根據dpr的值來修改html的font-size,從而使用rem實現等比縮放
  • 使用Hack手段用rem模擬vw特性
if (!dpr && !scale) {
    var isAndroid = win.navigator.appVersion.match(/android/gi);
    var isIPhone = win.navigator.appVersion.match(/iphone/gi);
    var devicePixelRatio = win.devicePixelRatio;
    if (isIPhone) {
        // iOS下,對於2和3的屏,用2倍的方案,其餘的用1倍方案
        if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {                
            dpr = 3;
        } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
            dpr = 2;
        } else {
            dpr = 1;
        }
    } else {
        // 其他裝置下,仍舊使用1倍的方案
        dpr = 1;
    }
    scale = 1 / dpr;
}

if (!metaEl) {
    metaEl = doc.createElement('meta');
    metaEl.setAttribute('name', 'viewport');
    metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
    if (docEl.firstElementChild) {
        docEl.firstElementChild.appendChild(metaEl);
    } else {
        var wrap = doc.createElement('div');
        wrap.appendChild(metaEl);
        doc.write(wrap.innerHTML);
    }
}

其它