移動端前端開發較PC端開發最大的不同之一就是需要適配各種大小不同的屏幕尺寸,如何實現辛苦編寫的 H5 頁面在各個機型屏幕上都能得到最佳展示?設計師設計的視覺稿為什麼都是2倍稿? ...
移動端 H5 頁面不可遺忘的 meta 標簽 viewport
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
這行代碼的作用是設置視口的寬度(其實就是頁面的寬度)等於設備寬度,頁面不縮放並且也不允許用戶進行縮放。
把一個普通的PC端頁面(未加入上面 meta 標簽的)直接放在手機端訪問是可以展示完全的,但是頁面明顯經過縮放。可以用 alert(document.body.clientHeight)
獲取一下頁面寬度,你會發現,大部分頁面的寬度都是980px。再用alert(window.innerWidth)
獲取一下設備寬度,很明顯,手機端自動將980px的頁面縮放到了window.innerWidth
的寬度才得以完全展示。但這不是我們想要的效果,我們想要的是未經縮放,以最佳樣式展現的Web頁面。每一個移動端頁面都應該首先加入上面這行 meta 標簽,這樣才能確保頁面得到了最佳的展現形式。
CSS 屏幕適配之媒體查詢(media query)
PC 端常用的CSS測量單位是 px,而移動端常用的卻是 rem。這樣做的原因仍然是為了適配多種屏幕尺寸。怎麼適配呢?首先需要弄清楚rem單位,rem是相對於DOM根元素(也就是)的字體大小的度量單位。比如說我們設置了 html{ font-size: 16px }
,然後給具體的DOM設置 p{ font-size: 2rem; height: 4rem; }
,其實就相當於設置了 p{ font-size: 2*16px; height: 4*16px; }
,也就是 1rem = 1*(html的fontSize)
,2.5rem=2.5*(html的fontSize)
。這樣就很清楚了,我們只需要控制不同屏幕尺寸下 html 的 fontSize,頁面上所有使用 rem 度量的DOM的尺寸都會相應改變。比如以下適配代碼:
html{font-size: 18px}
@media only screen and (min-width:360px){html{font-size: 20px!important}}
@media only screen and (min-width:375px){html{font-size: 21px!important}}
@media only screen and (min-width:400px){html{font-size: 22px!important}}
@media only screen and (min-width:414px){html{font-size: 23px!important}}
@media only screen and (min-width:480px){html{font-size: 24px!important}}
@media only screen and (min-width:540px){html{font-size: 26px!important}}
@media only screen and (min-width:640px){html{font-size: 28px!important}}
@media only screen and (min-width:768px){html{font-size: 32px!important}}
@media only screen and (min-width:960px){html{font-size: 36px!important}}
@media only screen and (min-width:1024px){html{font-size: 46px!important}}
上面一塊代碼的意思就是:
- 屏幕尺寸小於360px時,html 的 fontSize 就是18px;
- 當屏幕尺寸位於區間 [360px, 375px] 時,html 的 fontSize 就是 20px;
- 當屏幕尺寸位於區間 [375px, 400px] 時,html 的 fontSize 就是 21px;
- 以此類推,如果屏幕尺寸大於 1024px 的話,html 的 fontSize 都是46px。
上面CSS媒體查詢是一個區間一個區間地進行適配的,當然也可以使用 JS 進行更精細的適配,但歸根結底無非都是通過改變viewport的scale值和根節點html的fontSize值進行整體調整的。
設計師出 2 倍視覺稿,前端還原成 1 倍頁面,是在瞎折騰?
這樣做當然是有原因的,在解釋這個問題之前,先介紹一些像素小知識。
物理像素(也叫設備像素)
物理像素是顯示器上最小的顯示單元,電腦、電視、手機、平板這些電子設備的屏幕都是由一個個物理像素點組成的,連點成線,線再成面。在系統的調度下,每一個物理像素可以且僅可以顯示單獨的顏色值和亮度值。
比如 iPhone5 的屏幕有 640x1136 個物理像素,註意到了嗎,物理像素的總量其實就是所謂的解析度。解析度越高,物理像素點就越多,屏幕上能表現的顏色值就越多,畫面就越細膩。設備獨立像素(也叫CSS像素,邏輯像素)
設備獨立像素的學術解釋就是電腦坐標系統中的一個點,這個點代表一個可以由程式使用並控制的虛擬像素,然後由底層系統的程式轉換為物理像素。怪不得都不喜歡去看這些學術性的解釋,真的是佶屈聱牙,抽象難懂。
其實在我看來,設備獨立像素就是UI設計師設計工具(如Photoshop)中的像素,而UI設計師通常就在電腦上進行設計作業的,所以設備獨立像素其實就是電腦屏幕上的物理像素。每一個設備獨立像素可以表示一個或多個顏色值和亮度值。
iPhone5 屏幕的設備獨立像素數量是 320x568,為什麼這麼說呢,因為在普通電腦屏幕上,1 個設備獨立像素是對應著 1 個物理像素的,你把 iPhone5 的屏幕貼在電腦屏幕上,那一塊和iPhone5屏幕等大的電腦屏幕區域物理像素數量是多少,沒錯正好是320x568。嘿嘿,明白了吧,設備獨立像素是設計師和前端工程師進行作業時的測量單位。設備像素比(Device Pixel Ratio)
DPR 的計算公式如下:
設備像素比 = 設備像素/設備獨立像素 // 在某一方向上,x方向或y方向
DPR 的意義就是用來表示設備會分配多少個物理像素來展示1個設備獨立像素,一般是DPRxDPR個。比如由公式可計算出 iPhone5 的 DPR 為 2,那麼 iPhone5 就會分配 2x2=4 個物理像素來展示1個設備獨立像素。
其實現在市面上的很多機型 DPR 都是 2,也因此UI設計師為移動端所做的設計圖通常是 2 倍圖。為什麼這樣做呢,拿iPhone5來說吧,如果設計圖尺寸是320x568也就是等於設備的邏輯像素數量,當然是可以的,但這樣就浪費了硬體優勢了,因為設計圖上的1個CSS像素映射到手機屏幕上,手機屏幕會分配4個物理像素來展示它,很顯然,4個物理像素的顏色值和亮度值都一樣。而如果設計成2倍圖,那就是等於設備的物理像素數量了,設計師可以盡情發揮,設計更細膩的畫面,手機屏幕也可以充分發揮出高解析度的優勢。設計成2倍圖會出現一個問題,比如本來一張圖片是希望它在手機上呈現為 100x100(CSS像素)的尺寸,結果設計師把它設計成200x200(CSS像素)的,如果直接放在手機上,也會呈現 200x200(CSS像素)的,而不是100x100(CSS像素),就會顯得非常大,這時候就輪到前端工程師隆重登場了,前端在還原設計圖時所有尺寸都應該減半,也就是還原成1倍頁面。比如設計圖上的200x200(CSS像素)的尺寸,在頁面上對應地寫成100x100(CSS像素),這樣它在頁面上就會占據100x100個CSS像素了,手機系統會分配100x100x4個物理像素去展示這100x100個CSS像素,這樣就可以充分展現設計圖中的色彩信息了。