[月分享] 我對(duì)移動(dòng)端適配的了解

不知不覺做前端已經(jīng)兩年了,從PC端运挫,移動(dòng)端贮竟,微信小程序一路走來到今天剛剛開放注冊(cè)的快應(yīng)用(手機(jī)廠商對(duì)抗小程序的新技能,所以在注冊(cè)時(shí)用的是qq郵箱的話要去垃圾箱里才能找到注冊(cè)郵件),對(duì)于前端圈日新月異的磅礴發(fā)展對(duì)于大前端發(fā)展是喜聞樂見的帖汞,這次的快應(yīng)用的手機(jī)廠商們?yōu)槠溟_放了應(yīng)用入口和系統(tǒng)推廣引流入口耍缴。這些新能力為前端開發(fā)者們帶來更強(qiáng)的作戰(zhàn)能力砾肺。

我們?cè)陂_發(fā)PC站時(shí)經(jīng)常在瀏覽器兼容問題上耗費(fèi)巨大的時(shí)間,到了移動(dòng)端防嗡,面對(duì)webkit內(nèi)核的Safari與Chrome會(huì)舒心很多变汪。but,我們要對(duì)于市面上的手機(jī)各式各樣的分辨率進(jìn)行適配蚁趁,剛接觸移動(dòng)端開發(fā)的時(shí)候是不是有點(diǎn)猝不及防哈哈裙盾,尤其是去年年中以前老版本的微信內(nèi)置瀏覽器用的X5內(nèi)核,給網(wǎng)友們戲稱移動(dòng)端IE...


2.png

今天的主題是講的是我對(duì)移動(dòng)端多終端適配的解決方案和移動(dòng)端適配的有關(guān)布局的知識(shí)總結(jié)荣德,下面正式開始闷煤。

基本概念和原理

首先要了解的重要的基礎(chǔ)知識(shí)點(diǎn):物理像素,設(shè)備獨(dú)立像素涮瞻,css像素 鲤拿,設(shè)備像素比,布局視口署咽,可視視口 , 理想視口以及css單位rem近顷。

物理像素(設(shè)備像素)
屏幕的物理像素,又被稱為設(shè)備像素宁否。任何設(shè)備屏幕的物理像素出廠時(shí)就確定了窒升,是固定不變的。
設(shè)備獨(dú)立像素
設(shè)備獨(dú)立像素也可以理解為CSS像素慕匠,可以認(rèn)為是計(jì)算機(jī)坐標(biāo)系統(tǒng)中的一個(gè)點(diǎn)饱须,這個(gè)點(diǎn)代表一個(gè)可以由程序使用的虛擬像素(比如說CSS像素)。
設(shè)備像素比
設(shè)備像素比簡(jiǎn)稱為dpr台谊,dpr = 物理像素 / 設(shè)備獨(dú)立像素蓉媳。(以iphone6為例: dpr = 750 / 375 , 所以它的像素密度比為2譬挚,即 1個(gè)CSS像素 跨越了 2個(gè)物理像素),我們可以通過 window.devicePixelRatio 來獲取設(shè)備的像素密度酪呻,像素密度大于1就是高清屏减宣。
CSS像素
在CSS、JS中使用的一個(gè)長度單位玩荠,單位px漆腌。
注:在pc端1物理像素等于1px,但是移動(dòng)端1物理像素不一定等于1px(高清屏)阶冈。

布局視口(layout viewport)
可以看作是html元素的上一級(jí)容器即頂級(jí)容器闷尿,默認(rèn)情況或者將html元素的width屬性設(shè)為100%時(shí),會(huì)占滿這個(gè)頂級(jí)容器眼溶,此時(shí)用 document.documentElement.clientWidth 獲取到html元素的布局寬度也就是布局視口的寬度悠砚,使用媒體查詢時(shí) max-width 和 min-width 的值指的也是布局視口的寬晓勇。
在html中一般在meta中的name為viewport字段就是控制的布局視口堂飞。布局視口一般都是瀏覽器廠商給的一個(gè)值。在手機(jī)互聯(lián)網(wǎng)沒有普及前绑咱,網(wǎng)絡(luò)上絕大部分頁面都是為電腦端瀏覽而做的绰筛,根本沒有做移動(dòng)端的適配。
隨著移動(dòng)端的發(fā)展描融,在手機(jī)上看電腦端的頁面已成為非常普及現(xiàn)象铝噩。而電腦端頁面寬度較大,移動(dòng)端寬度有限窿克,要想看到整個(gè)網(wǎng)頁骏庸,會(huì)有很長的滾動(dòng)條,看起來非常麻煩年叮。于是瀏覽器廠商為了讓用戶在小屏幕下網(wǎng)頁也能夠顯示地很好具被,所以把布局視口設(shè)置的很大,一般在768px ~ 1024px 之間只损,最常用的寬度就是 980一姿。
這樣用戶就能看到絕大部分內(nèi)容,并根據(jù)具體內(nèi)容選擇縮放跃惫。
故布局視口是看不見的叮叹,瀏覽器廠商設(shè)置的一個(gè)固定值,如980px爆存,并將980px的內(nèi)容縮放到手機(jī)屏內(nèi)蛉顽。一塊手機(jī)屏幕,物理像素的數(shù)量是固定不變的先较。
視覺視口的大小是繼承自布局視口的大小携冤,視覺視口和布局視口的寬度為CSS的px數(shù)(可變的)遥诉。

理想視口
布局視口雖然解決了移動(dòng)端查看pc端網(wǎng)頁的問題,但是完全忽略了手機(jī)本身的尺寸噪叙。所以蘋果引入了理想視口矮锈,它對(duì)設(shè)備來說是最理想的布局視口,用戶不需要對(duì)頁面進(jìn)行縮放就能完美的顯示整個(gè)頁面睁蕾。最簡(jiǎn)單的做法就是使布局視口寬度設(shè)置為手機(jī)屏幕的寬度苞笨。移動(dòng)端到底怎么適配不同的屏幕呢?最簡(jiǎn)單的方法是設(shè)置如下視口:
<meta name="viewport" content="width=device-width,initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
復(fù)習(xí)一下: dpr = 物理像素 / 設(shè)備獨(dú)立像素子眶。
以iphone6為例瀑凝,iphone6的物理像素為750,如果沒有設(shè)置布局視口時(shí)臭杰,布局視口viewport默認(rèn)為980px
此時(shí):dpr = 750 / 980 = 0.76531粤咪,等于1個(gè)CSS像素有0.76531個(gè)物理像素。接近于1像素密度所以pc端的頁面在手機(jī)端看時(shí)不會(huì)太小渴杆。
當(dāng)在meta中設(shè)置了如下配置時(shí):
<meta name="viewport" content="width=device-width">
相當(dāng)于把布局視口設(shè)置為設(shè)備的寬度(即設(shè)備獨(dú)立像素)寥枝,
iphone6的設(shè)備獨(dú)立像素為 375px。
此時(shí):dpr = 750 / 375 = 2磁奖,等于1個(gè)CSS像素有2個(gè)物理像素囊拜。此時(shí)把pc端的尺寸拿來手機(jī)端看時(shí)字體和元素會(huì)特別大只。

現(xiàn)在移動(dòng)端設(shè)計(jì)稿都是基于iphone設(shè)計(jì)的比搭,一般為750px或640px冠跷,對(duì)應(yīng)的是iphone6和iphone5的物理像素。在設(shè)計(jì)稿中身诺,1px像素邊框?qū)?yīng)的是1物理像素蜜托。而在iphone5和iphone6中,當(dāng)布局視口width=device-width時(shí)霉赡,css的1px顯示出來的是2個(gè)物理像素橄务,所以用戶看到的是2px的邊框。怎么解決呢同廉?1px邊框效果其實(shí)有很多hack方法仪糖,其中一種就是通過縮放viewport。
<meta name="viewport" content="width=device-width,initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">
viewport縮放
initial-scale是對(duì)布局視口進(jìn)行縮放迫肖,initial-scale是相對(duì)于理想視口的锅劝,即initial-scale=1與width=device-width是一樣的效果。initial-scale=0.5等效于width= 2倍的 device-width蟆湖,所以設(shè)置initial-scale和width都可以改變布局視口的大小故爵。
對(duì)于可視視口的縮放可以理解為,用戶用雙指對(duì)頁面進(jìn)行縮放,當(dāng)用戶縮小頁面時(shí)诬垂,可視視口變大用戶可以看到的東西越多劲室,當(dāng)用戶放大頁面時(shí),可視視口
變小结窘,用戶看到的東西越少很洋。
對(duì)于iphone6當(dāng)添加如上設(shè)置后,initial-scale=0.5時(shí)隧枫。
布局視口: 375px * 2 = 750px;
所以此時(shí)布局視口為750px喉磁,此時(shí)1px等于1物理像素了。(移動(dòng)端一像素有很多hack寫法比如用偽類實(shí)現(xiàn)官脓,svg實(shí)現(xiàn)等等)
看到這是不是覺得要消化的知識(shí)點(diǎn)有點(diǎn)多协怒,不怕,休息一下消化消化卑笨,每個(gè)人都是這樣過來的孕暇。猥瑣發(fā)育~

多種適配方案探究

當(dāng)設(shè)計(jì)師給出ui圖時(shí),面對(duì)市場(chǎng)上各式各樣的手機(jī)它們屏幕大小不同赤兴,dpr不同妖滔,屏幕尺寸也是各種大小,那么我們應(yīng)該怎么做到對(duì)ui設(shè)計(jì)圖的充分還原搀缠,使得項(xiàng)目在各式各樣的手機(jī)里運(yùn)行呢铛楣?為了解決這種情況出現(xiàn)了許多的適配方案近迁,各方案的實(shí)現(xiàn)方法不一樣艺普,還原程度也不一樣,下面來總結(jié)一下常見的幾種適配方案及其原理鉴竭。
方案一:固定高度歧譬,使其寬度自適應(yīng)
這也是我接觸移動(dòng)端適配第一次使用的方案。
這個(gè)方案使用了理想視口,使得布局視口等于設(shè)備寬度搏存。
<meta name="viewport" content="width=device-width,initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
在布局方面縱向使用固定px值,橫向使用自適應(yīng)布局(百分比瑰步,felx,小額定值)璧眠。
這種方案相對(duì)簡(jiǎn)單缩焦,ui還原度比較低。

方案二:固定布局視口寬度责静,使用viewport進(jìn)行縮放(網(wǎng)易袁滥、荔枝FM)


       if(/Android (\d+\.\d+)/.test(navigator.userAgent)){
           var version = parseFloat(RegExp.$1);
           if(version>2.3){
               var phoneScale = parseInt(window.screen.width)/640;
               if(/MZ-M571C/.test(navigator.userAgent)){
                   document.write('<meta name="viewport" content="width=640, minimum-scale = 0.5, maximum-scale= 0.5">');
               }else if(/M571C/.test(navigator.userAgent)&&/LizhiFM/.test(navigator.userAgent)){
                   document.write('<meta name="viewport" content="width=640, minimum-scale = 0.5, maximum-scale= 0.5">');
               }else{
                   document.write('<meta name="viewport" content="width=640, minimum-scale = '+ phoneScale +', maximum-scale = '+ phoneScale +', target-densitydpi=device-dpi">');
               }
           }else{
               document.write('<meta name="viewport" content="width=640, target-densitydpi=device-dpi">');
           }
       }else{
           document.write('<meta name="viewport" content="width=640, user-scalable=no, target-densitydpi=device-dpi">');
       }

固定布局視口,寬度設(shè)置固定的值灾螃,總寬度為640px题翻,根據(jù)屏幕寬度動(dòng)態(tài)生成viewport。(設(shè)計(jì)稿寬度為640px)
這種布局方案頁面寬度始終為640px通過設(shè)置縮放比例scale實(shí)現(xiàn)適配:
var scale = window.screen.width / 640;
當(dāng)設(shè)計(jì)稿為640px時(shí)腰鬼,我們可以直接用1:1px來寫像素單位嵌赠。這種布局方案中的1px不一定等于1px塑荒,當(dāng)設(shè)備為iphone6時(shí)
1px(css) = window.screen.width*dpr = 640 = 375 * 2 / 640 = 1.171875(設(shè)備物理像素)
荔枝FM這種適配方案用到了target-densitydpi , 這是一個(gè)將被拋棄的屬性姜挺,因此不推薦使用這套方案(學(xué)習(xí)一下思路也不錯(cuò))

方案三:根據(jù)不同屏幕動(dòng)態(tài)寫入font-size齿税,以rem作為寬度單位,固定布局視口炊豪。(網(wǎng)易新聞)
首先設(shè)置理想視口:
<meta name="viewport" content="width=device-width,initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
接下來計(jì)算 html 元素的 font-size,將可視視口的寬度乘以一個(gè)系數(shù):

理論上這個(gè)系數(shù)可以是任意值偎窘,假設(shè)將這個(gè)系數(shù)取 1,則 html 元素的 font-size 即1 rem等于可視視口的寬度溜在,此時(shí)以 rem 為單位的長度 n rem 就可以理解為 n 倍可視視口的長陌知,這個(gè)系數(shù)取 0.01 時(shí),1 rem 等于可視視口寬的 1/100掖肋,也就等于布局視口寬的 1/100仆葡,也就等于 1vw。實(shí)際使用過程中這個(gè)系數(shù)的選擇盡可能方便將設(shè)計(jì)稿長度數(shù)值換算為css中的長度數(shù)值
網(wǎng)易新聞手機(jī)網(wǎng)易網(wǎng)選擇的系數(shù)為 100 / 750志笼,這個(gè)系數(shù)可以如下推出:

750px 是設(shè)計(jì)稿的寬度(以iphone6的物理像素?cái)?shù)為標(biāo)準(zhǔn))沿盅,100是期望的換算比例,即設(shè)計(jì)稿中 100px 的長度對(duì)應(yīng)css中 1rem纫溃,將設(shè)計(jì)稿中的長度數(shù)值除以 100 得到的就是以 rem 為單位的 css 長度的數(shù)值腰涧,設(shè)計(jì)稿的寬換算為以 rem 為單位的 css 長度應(yīng)為 (750/100) rem,同時(shí)設(shè)計(jì)稿的寬對(duì)應(yīng)可視視口的寬紊浩,即有 (750/100) rem = 可視視口寬窖铡,1 rem = 可視視口寬 * (100/750),(100/750)就是我們要的系數(shù)
在頁面初始化時(shí)設(shè)置一下 html 元素的 font-size:

在750寬的設(shè)計(jì)稿:document.documentElement.style.fontSize = window.innerWidth / 7.5 + 'px';
在640寬的設(shè)計(jì)稿:document.documentElement.style.fontSize = window.innerWidth / 7.5 + 'px';
這套方案能百分比還原設(shè)計(jì)稿坊谁。

方案四:根據(jù)不同屏幕動(dòng)態(tài)寫入font-size和viewport费彼,以rem作為寬度單位.
將屏幕分為固定的塊數(shù)10:

var width = document.documentElement.clientWidth; // 屏幕的布局視口寬度
var rem = width / 10; // 將布局視口分為10份
這樣在任何屏幕下,總長度都為10rem口芍。1rem對(duì)應(yīng)的值也不固定箍铲,與屏幕的布局視口寬度有關(guān)。

動(dòng)態(tài)縮放view:

var devicePixelRatio = window.devicePixelRatio;
var isIPhone = window.navigator.appVersion.match(/iphone/gi);
var dpr,scale;
if (isIPhone) {
  if (devicePixelRatio >=3) {
    dpr = 3;
  } else if (devicePixelRatio >=2) {
    dpr = 2;
  } else {
    dpr = 1;
  }
} else {
  dpr = 1;
}
scale = 1 / dpr;

淘寶只對(duì)iphone做了縮放處理鬓椭,對(duì)于android所有dpr=1颠猴,scale=1即沒有縮放處理。

此方案與方案三相似小染,增進(jìn)了viewport縮放使得在iphone上1px(css) = 1px(物理像素)翘瓮,這套方案能百分比還原設(shè)計(jì)稿。
Flexible實(shí)現(xiàn)手淘H5頁面的終端適配
方案五:
可以來看看我總結(jié)的 : 大漠老師最新的vw移動(dòng)端適配方案


最后看到這里相信大家心里都有個(gè)底氧映,知道選擇哪一種方案更能適配自己所開發(fā)的項(xiàng)目

(~ ̄▽ ̄)~

see u ~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末春畔,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌律姨,老刑警劉巖振峻,帶你破解...
    沈念sama閱讀 216,470評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異择份,居然都是意外死亡扣孟,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門荣赶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來凤价,“玉大人,你說我怎么就攤上這事拔创±担” “怎么了?”我有些...
    開封第一講書人閱讀 162,577評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵剩燥,是天一觀的道長慢逾。 經(jīng)常有香客問我,道長灭红,這世上最難降的妖魔是什么侣滩? 我笑而不...
    開封第一講書人閱讀 58,176評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮变擒,結(jié)果婚禮上君珠,老公的妹妹穿的比我還像新娘。我一直安慰自己娇斑,他們只是感情好策添,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,189評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著悠菜,像睡著了一般舰攒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上悔醋,一...
    開封第一講書人閱讀 51,155評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音兽叮,去河邊找鬼芬骄。 笑死,一個(gè)胖子當(dāng)著我的面吹牛鹦聪,可吹牛的內(nèi)容都是我干的账阻。 我是一名探鬼主播,決...
    沈念sama閱讀 40,041評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼泽本,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼淘太!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,903評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤蒲牧,失蹤者是張志新(化名)和其女友劉穎撇贺,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體冰抢,經(jīng)...
    沈念sama閱讀 45,319評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡松嘶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,539評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了挎扰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片翠订。...
    茶點(diǎn)故事閱讀 39,703評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖遵倦,靈堂內(nèi)的尸體忽然破棺而出尽超,到底是詐尸還是另有隱情,我是刑警寧澤梧躺,帶...
    沈念sama閱讀 35,417評(píng)論 5 343
  • 正文 年R本政府宣布橙弱,位于F島的核電站,受9級(jí)特大地震影響燥狰,放射性物質(zhì)發(fā)生泄漏棘脐。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,013評(píng)論 3 325
  • 文/蒙蒙 一龙致、第九天 我趴在偏房一處隱蔽的房頂上張望蛀缝。 院中可真熱鬧,春花似錦目代、人聲如沸屈梁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽在讶。三九已至,卻和暖如春霜大,著一層夾襖步出監(jiān)牢的瞬間构哺,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評(píng)論 1 269
  • 我被黑心中介騙來泰國打工战坤, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留曙强,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,711評(píng)論 2 368
  • 正文 我出身青樓途茫,卻偏偏與公主長得像碟嘴,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子囊卜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,601評(píng)論 2 353

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

  • 一娜扇、meta標(biāo)簽的效果 移動(dòng)端頁面一般會(huì)在head頭部添加如下meta標(biāo)簽错沃。 該meta標(biāo)簽是否添加對(duì)頁面渲染的影...
    nimw閱讀 3,542評(píng)論 0 5
  • 在移動(dòng)互聯(lián)網(wǎng)快速發(fā)展的今天,手機(jī)的種類和尺寸越來越多雀瓢,作為前端的小伙伴們可能會(huì)越來越頭疼枢析,但又不得不去適配一款又一...
    keenjaan閱讀 26,816評(píng)論 9 86
  • title: 移動(dòng)端Web頁面適配淺析date: 2018-01-31 16:38:01tags: 移動(dòng)端 適配 ...
    豆板兒閱讀 12,275評(píng)論 0 16
  • 我們第一次接觸移動(dòng)web的時(shí)候登疗,直觀印象樣應(yīng)該是:屏幕比pc小很多,所以對(duì)pc端設(shè)計(jì)的界面嫌蚤,不一定(或者說不完全)...
    Scaukk閱讀 16,847評(píng)論 6 46
  • 唯獨(dú)今夜脱吱, 我在月光下等待智政。 城市的其它人都走了, 只剩下你和我箱蝠, 我看著你续捂,我想你; 無論向前還是向后, 你都離...
    廣廈閱讀 206評(píng)論 4 0