移動(dòng)端適配

在 web 的世界里,無線和 PC 的響應(yīng)式適配其實(shí)是兩個(gè)世界……

1. 視口 viewport

1.1 viewport 基礎(chǔ)

viewport 解釋為中文就是‘視口’的意思,也就是瀏覽器中用于顯示網(wǎng)頁的區(qū)域。在 PC 端,其大小也就是瀏覽器可視區(qū)域的大小挤渔,所以我們也不會(huì)太關(guān)注此概念;而在移動(dòng)端,絕大多數(shù)情況下 viewport 都大于瀏覽器可視區(qū)骡男,保證 PC 頁面在移動(dòng)瀏覽器上面的可視性。為提升可視性體驗(yàn)傍睹,針對移動(dòng)端有了對 viewport 的深入研究隔盛。

1.2 viewport 詳解

在移動(dòng)端有三種類型的 viewport: layoutviewport、visualviewport拾稳、idealviewport吮炕。具體解釋如下:

layoutviewport:? 大于實(shí)際屏幕, 元素的寬度繼承于 layoutviewport访得,用于保證網(wǎng)站的外觀特性與桌面瀏覽器一樣龙亲。layoutviewport 到底多寬,每個(gè)瀏覽器不同悍抑。iPhone 的 safari 為 980px鳄炉,通過 document.documentElement.clientWidth 獲取。

visualviewport: 當(dāng)前顯示在屏幕上的頁面搜骡,即瀏覽器可視區(qū)域的寬度拂盯。

idealviewport: 為瀏覽器定義的可完美適配移動(dòng)端的理想 viewport,固定不變记靡,可以認(rèn)為是設(shè)備視口寬度磕仅。比如 iphone 7 為 375px, iphone 7p 為 414px。

1.3 viewport 設(shè)置

我們通過對幾種 viewport 設(shè)置可以對網(wǎng)頁的展示進(jìn)行有效的控制簸呈,在移動(dòng)端我們經(jīng)常會(huì)在 head 標(biāo)簽中看到這段代碼:

復(fù)制代碼

通過對 meta 標(biāo)簽三個(gè) viewport 的設(shè)置克伊,最終使頁面完美展示吃嘿。下面詳細(xì)的闡釋其具體含義:

width 設(shè)置的是 layoutviewport 的寬度

initial-scale 設(shè)置頁面的初始縮放值,并且這個(gè)初始縮放值是相對于 idealviewport 縮放的,最終得到的結(jié)果不僅會(huì)決定 visualviewport瞳筏,還會(huì)影響到 layoutviewport

user-scalable 是否允許用戶進(jìn)行縮放的設(shè)置

對上面的說明通過公式推導(dǎo)進(jìn)行進(jìn)一步的解釋:

// 設(shè)定兩個(gè)變量:? viewport_1 = width;? viewport_2 = idealviewport / initial-scale;// 則:? layoutviewport = max{viewport_1, viewport_2};? visualviewport = viewport_2;復(fù)制代碼

只要 layoutviewport === visualviewport绢馍,頁面下面不會(huì)出現(xiàn)滾動(dòng)條,默認(rèn)只是把頁面放大或縮小。

1.4 viewport 舉例

以下是通過改變 meta viewport 的幾個(gè)參數(shù)的值來算取不同的 viewport:

widthinitial-scalelayoutviewportvisualviewportidealviewport是否滾動(dòng)

--980px980px375px否

device-width1375px375px375px否

device-width2375px188px375px是

device-width0.5750px750px375px否

480px1480px375px375px是

480px2480px188px375px是

480px0.5750px750px375px否

以上是針對 iphone 6/7/8 的測試數(shù)據(jù)丛楚,且無論怎么設(shè)置 viewport 都具有臨界值,即:75 <= layoutviewport <= 10000憔辫,75 <= visualviewport <= 1500趣些。

1.5 為什么要設(shè)置 viewport

viewport 的設(shè)置不會(huì)對 PC 頁面產(chǎn)生影響,但對于移動(dòng)頁面卻很重要贰您。下面我們舉例來說明:

媒體查詢 @media

響應(yīng)式布局中坏平,會(huì)根據(jù)媒體查詢功能來適配多端布局,必須對 viewport 進(jìn)行設(shè)置锦亦,否則根據(jù)查詢到的尺寸無法正確匹配視覺寬度而導(dǎo)致布局混亂舶替。如不設(shè)置 viewport 參數(shù),多說移動(dòng)端媒體查詢的結(jié)果將是 980px 這個(gè)節(jié)點(diǎn)布局的參數(shù)杠园,而非我們通常設(shè)置的 768px 范圍內(nèi)的這個(gè)布局參數(shù)

由于目前多數(shù)手機(jī)的 dpr 都不再是 1顾瞪,為了產(chǎn)出高保真頁面,我們一般會(huì)給出 750px 的設(shè)計(jì)稿抛蚁,那么就需要通過設(shè)置 viewport 的參數(shù)來進(jìn)行整體換算陈醒,而不是在每次設(shè)置尺寸時(shí)進(jìn)行長度的換算。

2. 設(shè)備像素比 dpr 與 1px 物理像素

2.1 物理像素(physical pixel)

手機(jī)屏幕上顯示的最小單元瞧甩,該最小單元具有顏色及亮度的屬性可供設(shè)置孵延,iphone6、7亲配、8 為:750 * 1334尘应,iphone6+、7+吼虎、8+ 為 1242 * 2208

2.2 設(shè)備獨(dú)立像素(density-indenpendent pixel)

此為邏輯像素犬钢,計(jì)算機(jī)設(shè)備中的一個(gè)點(diǎn),css 中設(shè)置的像素指的就是該像素思灰。老早在沒有 retina 屏之前玷犹,設(shè)備獨(dú)立像素與物理像素是相等的。

2.3 設(shè)備像素比(device pixel ratio)

設(shè)備像素比(dpr) = 物理像素/設(shè)備獨(dú)立像素洒疚。如 iphone 6歹颓、7、8 的 dpr 為 2油湖,那么一個(gè)設(shè)備獨(dú)立像素便為 4 個(gè)物理像素巍扛,因此在 css 上設(shè)置的 1px 在其屏幕上占據(jù)的是 2個(gè)物理像素,0.5px 對應(yīng)的才是其所能展示的最小單位乏德。這就是 1px 在 retina 屏上變粗的原因撤奸,目前有很多辦法來解決這一問題吠昭。

2.4 1px的物理像素的解決方案

從第一部分的討論可知 viewport 的 initial-scale 具有縮放頁面的效果。對于 dpr=2 的屏幕胧瓜,1px壓縮一半便可與1px的設(shè)備像素比匹配矢棚,這就可以通過將縮放比 initial-scale 設(shè)置為 0.5=1/2 而實(shí)現(xiàn)。以此類推 dpr=3的屏幕可以將 initial-scale設(shè)置為 0.33=1/3 來實(shí)現(xiàn)府喳。

3. 設(shè)備像素比 dpr 與 rem 的適配方案

結(jié)合 2蒲肋、3 部分可以實(shí)現(xiàn) 1px 的物理像素這一最小屏幕單位,那在此基礎(chǔ)上如可讓設(shè)計(jì)通常提供的 750px 設(shè)計(jì)稿來完美的適配到多種機(jī)型上钝满,使用 rem 是一種解決方式兜粘。

3.1 rem 如何設(shè)置

rem 是相對于根元素 html 的 font-size 來做計(jì)算。通常在頁面初始化時(shí)加載時(shí)通過對document.documentElement.style.fontSize設(shè)置來實(shí)現(xiàn)舱沧。

3.2 rem 適配規(guī)則

通過對 initial-scale = 1/dpr 的設(shè)置,已將對屏幕的描述從物理像素轉(zhuǎn)化到了物理像素上了偶洋,這將是后續(xù)推導(dǎo)的基礎(chǔ)熟吏,且設(shè)計(jì)稿為 750px。

物理像素為 750 = 375 * 2玄窝,若屏幕等分為 10 份牵寺,那么 1rem = 75px,10rem = 750px;

物理像素為 1125 = 375 * 3恩脂,若屏幕等分為 10 份帽氓,那么 1rem = 112.5px, 10rem = 1125px;

物理像素為 1242 = 414 * 3, 若屏幕等分為 10 份,那么 1rem = 124.2px, 10rem = 1242px;

因此可推導(dǎo)出 rem 的設(shè)定方式:

document.documentElement.style.fontSize =document.documentElement.clientWidth /10+'px';復(fù)制代碼

下面我們將 750px 下俩块,1rem 代表的像素值用 baseFont 表示黎休,則在 baseFont = 75 的情況下,是分成 10 等份的玉凯。因此可以將上面的公式通用話一些:

document.documentElement.style.fontSize =document.documentElement.clientWidth / (750/75) +'px';復(fù)制代碼

整體設(shè)置可參考如下代碼:

(function(baseFontSize){const_baseFontSize = baseFontSize ||75;constua = navigator.userAgent;constmatches = ua.match(/Android[\S\s]+AppleWebkit\/(\d{3})/i);constisIos = navigator.appVersion.match(/(iphone|ipad|ipod)/gi);constdpr =window.devicePixelRatio ||1;if(!isIos && !(matches && matches[1] >534)) {// 如果非iOS, 非Android4.3以上, dpr設(shè)為1;dpr =1;? ? }constscale =1/ dpr;constmetaEl =document.querySelector('meta[name="viewport"]');if(!metaEl) {? ? ? ? metaEl =document.createElement('meta');? ? ? ? metaEl.setAttribute('name','viewport');window.document.head.appendChild(metaEl);? ? }? ? metaEl.setAttribute('content','width=device-width,user-scalable=no,initial-scale='+ scale +',maximum-scale='+ scale +',minimum-scale='+ scale);document.documentElement.style.fontSize =document.documentElement.clientWidth / (750/ _baseFontSize) +'px';})();復(fù)制代碼

同時(shí)為了書寫方便可以直接通過 px 布局势腮,然后在打包時(shí)利用 pxtorem 庫轉(zhuǎn)化為基于 rem 的布局。

4. 視口單位適配方案

將視口寬度window.innerWidth和視口高度window.innerHeight等分為 100 份漫仆,且將這里的視口理解成 idealviewport 更為貼切捎拯,并不會(huì)隨著 viewport 的不同設(shè)置而改變。

vw : 1vw 為視口寬度的 1%

vh : 1vh 為視口高度的 1%

vmin :? vw 和 vh 中的較小值

vmax : 選取 vw 和 vh 中的較大值

如果設(shè)計(jì)稿為 750px盲厌,那么 1vw = 7.5px署照,100vw = 750px。其實(shí)設(shè)計(jì)稿按照設(shè)么都沒多大關(guān)系吗浩,最終轉(zhuǎn)化過來的都是相對單位建芙,上面講的 rem 也是對它的模擬。這里的比例關(guān)系也推薦不要自己換算懂扼,使用 pxtoviewport 的庫就可以幫我們轉(zhuǎn)換岁钓。當(dāng)然每種方案都會(huì)有其弊端,這里就不展開討論。

總結(jié)

在移動(dòng)端開發(fā)中屡限,理解視口對適配至關(guān)重要品嚣。因此本文先從視口展開討論,從而引出 1px钧大、rem 及 vw/vh 這些和適配相關(guān)的主要話題翰撑。下面提供的參考文章會(huì)在某些點(diǎn)上更加細(xì)化,以供參考啊央。

作者:阿里巴巴TXD

鏈接:https://juejin.im/post/5c0dd7ac6fb9a049c43d7edc

來源:掘金

著作權(quán)歸作者所有眶诈。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處瓜饥。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末逝撬,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子乓土,更是在濱河造成了極大的恐慌宪潮,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件趣苏,死亡現(xiàn)場離奇詭異狡相,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)食磕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進(jìn)店門尽棕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人彬伦,你說我怎么就攤上這事滔悉。” “怎么了单绑?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵氧敢,是天一觀的道長。 經(jīng)常有香客問我询张,道長孙乖,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任份氧,我火速辦了婚禮唯袄,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蜗帜。我一直安慰自己恋拷,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布厅缺。 她就那樣靜靜地躺著蔬顾,像睡著了一般宴偿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上诀豁,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天窄刘,我揣著相機(jī)與錄音,去河邊找鬼舷胜。 笑死娩践,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的烹骨。 我是一名探鬼主播翻伺,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼沮焕!你這毒婦竟也來了吨岭?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤峦树,失蹤者是張志新(化名)和其女友劉穎辣辫,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體空入,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡络它,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年族檬,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了歪赢。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,622評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡单料,死狀恐怖埋凯,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情扫尖,我是刑警寧澤白对,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站换怖,受9級特大地震影響甩恼,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜沉颂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一条摸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧铸屉,春花似錦钉蒲、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽踏枣。三九已至,卻和暖如春钙蒙,著一層夾襖步出監(jiān)牢的瞬間茵瀑,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工仪搔, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留瘾婿,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓烤咧,卻偏偏與公主長得像偏陪,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子煮嫌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 不知不覺做前端已經(jīng)兩年了笛谦,從PC端,移動(dòng)端昌阿,微信小程序一路走來到今天剛剛開放注冊的快應(yīng)用(手機(jī)廠商對抗小程序的新技...
    是ADI呀閱讀 3,095評論 0 10
  • 【菜鳥一枚~哪里不對饥脑,希望大佬可以幫忙糾正】 以下是我電腦打開瀏覽器F12模式下的數(shù)據(jù):我的電腦分辨率當(dāng)前為192...
    文千會(huì)閱讀 986評論 0 0
  • 剛開始做移動(dòng)端web開發(fā)的同學(xué)應(yīng)該都碰到過頁面適配問題,為什么我在開發(fā)手機(jī)上調(diào)試好的頁面在其他手機(jī)會(huì)有這樣或那樣的...
    留七七閱讀 19,316評論 5 80
  • 前言:這周工作碰到了移動(dòng)端1px的問題懦冰。以前一直寫樣式也沒有特別注意著一點(diǎn)灶轰。還有就是rem的原理。這些其實(shí)就是比較...
    奮斗的香蕉閱讀 449評論 0 1
  • 相信很多人和我一樣刷钢,從來沒有接觸過什么工廠笋颤,雖然我們每天用著各種各樣的產(chǎn)品,卻無法分辨其中制造難度内地。也正因?yàn)槲覀兲?..
    寒陽198閱讀 503評論 0 3