關於移動端開發1px邊框的一些理解及解決辦法

初識1px

學習前端方向也有一段時間了,起初作過一些項目,老是發現作完以後本身的邊框會變得比較粗,後面翻閱了部分資料慢慢的才瞭解了這個問題,大體列舉了幾種解決的辦法。css

形成邊框變粗的緣由

在window對象中有一個devicePixelRatio屬性,他能夠反應css中的像素與設備的像素比。然而1px在不一樣的移動設備上都等於這個移動設備的1px,這是由於不一樣的移動設備有不一樣的像素密度。有關這個屬性,它的官方的定義爲:設備物理像素和設備獨立像素的比例,也就是
html

devicePixelRatio = 物理像素 / 獨立像素複製代碼

還記不記得移動端html的header這句話
前端

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">複製代碼

這句話定義了本頁面的viewport的寬度爲設備寬度,初始縮放值和最大縮放值都爲1,並禁止了用戶縮放.
手機存在一個能完美適配的理想viewport, 分辨率相差很大的手機的理想viewport的寬度多是同樣的, 這樣作的目的是爲了保證一樣的css在不一樣屏幕下的顯示效果是一致的, 上面的meta其實是設置了ideal viewport的寬度.
以實際舉例: iphone3和iphone4的屏幕寬度分別是320px,640px, 可是它們的ideal viewport的寬度都是320px, 設置了設備寬度後, 320px寬的元素都能100%的填充滿屏幕寬. 不一樣手機的ideal viewport寬度是不同的, 常見的有320px, 360px, 384px. iphone系列的這個值在6以前都是320px, 控制viewport的好處就在於一套css能夠適配多個機型.git

看懂的人應該已經明白 1px變粗的緣由了, viewport的設置和屏幕物理分辨率是按比例而不是相同的. 移動端window對象有個devicePixelRatio屬性, 它表示設備物理像素和css像素的比例, 在retina屏的iphone手機上, 這個值爲2或3, css裏寫的1px長度映射到物理像素上就有2px或3px那麼長.談到這裏那麼就會有人問,有哪些解決的辦法呢?github

1px的解決辦法

僞類+transform實現

對於解決1px邊框問題,我我的以爲最完美的解決辦法仍是僞類+transform比較好。
原理:是把原先元素的 border 去掉,而後利用 :before 或者 :after 重作 border ,並 transformscale 縮小一半,原先的元素相對定位,新作的 border 絕對定位。 web

  • 單條border樣式設置markdown

    .scale{
      position: relative;
      border:none;
    }
    .scale:after{
      content: '';
      position: absolute;
      bottom: 0;
      background: #000;
      width: 100%;
      height: 1px;
      -webkit-transform: scaleY(0.5);
      transform: scaleY(0.5);
      -webkit-transform-origin: 0 0;
      transform-origin: 0 0;
    }複製代碼
  • 四條boder樣式設置:iphone

    .scale{
      position: relative;
      margin-bottom: 20px;
      border:none;
    }
    .scale:after{
      content: '';
      position: absolute;
      top: 0;
      left: 0;
      border: 1px solid #000;
      -webkit-box-sizing: border-box;
      box-sizing: border-box;
      width: 200%;
      height: 200%;
      -webkit-transform: scale(0.5);
      transform: scale(0.5);
      -webkit-transform-origin: left top;
      transform-origin: left top;
    }複製代碼
  • 最好在使用前也判斷一下,結合 JS 代碼,判斷是否 Retina 屏 ide

    if(window.devicePixelRatio && devicePixelRatio >= 2){
      document.querySelector('ul').className = 'scale';
    }複製代碼

flexible.js

這是淘寶移動端採起的方案, github的地址:github.com/amfe/lib-fl…. 前面已經說過1px變粗的緣由就在於一刀切的設置viewport寬度, 若是能把viewport寬度設置爲實際的設備物理寬度, css裏的1px不就等於實際1px長了麼. flexible.js就是這樣乾的. oop

裏面的scale值指的是對ideal viewport的縮放, flexible.js檢測到IOS機型, 會算出scale = 1/devicePixelRatio, 而後設置viewport

metaEl = doc.createElement('meta');
metaEl.setAttribute('name', 'viewport');
metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');複製代碼

devicePixelRatio=2時輸出meta以下, 這樣viewport與ideal viewport的比是0.5, 也就與設備物理像素一致

<meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">複製代碼

在devicePixelRatio = 3 時,輸出viewport

<meta name="viewport" content="initial-scale=0.3333333333333333, maximum-scale=0.3333333333333333, minimum-scale=0.3333333333333333, user-scalable=no">複製代碼

使用box-shadow模擬邊框

利用css 對陰影處理的方式實現0.5px的效果

.box-shadow-1px {
  box-shadow: inset 0px -1px 1px -1px #c8c7cc;
}複製代碼
相關文章
相關標籤/搜索