移动端适配深度探究
我在網(wǎng)上看過很多相關(guān)的資料,都在說淘寶適配方案和網(wǎng)易適配方案。說了dpr,meta等好多概念,說實(shí)話我感覺寫的都好復(fù)雜,跟我自己想的有出入。新學(xué)東西我總想找到這個(gè)東西設(shè)計(jì)的出發(fā)點(diǎn),但我沒在這些文章中找出來。在看了些現(xiàn)在主流網(wǎng)站的代碼后,覺得自己有了一點(diǎn)心得,所以獻(xiàn)丑拿來分享下,希望對(duì)你有點(diǎn)幫助
準(zhǔn)備
既然是適配我們開始肯定要有一個(gè)參考屏幕,這里我們先提前確定下面所有的例子都是以iphone6的屏幕(寬度為375px)為參照。通常設(shè)計(jì)稿是2倍的設(shè)計(jì)稿,所以我們拿到的設(shè)計(jì)稿設(shè)計(jì)稿最終寬度為750px。
屏幕適配
屏幕適配最終的目標(biāo)或者說本質(zhì)就是實(shí)現(xiàn) 等比縮放。
現(xiàn)在各大網(wǎng)站雖然方案有差異,但步驟和目的其實(shí)是一樣的,主要分為以下幾步:
為什么要有個(gè)基準(zhǔn)?因?yàn)槲覀儾幌M糠N屏幕寫一種布局樣式,所以我們需要有一個(gè)基準(zhǔn)來隨屏幕寬度變化,我們只要根據(jù)基準(zhǔn)來確定我們的css值,就可以適配所有的屏幕了。
這就是適配的全部了,下面我們來看看這幾步可以用什么方案來解決。
基準(zhǔn)是什么?為了簡(jiǎn)單基準(zhǔn)我們看成單位,所以我們需要找一個(gè)能變化的單位,思考下,css中哪些單位可以變化?rem是以根字體的大小來確定自己的值的,符合條件。所以我們可以讓根字體隨屏幕變化而變化,我們直接用rem進(jìn)行布局可以了。
下一步就是確定基準(zhǔn)值,我們這里就是確定根字體的值。為了方便我們計(jì)算我們可以設(shè)置一個(gè)很容易計(jì)算的值,比如我們可以讓設(shè)計(jì)稿中1rem=100px,那么寫起來就是
// 屏幕寬度 / 7.5 = 1rem// 或// 100vw / 7.5 = 1rem 復(fù)制代碼這兩種在這個(gè)例子中是一樣的,然后我們寫樣式的時(shí)候用rem做為單位就可以了,比如設(shè)計(jì)稿上有一個(gè)寬度為80px的div元素,我們只需要這樣寫:
div {width: .8rem; } 復(fù)制代碼如果你還是嫌每次手動(dòng)計(jì)算麻煩,可以用現(xiàn)在樣式預(yù)處理器(如less、sass)中的mixin的來幫你或者使用js來動(dòng)態(tài)計(jì)算。
到這里我們的適配就說完了。你可能會(huì)問dpr、meta頭設(shè)置視圖寬度那些東西怎么沒看到,我明明在很多文章看到這些概念。別急,其實(shí)這些都是為了解決一個(gè)問題,下面我們就來說說這個(gè)問題
hairline
hairline是啥?hairline其實(shí)就是很細(xì)的線,很多設(shè)計(jì)師特別喜歡用這種線,讓我們前端頭大?。這種線直接用0.5px行嗎?這在以前一些舊的屏幕上是不行的,會(huì)被自動(dòng)修正為1px,我們都知道。
但是現(xiàn)代很多手機(jī)都是高倍屏,即一個(gè)css像素會(huì)有多個(gè)物理像素,這樣顯示的圖像更細(xì)膩并且更清晰,有的已經(jīng)支持css使用小數(shù),這種情況下我們可以直接使用像0.5px來寫出這種寬度的線了。這里有個(gè)概念,物理像素?cái)?shù)和css像素被稱為設(shè)備像素比,也就是我們經(jīng)常說的dpr了
物理像素?cái)?shù) / css像素?cái)?shù) = dpr 復(fù)制代碼dpr的值可以通過window.devicePixelRadio來獲取。
問題好像已經(jīng)解決了。但是我們前端還有很重要的一部分的工作是兼容,如果遇到不支持這種小數(shù)css寫法的怎么辦?我們想個(gè)很通用的解決方案,那就是縮放,比如我們把1px寬度的線縮小一半就能得到0.5px寬度的線了。
為了讓我們所有1px寬度縮為一個(gè)物理像素寬,我們就需要讓頁面寬度為屏幕css寬度 * dpr。然后我們?cè)谶@個(gè)寬度下寫1px寬度的線,最后再縮小dpr倍我們就可以得得到1物理像素寬度了。
為了實(shí)現(xiàn)讓頁面變?yōu)槠聊籧ss寬度 * dpr的寬的目的,我們需要按比例改變我們上面的適配方案。
假如現(xiàn)在dpr=3,我們就需要讓頁面寬度為 375 * 3 = 1125,而我們的設(shè)計(jì)稿是750。我們就需要讓我們的基準(zhǔn)值成比例變化
// 屏幕寬度 / 7.5 => 屏幕寬度 / 7.5 / 2 * 3 復(fù)制代碼現(xiàn)在我們得到尺寸為屏幕css寬度 * dpr的頁面了,為了讓頁面完全顯示在屏幕中我們需要在html中設(shè)置meta頭(不了解這些的自己查下,有很多資料)
<meta name="viewport" content="width=屏幕css寬度 * dpr"> 復(fù)制代碼然后縮小dpr倍變成
<meta name="viewport" content="width=屏幕css寬度 * dpr,initial-scale=1/dpr,minimum-scale=1/dpr,maximum-scale=1/dpr,user-scalable=no"> 復(fù)制代碼到這里,我們所有東西都講完了,希望你已經(jīng)理解了為什么會(huì)有那么多寫法不同的適配方案了,他們都是殊途同歸。
思考題
最后附上現(xiàn)在淘寶和網(wǎng)易的部分代碼,你可以自己直接去他們網(wǎng)站找到這些代碼。你應(yīng)該能根據(jù)這些代碼分析他們的方案了,這些留給你自己思考和分析了
手機(jī)淘寶網(wǎng)部分適配代碼
! 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) 復(fù)制代碼手機(jī)網(wǎng)易新聞網(wǎng)部分適配代碼
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} } 復(fù)制代碼本文原文更新在我的github上,這里是原文鏈接。如果文章有任何錯(cuò)誤或不準(zhǔn)確之處,歡迎指出,非常感謝!
轉(zhuǎn)載于:https://juejin.im/post/5c9830e65188252d64583343
總結(jié)
- 上一篇: Docker版本(三)
- 下一篇: 企业应用开发(4)(补充)--需求说明文