移动端适配--meta标签玩的是什么
基本一直都在做移動(dòng)端的開(kāi)發(fā),rem布局也寫(xiě)了很久,不過(guò)對(duì)于實(shí)現(xiàn)的原理有些模棱兩可的盲點(diǎn),自己總結(jié)一下留著以后回顧。 本文分以下幾個(gè)層面,主打用最最通俗的語(yǔ)言來(lái)闡述。
布局小例子----常見(jiàn)困惑
iphone6尺寸是375*667,那給div設(shè)置寬度375px后,為什么寬度不是充滿(mǎn)屏幕呢? 代碼如下:(為了方面看,我全截圖吧)
然后運(yùn)行結(jié)果如下:這是為什么呢? 來(lái)看一下頁(yè)面寬度是多少
哦?這個(gè)980是哪里來(lái)的呢?帶著疑問(wèn)引出本文的主角----viewportviewport作用
viewport是什么?翻譯過(guò)來(lái)就是視窗的意思,只不過(guò)在移動(dòng)端,視窗稍微有點(diǎn)繞。在解釋這個(gè)之前,不得不引出幾個(gè)詞匯,分別是物理像素(physical pixel),設(shè)備獨(dú)立像素(density-indenpendent pixel),設(shè)備像素比(device pixel ratio),要怎么通俗理解這三個(gè)詞呢? 容我找找網(wǎng)上的圖。
物理像素
手機(jī)屏幕顯示圖像的最小單元。上圖中iphone4和3gs,同樣大小尺寸情況下,iphone4明顯畫(huà)面細(xì)膩很多,這是為什么?屏幕尺寸沒(méi)變,分辨率提升,畫(huà)面就細(xì)膩了,更通俗一點(diǎn)的就是iphone4用來(lái)顯示圖像的點(diǎn)更多了,把屏幕上的物理像素點(diǎn)想象成整齊排列的點(diǎn)陣,3gs有320 * 480個(gè)點(diǎn)而ip4有960 * 640個(gè)點(diǎn)。
設(shè)備獨(dú)立像素
如果把物理像素看做是負(fù)責(zé)顯示圖像的硬件的話(huà),那么設(shè)備獨(dú)立像素是什么呢?我們平時(shí)寫(xiě)的css像素就是設(shè)備獨(dú)立像素的一種了。而這1px的css像素,在不同的手機(jī)卻是呈現(xiàn)不同的,為什么ip4畫(huà)面細(xì)膩?就是人家用4個(gè)物理像素點(diǎn)來(lái)描繪一個(gè)css像素。
設(shè)備像素比
也就是常說(shuō)的dpr , dpr = 物理像素/設(shè)備獨(dú)立像素(注意,是在某一方向的,x軸或者y軸) , 理解這個(gè)很重要,iphone6的dpr是2,iphonex的dpr是3。
dpr是2的情況下css畫(huà)一個(gè)點(diǎn),這個(gè)點(diǎn)是由4個(gè)物理像素點(diǎn)提供支撐的。畫(huà)一條線(xiàn)的話(huà),那這條線(xiàn)其實(shí)是2排物理像素點(diǎn)支撐的。
同理,dpr是3的情況下css畫(huà)一個(gè)點(diǎn),這個(gè)點(diǎn)是由9個(gè)物理像素點(diǎn)提供支撐的。畫(huà)一條線(xiàn)的話(huà),那這條線(xiàn)其實(shí)是3排物理像素點(diǎn)支撐的。
viewport登場(chǎng)
在移動(dòng)端,視窗分為三種,分別為layoutviewport、visualviewport、idealviewport。可以先記住一個(gè),idealviewport就認(rèn)為是設(shè)備寬度就好,iphone6就是375,iphone6p 就是414 ,其余兩個(gè)先看我下面例子吧。
對(duì)于上面的代碼做簡(jiǎn)單修改 簡(jiǎn)要說(shuō)明下: js動(dòng)態(tài)生成一個(gè)關(guān)于viewport的標(biāo)簽,meta標(biāo)簽可以控制viewport的縮放。window.devicePixelRatio : 查看設(shè)備dpr
document.documentElement.clientWidth : 查看layoutviewport寬度
window.visualViewport.width : 查看visualViewport寬度
window.innerWidth : 查看文檔寬度
只設(shè)置initial-scale = 1 不加meta標(biāo)簽 initial-scale=2, width=device-width initial-scale= 0.5 , width=device-width需要來(lái)個(gè)小結(jié)了:
layoutviewport
默認(rèn)是980 (針對(duì)ios)
設(shè)置縮放為1 寬度為設(shè)備寬度時(shí):就是375(設(shè)備寬度)
設(shè)置縮放為2 寬度為設(shè)備寬度時(shí):還是375(設(shè)備寬度)
設(shè)置縮放為0.5 寬度為設(shè)備寬度時(shí):是750(設(shè)備寬度的2倍)
layoutviewport 取設(shè)置的寬度或者visualviewport他們中的最大值
visualviewport
默認(rèn)是980 (針對(duì)ios)
設(shè)置縮放為1 寬度為設(shè)備寬度時(shí):就是375(設(shè)備寬度)
設(shè)置縮放為2 寬度為設(shè)備寬度時(shí):是187.5(設(shè)備寬度一半)
設(shè)置縮放為0.5 寬度為設(shè)備寬度時(shí):是750(設(shè)備寬度的2倍)
其實(shí)是有公式的,visualviewport = 設(shè)備寬度/縮放。也就是visualviewport = idealviewport / initial-scale
idealviewport
顧名思義,是理想視窗意思,就是指的設(shè)備尺寸,主要用來(lái)和initial-scale配合,計(jì)算也就是visualviewport用的。
那layoutviewport和visualviewport負(fù)責(zé)什么
其實(shí)也是可以從名字就看出來(lái)的,layoutviewport布局視窗,visualviewport視覺(jué)視窗。 這里加個(gè)圖,initial-scale = 1 width=devide-width,然后box寬度設(shè)置750px,發(fā)現(xiàn)html寬度在375,頁(yè)面出現(xiàn)滾動(dòng)條,并且,有意思的是,是按照375寬度排列的,只有那個(gè)設(shè)置了寬度是750的box寬度變大,所以layoutviewport負(fù)責(zé)布局,visualviewport負(fù)責(zé)視覺(jué),是不是有了點(diǎn)直觀印象了,如下圖:
layoutviewport和visualviewport不一致的情況下,頁(yè)面就會(huì)出現(xiàn)滾動(dòng)條。(截圖滾動(dòng)條不明顯)viewport和移動(dòng)端適配關(guān)系
這里就更不好用語(yǔ)言描述了,有些抽象。回顧上文,知道iphone3gs iphone6 iphonex三者屏幕尺寸大小不同,dpr的話(huà),前兩者是1 2 而 iphonex是3。那如何使得一張前端頁(yè)面,在每個(gè)手機(jī)看起來(lái)都是一樣大呢?以iphone6和iphonex來(lái)舉例,雖然屏幕寬度都是375,但是iphonex卻擁有更加密集的物理像素點(diǎn)陣。iphone3gs更不用說(shuō),320的寬度,dpr又是1。 倘若我們規(guī)定,只用設(shè)備的物理像素,來(lái)繪制css的像素,要求一比一的繪制,那一張320px寬度的頁(yè)面,在3個(gè)手機(jī)上的展示一定大致如下:
這只是一個(gè)示意圖,也許并不精準(zhǔn)。不過(guò)大體就是這樣的,ip6寬度有著750個(gè)物理像素點(diǎn),iphonex寬度有1125個(gè)物理像素點(diǎn),所以根據(jù)上面的假想要求,畫(huà)出來(lái)的一定是這樣的。那么想要iphone6畫(huà)出的這個(gè)320px的頁(yè)面也充滿(mǎn)屏幕的話(huà),要怎么做?首先假如設(shè)置initial-scale=1, width=device-width,這種情況下,寬度375的iphone6畫(huà)出寬度320px的前端頁(yè)面大致什么樣呢?
就是這樣的效果圖,但是需要注意的是,此時(shí)的一條橫線(xiàn),3gs是用一排物理像素點(diǎn)描繪的,而iphone6確是用了兩排物理像素點(diǎn)!也就引申出了經(jīng)典的1px邊框問(wèn)題。iphone6的物理像素點(diǎn)再密集,用兩排畫(huà)一條線(xiàn)和只用一排畫(huà)一條線(xiàn),還是能看出差距的。那么這種情況是不可取的。那假如設(shè)置initial-scale=0.5, width=device-width,這種情況下呢?我也想畫(huà)出看著和iphone3gs一樣視覺(jué)大小的圖像的話(huà),(注意是視覺(jué)大小哦,就是拿著兩手機(jī),看著屏幕中的圖一樣大。)要怎么做呢?根據(jù)上面知識(shí),對(duì)視窗進(jìn)行了0.5縮放,那此時(shí)肉眼看到視覺(jué)是不是就和上面提到的這個(gè)圖一致了呢? 所以,我們需要在這種情況下,寫(xiě)css是寬度寫(xiě)為640px,就能看起來(lái)和上面initial-scale=1, width=device-width一樣的效果了!也解決了1px像素問(wèn)題!rem適配方案
rem是什么,這個(gè)大家應(yīng)該都清楚了。就是給html設(shè)置字體大小,假如是30px,那么頁(yè)面中寫(xiě)了2rem那就是60px。 設(shè)計(jì)給出一張?jiān)O(shè)計(jì)稿,頁(yè)面寬度是750px,其中一個(gè)div標(biāo)注了是寬度375px。如何做到在iphone6和iphonex中,看到的這個(gè)div都是屏幕寬度的一半呢?
相信大家都已經(jīng)有答案了。
對(duì)于iphone6 設(shè)置initial-scale=0.5, width=device-width,然后就直接寫(xiě)375px就好 對(duì)于iphonex 設(shè)置initial-scale=1/3, width=device-width,然后就直接寫(xiě)(375*(3/2))px就好。 缺點(diǎn)就是需要我們自行計(jì)算。
rem方案 : 設(shè)計(jì)稿750px,div標(biāo)注375px,對(duì)于iphone6 設(shè)置initial-scale=0.5, width=device-width,如果html設(shè)置font-size為75px,那div我們就直接寫(xiě)5rem就行了。然后適配到iphonex中時(shí),不需要改變div的5rem,只需改變?cè)趇phonex中html的字體以及頁(yè)面縮放,設(shè)置 iphonex中 initial-scale=1/3, width=device-width,然后設(shè)置html字體為112.5px,此時(shí)的5rem為562.5px,剛好是屏幕1125的一半。
flexible.js原理
上面關(guān)于rem適配已經(jīng)思路實(shí)現(xiàn),現(xiàn)在還差幾個(gè)環(huán)節(jié),就是為什么設(shè)置iphone6是0.5縮放,iphonex是1/3縮放呢?然后又根據(jù)什么設(shè)置的html字體?
答: dpr 。那么又是怎么設(shè)置的?flexible.js就要登場(chǎng)了,flexible.js是手淘的前移動(dòng)端適配解決方案,為什么是前方案,因?yàn)槟壳盀g覽器對(duì)于vw vh支持的更加友好,這個(gè)后面再說(shuō)。看看flexible.js做了什么吧,直接截圖一些代碼吧。
感覺(jué)沒(méi)什么好解釋的,就是獲取設(shè)備dpr,然后確定scale嘛
然后把meta標(biāo)簽塞到html中
因?yàn)橐呀?jīng)縮放好了頁(yè)面,此時(shí)iphonex的話(huà),這個(gè)width拿到的就是1125了,rem就112.5并設(shè)置到html字體中不過(guò)rem我們自己來(lái)計(jì)算的話(huà)就很繁瑣了,如給的iphone6,寬度750的設(shè)計(jì)稿,標(biāo)注的375px,我們就寫(xiě)375px就好,當(dāng)然是寫(xiě)成px2rem(375)這樣。
關(guān)于flexible.js的實(shí)現(xiàn)原理,我也就是挑重點(diǎn)的說(shuō)了說(shuō),還是建議大家去看大漠老師寫(xiě)的源碼,一百多行代碼而已,挺好的,也很容易看懂,不過(guò)要想清楚為什么要那么做,就是我上面大篇幅寫(xiě)的東東啦~
vw vh
關(guān)于vw vh其實(shí)是將視口寬度 window.innerWidth 和視口高度 window.innerHeight 等分為 100 份,并且此時(shí)的視窗并不會(huì)隨著 viewport 的不同設(shè)置而改變。
vw : 1vw 為視口寬度的 1%
vh : 1vh 為視口高度的 1%
上面說(shuō)的設(shè)計(jì)稿為 750px,那么 1vw = 7.5px,100vw = 750px。此時(shí)給的不是750設(shè)計(jì)稿也沒(méi)所謂,假如給1000px的設(shè)計(jì)稿,那我們寫(xiě)的1v我就是10px。其實(shí)這不就是rem做的事嗎?只不過(guò)我們用rem+flexible.js繞了一圈的感覺(jué)
后面具體項(xiàng)目中新頁(yè)面用vw試試,有什么坑 待補(bǔ)充
flexible.js VS vw vh
作為后面要補(bǔ)充的點(diǎn)吧,vw等我項(xiàng)目具體實(shí)操一波,再來(lái)補(bǔ)這個(gè)
轉(zhuǎn)載于:https://juejin.im/post/5ce1449ff265da1bcd37a8cd
總結(jié)
以上是生活随笔為你收集整理的移动端适配--meta标签玩的是什么的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 基于视频会议系统的应急指挥项目建设方案
- 下一篇: 测试开发面试准备之Selenium 工作