移動端適配深度探究

Xiaowei發表於2019-03-25

我在網上看過很多相關的資料,都在說淘寶適配方案和網易適配方案。說了dpr,meta等好多概念,說實話我感覺寫的都好複雜,跟我自己想的有出入。新學東西我總想找到這個東西設計的出發點,但我沒在這些文章中找出來。在看了些現在主流網站的程式碼後,覺得自己有了一點心得,所以獻醜拿來分享下,希望對你有點幫助

準備

既然是適配我們開始肯定要有一個參考螢幕,這裡我們先提前確定下面所有的例子都是以iphone6的螢幕(寬度為375px)為參照。通常設計稿是2倍的設計稿,所以我們拿到的設計稿設計稿最終寬度為750px

螢幕適配

螢幕適配最終的目標或者說本質就是實現 等比縮放

現在各大網站雖然方案有差異,但步驟和目的其實是一樣的,主要分為以下幾步:

  1. 找到一個基準,基準能隨螢幕寬度變化
  2. 確定基準的值
  3. 根據基準的值來寫我們的樣式

為什麼要有個基準?因為我們不希望每種螢幕寫一種佈局樣式,所以我們需要有一個基準來隨螢幕寬度變化,我們只要根據基準來確定我們的css值,就可以適配所有的螢幕了。

這就是適配的全部了,下面我們來看看這幾步可以用什麼方案來解決。

基準是什麼?為了簡單基準我們看成單位,所以我們需要找一個能變化的單位,思考下,css中哪些單位可以變化?rem是以根字型的大小來確定自己的值的,符合條件。所以我們可以讓根字型隨螢幕變化而變化,我們直接用rem進行佈局可以了。

下一步就是確定基準值,我們這裡就是確定根字型的值。為了方便我們計算我們可以設定一個很容易計算的值,比如我們可以讓設計稿中1rem=100px,那麼寫起來就是

// 螢幕寬度 / 7.5 = 1rem

// 或

// 100vw  / 7.5 = 1rem
複製程式碼

這兩種在這個例子中是一樣的,然後我們寫樣式的時候用rem做為單位就可以了,比如設計稿上有一個寬度為80pxdiv元素,我們只需要這樣寫:

div {
  width: .8rem;
}
複製程式碼

如果你還是嫌每次手動計算麻煩,可以用現在樣式前處理器(如less、sass)中的mixin的來幫你或者使用js來動態計算。

到這裡我們的適配就說完了。你可能會問dpr、meta頭設定檢視寬度那些東西怎麼沒看到,我明明在很多文章看到這些概念。別急,其實這些都是為了解決一個問題,下面我們就來說說這個問題

hairline

hairline是啥?hairline其實就是很細的線,很多設計師特別喜歡用這種線,讓我們前端頭大?。這種線直接用0.5px行嗎?這在以前一些舊的螢幕上是不行的,會被自動修正為1px,我們都知道。

但是現代很多手機都是高倍屏,即一個css畫素會有多個物理畫素,這樣顯示的影像更細膩並且更清晰,有的已經支援css使用小數,這種情況下我們可以直接使用像0.5px來寫出這種寬度的線了。這裡有個概念,物理畫素數和css畫素被稱為裝置畫素比,也就是我們經常說的dpr了

物理畫素數 / css畫素數 = dpr
複製程式碼

dpr的值可以通過window.devicePixelRadio來獲取。

問題好像已經解決了。但是我們前端還有很重要的一部分的工作是相容,如果遇到不支援這種小數css寫法的怎麼辦?我們想個很通用的解決方案,那就是縮放,比如我們把1px寬度的線縮小一半就能得到0.5px寬度的線了。

為了讓我們所有1px寬度縮為一個物理畫素寬,我們就需要讓頁面寬度為螢幕css寬度 * dpr。然後我們在這個寬度下寫1px寬度的線,最後再縮小dpr倍我們就可以得得到1物理畫素寬度了。

為了實現讓頁面變為螢幕css寬度 * dpr的寬的目的,我們需要按比例改變我們上面的適配方案。

假如現在dpr=3,我們就需要讓頁面寬度為 375 * 3 = 1125,而我們的設計稿是750。我們就需要讓我們的基準值成比例變化

// 螢幕寬度 / 7.5 => 螢幕寬度 / 7.5 / 2 * 3
複製程式碼

現在我們得到尺寸為螢幕css寬度 * dpr的頁面了,為了讓頁面完全顯示在螢幕中我們需要在html中設定meta頭(不瞭解這些的自己查下,有很多資料)

<meta name="viewport" content="width=螢幕css寬度 * dpr">
複製程式碼

然後縮小dpr倍變成

<meta name="viewport" content="width=螢幕css寬度 * dpr,initial-scale=1/dpr,minimum-scale=1/dpr,maximum-scale=1/dpr,user-scalable=no">
複製程式碼

到這裡,我們所有東西都講完了,希望你已經理解了為什麼會有那麼多寫法不同的適配方案了,他們都是殊途同歸。

思考題

最後附上現在淘寶和網易的部分程式碼,你可以自己直接去他們網站找到這些程式碼。你應該能根據這些程式碼分析他們的方案了,這些留給你自己思考和分析了

手機淘寶網部分適配程式碼

! function (e, t) {
  var n = t.documentElement,
    d = e.devicePixelRatio || 1;

  function i() {
    var e = n.clientWidth / 3.75;
    n.style.fontSize = e + "px"
  }
  if (function e() {
      t.body ? t.body.style.fontSize = "16px" : t.addEventListener("DOMContentLoaded", e)
    }(), i(), e.addEventListener("resize", i), e.addEventListener("pageshow", function (e) {
      e.persisted && i()
    }), 2 <= d) {
    var o = t.createElement("body"),
      a = t.createElement("div");
    a.style.border = ".5px solid transparent", o.appendChild(a), n.appendChild(o), 1 === a.offsetHeight && n.classList.add("hairlines"), n.removeChild(o)
  }
}(window, document)
複製程式碼

手機網易新聞網部分適配程式碼

html {
    font-size: 13.33333vw
}

@media screen and (max-width: 320px) {
    html {
        font-size:42.667px;
        font-size: 13.33333vw
    }
}

@media screen and (min-width: 321px) and (max-width:360px) {
    html {
        font-size:48px;
        font-size: 13.33333vw
    }
}

@media screen and (min-width: 361px) and (max-width:375px) {
    html {
        font-size:50px;
        font-size: 13.33333vw
    }
}

@media screen and (min-width: 376px) and (max-width:393px) {
    html {
        font-size:52.4px;
        font-size: 13.33333vw
    }
}

@media screen and (min-width: 394px) and (max-width:412px) {
    html {
        font-size:54.93px;
        font-size: 13.33333vw
    }
}

@media screen and (min-width: 413px) and (max-width:414px) {
    html {
        font-size:55.2px;
        font-size: 13.33333vw
    }
}

@media screen and (min-width: 415px) and (max-width:480px) {
    html {
        font-size:64px;
        font-size: 13.33333vw
    }
}

@media screen and (min-width: 481px) and (max-width:540px) {
    html {
        font-size:72px;
        font-size: 13.33333vw
    }
}

@media screen and (min-width: 541px) and (max-width:640px) {
    html {
        font-size:85.33px;
        font-size: 13.33333vw
    }
}

@media screen and (min-width: 641px) and (max-width:720px) {
    html {
        font-size:96px;
        font-size: 13.33333vw
    }
}

@media screen and (min-width: 721px) and (max-width:768px) {
    html {
        font-size:102.4px;
        font-size: 13.33333vw
    }
}

@media screen and (min-width: 769px) {
    html {
        font-size:102.4px;
        font-size: 13.33333vw
    }
}
複製程式碼

本文原文更新在我的github上,這裡是原文連結。如果文章有任何錯誤或不準確之處,歡迎指出,非常感謝!

相關文章