移動端開發中,有一些基本概念需要理解清楚,才能更好的組織編程邏輯。在剛接觸時,移動端視口的縮放和rem單位的縮放搞混淆了,弄得自己很蒙圈。所以仔細總結下自己的理解。
移動端的適配,我理解為兩點:
第一點就是視口的縮放配置,牽扯出視口和像素等概念。目的是為讓我們的CSS樣式中邏輯像素匹配到手機終端的物理像素,讓網頁視圖適合手機屏幕。雖然在代碼中只是一個語句就解決的問題,但要理解它,要弄懂很多概念。《關於像素Pixel歷史的詳解看下一篇文檔》
第二點就是rem單位的使用,目的是為了我們只需要一份代碼就可以適應大部分不同屏幕的手機。
以上兩點雖然實現的目的不同,但采用的方法原理基本一樣,都用到縮放因子來解決問題。第一種是DPR,第二種是rem。
自適應:指在同一終端下,頁面布局能根據視口本身變化而自動調節布局,比如PC端瀏覽器頁面尺寸的變化,resize事件;
響應式:指頁面能在根據檢測到的不同終端類型,自動調整布局。比如手機、平板、電腦等不同終端下的響應。媒體查詢@media的語法,要熟悉。
一、視口
視口,從字面上用常規思維可以理解為人眼的可視區域。在移動端開發中,常將視口抽象划分為布局視口、視覺視口和理想視口。為什么這么划分呢?我覺得還是為了讓我們更好理解CSS像素和設備像素的區別,也就是邏輯像素和物理像素的區別。
在PC端開發書寫CSS時,對元素的尺寸的限定單位經常就是PX,即像素大小。從一開始接觸和學習過程中,一直都是使用PX,導致我們的思維產生定式,總覺得CSS中元素的大小的度量就只有PX了。
另一個默認的思維定式就是在我們CSS代碼中,CSS的PX像素單位就是真實的代表一個像素,導致當網頁開發轉到移動端開發時,一個新概念的出現對我們沖擊特別大,很難轉過彎來理解,比如現在要說的視口的理解,牽扯出來的CSS像素和設備像素的概念。
其時,只要記住一點,CSS像素PX只是代表WEB網頁中的一個度量單位,可以理解為同rem和em等單位一樣,需要有一個參照尺寸才能確定其實際大小。比如rem參照根字節點的字體大小來確定自身大小,em參照父級元素字體大小來確定自身大小。思維定式中rem和em參照物是我們“絕對單位”像素PX而定的。
像素PX大小其時是相對顯示硬件中的發光點(Dot)定義的,一個發光點常稱為一個物理像素。
關於像素Pixel的前世經生,可以看這里:https://blog.csdn.net/zssureqh/article/details/78768942
顯示硬件中的發光點(Dot)與圖像分辨率中的像素(Pixel)是容易混淆的兩個概念, 顯示硬件中的點可以說是硬件設備最小的顯示單元,而像素則既可是一個點,又可是多個點的集合。
在掃描儀掃描圖像時,掃描儀的每一個樣點都是和所形成圖像的每一個像素相對應的,此時掃描時設定的DPI值(Dots Per Inch)與掃描形成圖像的PPI(Pixel Per Inch)值是相等的,此時兩者可以划等號。但在許多情況下,兩者的區別是相當大的。比如,分辨率為1 PPI的圖像,在300DPI的打印機上輸出,此時圖像的每一個像素,在打印時都對應了300×300點。在計算機顯示器的運用上也存在類似問題,比如 12英寸顯示器的有效顯示區域約200mm×160mm,如果熒光屏的光點直徑為0.31mm,通過換算可知熒光屏上最大可顯示的光點數為640(200 ÷0.31)×480(160÷0.31),相應的分辨率為80DPI。這個80DPI是這樣來的:640Dot÷(200mm÷ 25.3995mm/Inch)≈80Dot/Inch或者 480Dot÷(160mm÷25.3995mm/Inch)≈80Dot/Inch 。
在這種情況下,顯示卡的顯示模式最高可設置為640×480,這時1 Pixel由1 Dot組成。如把顯示卡的顯示模式調整為320×200,在顯示一幅320×200的圖像時,一個像素就要對應於四個光點。
上面就解釋了我們在PC端書寫CSS樣式時直接使用PX,不考慮適配的原因,因為電腦出廠設置默認都是PPI = 顯示屏DPI的,1:1關系,即dpr(devicePixelRatio,設備像素比 = 物理像素(即發光點)/邏輯像素(px)),這是顯示器的“最佳分辨率,也是我們PX像素比例所依賴的分辨率。
有兩種現象:
1、我們將電腦屏幕的分辨率調低,就會出現一部分黑邊,即有顯示硬件中會有部分不被點亮的發光點。實現發光的點還是按設置的分辨率,即像素與點一一對應。所以在PC端,DPR都是1.
2、我們在電腦端上對一張圖片進行放大和縮小,難道說我們就改變了圖片的像素尺寸了嘛?實際不是,圖片長寬方向的像素尺寸至少數值上沒有改變的。電腦改變的只是每個圖片每個像素對應的發光點數量布局。跟上面掃描儀掃描圖片一個道理。圖片放大4(2*2)倍,圖片原來一個像素對應一個發光點變為現在一個像素對應2個發光點。所以說像素是可以被拉伸的。
所以后面提到的手機端適配也是通過對像素拉伸達到的,就是說讓一個邏輯像素對應更多的發光點(物理像素)。
手機屏幕在最開始的時候,像素與發光點也是一對一的,此時在手機布局頁面操作就跟電腦PC端一樣,直接用像素PX度量就好了。但時代是進步的,科技更是在飛速的發展,屏幕的分辯率越來越高,即同樣大小的屏幕所能產生的光點越來越多,屏幕的對應的像素也越來越多。特別是從蘋果公司在IPONE4中采用Retina視網膜屏之后。雖然像素密度的提升,頁面顏色的顯示量多為細致。但卻給移動端頁面布局帶來了困擾。
方便大家理解,數據和單位權當假設,在最初的時候一個平方厘米的面積上就顯示10*10=100個像素點,那我CSS中某個字體大小就設為10PX(字體大小以寬度像素為准),我們在屏幕上看到這個字體感覺很好,但現在技術更新了,同樣1個平方厘米的面積上,我可以顯示100*100=10000個像素點,那如果DPR還保持一比一的關系,那字體還是被顯示為10px(10個發光點),那此時我們看到的字體是不是變得小了很多,相當於原來字體的寬度和長度同比例縮小10倍。
比如ipone3和ipone4,同樣是對角線8.9厘米大小的手機屏幕,ipone3能顯示的像素是320*480,而ipone4能顯示的像素是640*960。像素密度多了2倍。相當在ipone3上顯示100px的字,在ipone4上同樣設置100px,但看上去字體大小會比ipone3縮小了2倍。
看下這張圖,手機屏幕的像素越來越高,那是不是在手機上顯示的字體越來越小呢?
如果CSS里字體尺寸的像素標准還維持原來PC端的DPR=1標准不變,那勢必會導致這樣的結果。所以蘋果公司率先在手機端改變了DPR的比值。因為包括IPONE3之前幾代手機里,手機的物理像素(即設備顯示屏的發光點)和CSS世界里的邏輯像素單位是1:1的關系,字體大小在手機里感官體驗也是很好的。所以既然像素PPI增加了2倍,那這個比例關系就改為2:1啦。就是說,手機屏幕的2個物理像素相當於CCS里的1個邏輯像素。這樣屏幕尺寸沒變都是3.5寸屏,像素密度增加了兩倍,但因像素單位也增加2倍,所以也保證了字體大小沒變化。這里我們常說的DPR。它是由手機廠商根據自己手機屏幕尺寸和像素PPI考慮的,在手機出廠時就設定好了。
像上面字體大小設定一樣,廠商根據手機屏幕尺寸大小,會有一個最符合這個屏幕尺寸頁面設計方案,使得整個頁面剛好全部覆蓋手機屏幕,屏幕不會產生滾動條,用戶視覺感官最佳的頁面大小。這個視口就是我們稱為理想視口,此時視口的寬度就定義為設備寬度device-width,這個device-width就不是屏幕分辨率所指的像素寬度了,是一個中間層。
所以這里我們就可以定義視口了:
把剛好符合手機屏幕尺寸顯示完美頁面的區域稱為理想視口ideal layout;
根據放大DPR倍方便我們使用物理像素進行頁面布局的頁面稱為布局視口layout viewport。
當代碼中沒有限制縮小或放大設置時,用戶可以對瀏覽頁面進行縮小或放大,此時縮放后用戶看見頁面內容區域就叫視覺視口visual viewport 。
如果每個元素的大小都要這樣逐個根據設計稿進行換算,那效率肯定不行。那如果反過來想,我把頁面中CSS的像素單位全部都放大DPR倍的比例,就是用布局視圖來寫,就剛好對應設計稿的單位大小啦,整個頁面寫完后再整體將頁面的比例縮小1/DPR倍,就剛好回到CCS對應的邏輯像素單位啦。
所以移動端html文檔中JS代碼經常有下面的語句:
<meta id="viewport" name="viewport" content="width=device-width; initial-scale=1/DPR; minimum-scale=1/DPR; maximum-scale=1/DRP; user-scalable=no;">
語句分析:
content="width=device-width:指定手機瀏覽器顯示的頁面寬度剛好符合理想視口的寬度。Device-width:設備屏幕寬度,就是理想視口寬度。由手機廠商根據手機分辨率和自定義DPR算出,在手機出廠里就設置好的。
initial-scale=1/DPR:由於我們在頁面代碼中書寫的像素值都是布局視圖中手機的物理像素值大小,所以需要對頁面進行初始化縮小1/DPR倍。
minimum-scale=1/DPR; maximum-scale=1/DRP; user-scalable=no;" 是指定理想視口下頁面能被最大的縮放、最小的縮放、以及是否允許用戶縮放進行設置。前兩項是允許用戶操作視覺視口的最大和最小縮放。
最后以這張圖總結:
iphone手機型號 |
屏幕尺寸 |
像素尺寸 |
屏幕像素密度PPI |
理想視口尺寸 |
縮放DPR |
ipone2G/3G/3GS |
3.5 |
320 480 |
163 |
320 480 |
1 |
ipone4/4s |
3.5 |
640 960 |
326 |
320 480 |
2 |
ipone5/5S/5C/SE |
4 |
640 1136 |
326 |
320 568 |
2 |
ipone6/6S/7/8 |
4.7 |
750 1334 |
326 |
375 667 |
2 |
ipone6plus/6S+/7+/8+ |
5.5 |
1242*2208 |
401 |
414*736 |
3 |
iponeX |
5.8 |
1125*2346 |
458 |
375*812 |
3 |
- G指網絡信息Generation S就是speed plus +大屏
- 1 inch = 2.54cm = 25.4mm
- 像素(Pixel):Picture Element(圖形元素)的簡稱。在計算機中每塊像素都具有固定地址,通過地址為其分配顏色。所以也可以理解為屏幕上每個分配顏色的最小色塊。
- 屏幕尺寸:指的是顯示屏對角線的長度(diagonal)。我們通常所說的iPhone5屏幕尺寸為4英寸、iPhone6屏幕尺寸為4.7英寸。
- 屏幕分辨率:指屏幕上以水平和垂直方向顯示的像素個數
- 像素密度PPI:PPI(Pixel Per Inch by diagonal):表示沿着對角線,每英寸所擁有的像素(Pixel)數目
- DPI,物理像素與邏輯像素的比例
- DPI中的點(Dot)與圖像分辨率中的像素(Pixel)是容易混淆的兩個概念, DPI中的點可以說是硬件設備最小的顯示單元
- 在IPONE4上蘋果公司使用了Retina屏技術,並非蘋果原創,是摩托羅拉創造的,但是蘋果公司首次應用在手機上,其它手機廠商陸續也采用該技術,使得該技術得到普遍應用。
- 理論上,只要技術不斷發展,單位面積能增加像素數量會越來越多,但是人的肉眼分辨率是固定的,只要能滿足讓人眼感受不到像素的顆粒度就可以啦,一味提高PPI,人的視覺感官到權限后也不會再有更好的感受,就無畏增加成本了。所以根據屏幕尺寸,到底設置多大的PPI,蘋果有自己的Retina計算公式。所以你看后面幾代蘋果手機都差不多保持在相同的PPI上。
- 布局視口的寬度在手機上,可以通過document.documentElement.clientWidth來獲取。
- 在設置了<meta />標簽以后,device-width值可以用window.innerWidth來獲取device-width值