移動(dòng)端開(kāi)發(fā)之前端

1.移動(dòng)端迷之視口

? ? 為什么我稱(chēng)他為“迷之視口”,因?yàn)槠鋵?shí)我聽(tīng)過(guò)很多人的分享,來(lái)講解移動(dòng)端視口的問(wèn)題,但我好像都沒(méi)太懂。尷尬~_~,? 其實(shí)我也不確定我能否將我的理解表述清楚,再次尷尬~_~。

說(shuō)到視口的事情,要提一個(gè)大神:

Peter-Paul Koch(另一個(gè)更廣為人知的名字是PPK)是HTML、CSS和JavaScript方面的專(zhuān)家,尤其擅長(zhǎng)解決瀏覽器兼容性問(wèn)題。在2009年,他就從傳統(tǒng)的桌面瀏覽器和網(wǎng)站轉(zhuǎn)而研究移動(dòng)Web領(lǐng)域,并且從未間斷。

ppk大神對(duì)于移動(dòng)設(shè)備上的viewport有著非常多的研究(第一篇,第二篇,第三篇),有興趣的同學(xué)可以去看一下,本文中有很多數(shù)據(jù)和觀(guān)點(diǎn)也是出自那里。你也可以在StackOverflow上找到一些對(duì)此描述的相互補(bǔ)充,例如:[1],[2],有興趣的童鞋也可以看看。

ppk認(rèn)為,移動(dòng)設(shè)備上有三個(gè)viewport。

1:layout viewport (布局視口)

2:visual viewport (視覺(jué)視口)

3:ideal viewport ? (完美視口)

layout viewport(布局視口)

首先,移動(dòng)設(shè)備上的瀏覽器認(rèn)為自己必須能讓所有的網(wǎng)站都正常顯示,即使是那些不是為移動(dòng)設(shè)備設(shè)計(jì)的網(wǎng)站。但如果以瀏覽器的可視區(qū)域作為viewport的話(huà),因?yàn)橐苿?dòng)設(shè)備的屏幕都不是很寬,所以那些為桌面瀏覽器設(shè)計(jì)的網(wǎng)站放到移動(dòng)設(shè)備上顯示時(shí),必然會(huì)因?yàn)橐苿?dòng)設(shè)備的viewport太窄,而擠作一團(tuán),甚至布局什么的都會(huì)亂掉。也許有人會(huì)問(wèn),現(xiàn)在不是有很多手機(jī)分辨率都非常大嗎,比如768x1024,或者1080x1920這樣,那這樣的手機(jī)用來(lái)顯示為桌面瀏覽器設(shè)計(jì)的網(wǎng)站是沒(méi)問(wèn)題的吧?前面我們已經(jīng)說(shuō)了,css中的1px并不是代表屏幕上的1px,你分辨率越大,css中1px代表的物理像素就會(huì)越多,devicePixelRatio的值也越大,這很好理解,因?yàn)槟惴直媛试龃罅?,但屏幕尺寸并沒(méi)有變大多少,必須讓css中的1px代表更多的物理像素,才能讓1px的東西在屏幕上的大小與那些低分辨率的設(shè)備差不多,不然就會(huì)因?yàn)樘《床磺?。所以?080x1920這樣的設(shè)備上,在默認(rèn)情況下,也許你只要把一個(gè)div的寬度設(shè)為300多px(視devicePixelRatio的值而定),就是滿(mǎn)屏的寬度了?;氐秸}上來(lái),如果把移動(dòng)設(shè)備上瀏覽器的可視區(qū)域設(shè)為viewport的話(huà),某些網(wǎng)站就會(huì)因?yàn)関iewport太窄而顯示錯(cuò)亂,所以這些瀏覽器就決定默認(rèn)情況下把viewport設(shè)為一個(gè)較寬的值,比如980px,這樣的話(huà)即使是那些為桌面設(shè)計(jì)的網(wǎng)站也能在移動(dòng)瀏覽器上正常顯示了。ppk把這個(gè)瀏覽器默認(rèn)的viewport叫做layout viewport。這個(gè)layout viewport的寬度可以通過(guò)document.documentElement.clientWidth來(lái)獲取。

Apple對(duì)于這個(gè)問(wèn)題的處理地是在iOS Safari中定義了一個(gè)viewport meta標(biāo)簽,用來(lái)創(chuàng)建一個(gè)虛擬的布局視口(layout viewport),而這個(gè)視口的分辨率接近于PC顯示器,Apple將其定義為980px(其他廠(chǎng)商各有不同)。

這就很好的解決了早期的頁(yè)面在手機(jī)上顯示的問(wèn)題,由于兩者之間的寬度趨近,CSS只需要像在PC上那樣渲染頁(yè)面就行,原有的頁(yè)面結(jié)構(gòu)不會(huì)被破壞。

描述大致如下,數(shù)值不一定持續(xù)準(zhǔn)確,廠(chǎng)商可能更改,但這個(gè)絕對(duì)值其實(shí)并非特別重要:

iOS, Android基本都是: 980px ? ? ? ? ? ? ? ? ? ? ? ? ?

BlackBerry: 1024px

visual viewport(視覺(jué)視口)

然而,layout viewport?的寬度是大于瀏覽器可視區(qū)域的寬度的,所以我們還需要一個(gè)viewport來(lái)代表 瀏覽器可視區(qū)域的大小,來(lái)承載layout viewport ,ppk把這個(gè)viewport叫做visual viewport。這個(gè)視口可以簡(jiǎn)單的認(rèn)為是手持設(shè)備物理屏幕的可視區(qū)域,這是一個(gè)比較直觀(guān)的概念,因?yàn)槟隳芸吹靡?jiàn)你的手機(jī)屏幕。visual viewport的寬度可以通過(guò)window.innerWidth來(lái)獲取,但在A(yíng)ndroid 2, Oprea mini 和 UC 8中無(wú)法正確獲取。

對(duì)于visual viewport,開(kāi)發(fā)者一般只需要知道它的存在和概念就行,因?yàn)闊o(wú)法對(duì)它進(jìn)行任何設(shè)置或者修改。很明顯,visual viewport的尺寸不會(huì)是一個(gè)固定的值,甚至每款設(shè)備都可能不同。大致列幾種常見(jiàn)設(shè)備的visual viewport尺寸:

iPhone4~iPhone5S: 320*480px

iPhone6~iPhone6S: 375*627px

iPhone6 Plus~iPhone6S Plus: 414*736px

ideal viewport? (完美視口)

為了更好的適配移動(dòng)端或者只為移動(dòng)端設(shè)計(jì)的應(yīng)用,單有布局視口和視覺(jué)視口還是不夠的。

我們還需要一個(gè)視口,它類(lèi)似于布局視口,但寬度和視覺(jué)視口相同,這就是完美視口(ideal viewport)。所謂的完美適配指的是,首先不需要用戶(hù)縮放和橫向滾動(dòng)條就能正常的查看網(wǎng)站的所有內(nèi)容;其次,顯示的文字的大小是合適,比如一段14px大小的文字,不會(huì)因?yàn)樵谝粋€(gè)高密度像素的屏幕里顯示得太小而無(wú)法看清,理想的情況是這段14px的文字無(wú)論是在何種密度屏幕,何種分辨率下,顯示出來(lái)的大小都是差不多的。當(dāng)然,不只是文字,其他元素像圖片什么的也是這個(gè)道理。ppk把這個(gè)viewport叫做ideal viewport,也就是第三個(gè)viewport——移動(dòng)設(shè)備的理想viewport。


我們?cè)陂_(kāi)發(fā)移動(dòng)設(shè)備的網(wǎng)站時(shí),最常見(jiàn)的的一個(gè)動(dòng)作就是把下面這個(gè)東西復(fù)制到我們的head標(biāo)簽中:

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />

該meta標(biāo)簽的作用是讓當(dāng)前viewport的寬度等于設(shè)備的寬度,同時(shí)不允許用戶(hù)手動(dòng)縮放。也許允不允許用戶(hù)縮放不同的網(wǎng)站有不同的要求,但讓viewport的寬度等于設(shè)備的寬度,這個(gè)應(yīng)該是大家都想要的效果,如果你不這樣的設(shè)定的話(huà),那就會(huì)使用那個(gè)比屏幕寬的默認(rèn)viewport,也就是說(shuō)會(huì)出現(xiàn)橫向滾動(dòng)條。

一般viewport 有6種屬性設(shè)置,這些屬性可以同時(shí)使用,也可以單獨(dú)使用或混合使用,多個(gè)屬性同時(shí)使用時(shí)用逗號(hào)隔開(kāi)就行了。此外,在安卓中還支持? target-densitydpi? 這個(gè)私有屬性,它表示目標(biāo)設(shè)備的密度等級(jí),作用是決定css中的1px代表多少物理像素。

target-densitydpi值可以為一個(gè)數(shù)值或 high-dpi 、 medium-dpi、 low-dpi、 device-dpi 這幾個(gè)字符串中的一個(gè)

特別說(shuō)明的是,當(dāng) target-densitydpi=device-dpi 時(shí), css中的1px會(huì)等于物理像素中的1px。因?yàn)檫@個(gè)屬性只有安卓支持,并且安卓已經(jīng)決定要廢棄?target-densitydpi?這個(gè)屬性了,所以這個(gè)屬性我們要避免進(jìn)行使用? 。

width被用來(lái)定義layout viewport的寬度,如果不指定該屬性(或者移除viewport meta標(biāo)簽),則layout viewport寬度為廠(chǎng)商默認(rèn)值。如:iPhone為980px;

視口小結(jié):

第一、如果不設(shè)置meta viewport標(biāo)簽,那么移動(dòng)設(shè)備上瀏覽器默認(rèn)的寬度值為800px,980px,1024px等這些,總之是大于屏幕寬度的。這里的寬度所用的單位px都是指css中的px,它跟代表實(shí)際屏幕物理像素的px不是一回事。

第二、每個(gè)移動(dòng)設(shè)備瀏覽器中都有一個(gè)理想的寬度,這個(gè)理想的寬度是指css中的寬度,跟設(shè)備的物理寬度沒(méi)有關(guān)系,在css中,這個(gè)寬度就相當(dāng)于100%的所代表的那個(gè)寬度。我們可以用meta標(biāo)簽把viewport的寬度設(shè)為那個(gè)理想的寬度,如果不知道這個(gè)設(shè)備的理想寬度是多少,那么用device-width這個(gè)特殊值就行了,同時(shí)initial-scale=1也有把viewport的寬度設(shè)為理想寬度的作用。所以,我們可以使用。來(lái)得到一個(gè)理想的viewport(也就是前面說(shuō)的ideal viewport)。為什么需要有理想的viewport呢?比如一個(gè)分辨率為320x480的手機(jī)理想viewport的寬度是320px,而另一個(gè)屏幕尺寸相同但分辨率為640x960的手機(jī)的理想viewport寬度也是為320px,那為什么分辨率大的這個(gè)手機(jī)的理想寬度要跟分辨率小的那個(gè)手機(jī)的理想寬度一樣呢?這是因?yàn)?,只有這樣才能保證同樣的網(wǎng)站在不同分辨率的設(shè)備上看起來(lái)都是一樣或差不多的。實(shí)際上,現(xiàn)在市面上雖然有那么多不同種類(lèi)不同品牌不同分辨率的手機(jī),但它們的理想viewport寬度歸納起來(lái)無(wú)非也就 320、360、384、400等幾種,都是非常接近的,理想寬度的相近也就意味著我們針對(duì)某個(gè)設(shè)備的理想viewport而做出的網(wǎng)站,在其他設(shè)備上的表現(xiàn)也不會(huì)相差非常多甚至是表現(xiàn)一樣的。

2.移動(dòng)端應(yīng)該如何動(dòng)態(tài)設(shè)置字體大???


1.px單位在PC上很流行,在手機(jī)屏幕上一看,MD的,同樣的12px卻小的跟螞蟻似的。

2.好不容易在iPhone上調(diào)的正常了,換個(gè)菊花牌手機(jī),MD不堪入目了。

3.知道了rem的用法,但是html的font-size到底是多少才合適啊啊啊,MD~。

好了,那么現(xiàn)在來(lái)解決這些問(wèn)題。

在解決之前,要了解一些你可能不想了解的東東

1.物理像素(physical pixel)

我們看到的每個(gè)屏幕都是由一顆顆我們?nèi)庋垭y以看到的小顆粒(物理像素)組成的。

2.邏輯像素(css)

是計(jì)算機(jī)坐標(biāo)系統(tǒng)中的一個(gè)點(diǎn),這個(gè)點(diǎn)代表一個(gè)可以由程序使用的虛擬像素(比如說(shuō)CSS像素)。

3.設(shè)備的像素比(device pixel ratio)簡(jiǎn)稱(chēng)DPR

它的數(shù)值體現(xiàn)了物理像素和邏輯像素之間的關(guān)系,用公式可以計(jì)算出該設(shè)備的DPR的大?。?/p>

DPR= 物理像素 / 邏輯像素 [eg: 2=640/320;]

4.PPI (Pixels Per Inch所表示的是每英寸所擁有的像素(Pixel)數(shù)目)

ppi可以理解為屏幕像素密度;

那么了解了上面這些概念,就可以知道,為什么css在pc上寫(xiě)著font-size=12px;但是換到手機(jī)上卻變小了?因?yàn)镈PR啊啊啊,大嬸~。

沒(méi)錯(cuò),我們?cè)陔娔X屏幕上的DPR是1,但是手機(jī)卻不同,可能是它可能是2,也可能是3。獲取設(shè)備DPR的方法還是有的:

1.在JavaScript中,通過(guò)window.devicePixelRatio來(lái)獲取

2.在css中,可以通過(guò)-webkit-device-pixel-ratio,-webkit-min-device-pixel-ratio和-webkit-max-device-pixel-ratio進(jìn)行媒體查詢(xún),對(duì)不同DPR的設(shè)備,做一些樣式適配(這里只針對(duì)webkit內(nèi)核的瀏覽器和webview)。

下面把幾個(gè)常用的列舉出來(lái):

一,用媒體查詢(xún)來(lái)設(shè)置html的font-size:

@media screen and (min-width:320px)?{html{font-size:14px;}}

…… ……

二,用LESS或者SASS函數(shù)進(jìn)行轉(zhuǎn)換

SASS:

sass function px to rem


LESS:

less function px to rem


三,淘寶貌似是用JS來(lái)做這方面的轉(zhuǎn)換,這個(gè)我先暫時(shí)不作說(shuō)明;

四,高手在民間,我相信一定也會(huì)有其它的方法;

總之這些知識(shí)也可以說(shuō)是常識(shí),既不高深也不新奇,它僅僅是一點(diǎn)觀(guān)念轉(zhuǎn)變。當(dāng)我們掌握了viewport,那么意味著你已經(jīng)大致了解了移動(dòng)平臺(tái)與PC平臺(tái)的不同,可以幫助我們更專(zhuān)注而細(xì)致的去解決某些平臺(tái)差異問(wèn)題。

最后給大家分享一個(gè)有趣的現(xiàn)象,


戳鏈接打開(kāi)看

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容