最近看了很多這方面的文章,能搜到的基本看了個遍,但感覺還是似懂非懂,知道這個東西,很難說出這是個什么東西,先整理一些概念,慢慢消化,以后慢慢探索其中的原因。
1、PX(CSS pixels)
1.1 定義
虛擬像素,可以理解為“直覺”像素,
CSS
和JS
使用的抽象單位,瀏覽器內的一切長度都是以CSS
像素為單位的,CSS
像素的單位是px。
1.2 注意
在CSS
規范中,長度單位可以分為兩類,絕對(absolute
)單位以及相對(relative
)單位。px
是一個相對單位,相對的是設備像素(device pixel
)。
在同樣一個設備上,每1個CSS像素所代表的物理像素是可以變化的(即CSS像素的第一方面的相對性);?
在不同的設備之間,每1個CSS像素所代表的物理像素是可以變化的(即CSS像素的第二方面的相對性);
1.3 那么PX到底是什么?
px
實際是pixel
(像素)的縮寫,根據?維基百科的解釋,它是圖像顯示的基本單元,既不是一個確定的物理量,也不是一個點或者小方塊,而是一個抽象概念。所以在談論像素時一定要清楚它的上下文!一定要清楚它的上下文!一定要清楚它的上下文!
不同的設備,圖像基本采樣單元是不同的,顯示器上的物理像素等于顯示器的點距,而打印機的物理像素等于打印機的墨點。而衡量點距大小和打印機墨點大小的單位分別稱為ppi
和dpi
:
ppi:每英寸多少像素數,放到顯示器上說的是每英寸多少物理像素及顯示器設備的點距。
dpi:每英寸多少點。
關于打印機的點距我們不去關心,只要知道?當用于描述顯示器設備時ppi與dpi是同一個概念?。
1.4 CSS像素的真正含義
由于不同的物理設備的物理像素的大小是不一樣的,所以css
認為瀏覽器應該對css
中的像素進行調節,使得瀏覽器中 1css像素的大小在不同物理設備上看上去大小總是差不多 ,目的是為了保證閱讀體驗一致。為了達到這一點瀏覽器可以直接按照設備的物理像素大小進行換算,而css
規范中使用**"參考像素"**來進行換算。
1參考像素即為從一臂之遙看解析度為96DPI
的設備輸出(即1英寸96點)時,1點(即1/96英寸)的視角。它并不是1/96英寸長度,而是從一臂之遙的距離處看解析度為96DPI
的設備輸出一單位(即1/96英寸)時視線與水平線的夾角。通常認為常人臂長為28英寸,所以它的視角是:
(1/96)in / (28in * 2 * PI / 360deg) = 0.0213度。
由于css
像素是一個視角單位,所以在真正實現時,為了方便基本都是根據設備像素換算的。瀏覽器根據硬件設備能夠直接獲取css
像素
1.5 舉個栗子來理解css像素的相對性
作為Web開發者,我們接觸的更多的是用于控制元素樣式的樣式單位像素。這里的像素我們稱之為CSS像素。
CSS像素有什么特別的地方?我們可以借用quirksmode中的這個例子:
假設我們用PC瀏覽器打開一個頁面,瀏覽器此時的寬度為800px,頁面上同時有一個400px寬的塊級元素容器。很明顯此時塊狀容器應該占頁面的一半。
但如果我們把頁面放大(通過“Ctrl鍵”加上“+號鍵”),放大為200%,也就是原來的兩倍。此時塊狀容器則橫向占滿了整個瀏覽器。
吊詭的是此時我們既沒有調整瀏覽器窗口大小,也沒有改變塊狀元素的css寬度,但是它看上去卻變大了一倍——這是因為我們把CSS像素放大為了原來的兩倍。
CSS像素與屏幕像素1:1同樣大小時:
CSS像素(黑色邊框)開始被拉伸,此時1個CSS像素大于1個屏幕像素
也就是說默認情況下一個CSS像素應該是等于一個物理像素的寬度的,但是瀏覽器的放大操作讓一個CSS像素等于了兩個設備像素寬度。在后面你會看到更復雜的情況,在高PPI的設備上,CSS像素甚至在默認狀態下就相當于多個物理像素的尺寸。
從上面的例子可以看出,CSS像素從來都只是一個相對值。
2、DP(device pixels)
2.1 定義
設備像素(物理像素),顧名思義,顯示屏是由一個個物理像素點組成的,通過控制每個像素點的顏色,使屏幕顯示出不同的圖像,屏幕從工廠出來那天起,它上面的物理像素點就固定不變了,單位pt。
2.2 注意
pt
在css
單位中屬于真正的絕對單位,1pt = 1/72(inch)
,inch
及英寸,而1英寸等于2.54厘米。
不同的設備,其圖像基本單位是不同的,比如顯示器的點距,可以認為是顯示器的物理像素。現在的液晶顯示器的點距一般在0.25mm
到0.29mm
之間。而打印機的墨點,也可以認為是打印機的物理像素,300DPI
就是0.085mm
,600DPI
就是0.042mm
。
注意,我們通常所說的顯示器分辨率,其實是指桌面設定的分辨率,而不是顯示器的物理分辨率。只不過現在液晶顯示器成為主流,由于液晶的顯示原理與CRT
不同,只有在桌面分辨率與物理分辨率一致的情況下,顯示效果最佳,所以現在我們的桌面分辨率幾乎總是與顯示器的物理分辨率一致了。
2.3 小知識
小知識:屏幕普遍采用RGB色域(紅、綠、藍三個子像素構成),而印刷行業普遍使用CMYK色域(青、品紅、黃和黑)
2.4 設備像素(DP)與CSS像素之間的關系
獲得設備像素比(dpr)后,便可得知設備像素與CSS像素之間的比例。當這個比率為1:1時,使用1個設備像素顯示1個CSS像素。當這個比率為2:1時,使用4個設備像素顯示1個CSS像素,當這個比率為3:1時,使用9(3*3)個設備像素顯示1個CSS像素。
所以,有如下公式:
DPR = 設備像素/CSS像素
3、DIP(Device independent Pixel)
設備獨立像素,也稱為邏輯像素,簡稱dip
。
根據上述設備像素與CSS
像素之間的關系、及DPR
的官方定義,我們可以推斷出:
CSS像素 =設備獨立像素 = 邏輯像素
下面,還是引用?http://www.cnblogs.com/2050/p/3877280.html?文中的內容說明:
在移動端瀏覽器中以及某些桌面瀏覽器中,window對象有一個devicePixelRatio
屬性,它的官方的定義為:設備物理像素和設備獨立像素的比例,也就是?devicePixelRatio = 物理像素 / 獨立像素。CSS
像素就可以看做是設備的獨立像素,所以通過devicePixelRatio
,我們可以知道該設備上一個css
像素代表多少個物理像素。例如,在Retina
屏的iphone
上,devicePixelRatio
的值為2,也就是說1個css
像素相當于2個物理像素。但是要注意的是,devicePixelRato
在不同的瀏覽器中還存在些許的兼容性問題,所以我們現在還并不能完全信賴這個東西,具體的情況可以看下這篇文章。
為什么是“每四個一組”?而且要讓這四個一組來顯示“原來屏幕的一個像素”?這大概就是 Retina 顯示技術的一種表現吧。而這“每四個一組”的“大像素”,可以被稱作“設備獨立像素”,device independent pixel
?,或者?density-independentpixel
?,它可以是系統中的一個點,這個點代表一個可以由程序使用的虛擬像素,然后由相關系統轉換為物理像素。
“設備獨立像素”也有人稱為“CSS像素”,一種形象的說法,更傾向于表明與?CSS
?中尺寸的對應。
設備獨立像素與物理像素的對應關系,可以這樣看:
類似的每四個一組的對應關系,也許正是?Retina
?顯示技術所做的。
4、DPR(device pixels ratio)
4.1 定義
設備像素比(dpr?描述的是未縮放狀態下,
物理像素
和CSS像素
的初始比例關系,計算方法如下圖。
?
4.2 理解
設備像素比(dpr)?是指在移動開發中1個css像素占用多少設備像素,如2代表1個css像素用2x2個設備像素來繪制。
設備像素比(dpr),公式為1px = (dpr)^2 * 1dp
,可以理解為1px由多少個設備像素組成;
?
5、PPI(pixels per inch)
5.1 定義
每英寸像素取值,更確切的說法應該是像素密度,也就是衡量單位物理面積內擁有像素值的情況。
5.2 ppi是如何計算出來的呢?
顧名思義,每英寸的像素點(設備像素),已知屏幕分辨率和主對角線的尺寸,則ppi
等于
以愛瘋6為例:
我們知道,ppi越高,每英寸像素點越多,圖像越清晰;我們可以類比物體的密度,密度越大,單位體積的質量就越大,ppi越高,單位面積的像素越多。
5.3 ppi和dpr到底什么關系?
畢竟這些參數是外國人先發明的,他們會優先選擇自己熟悉的計量單位作為顯示設備的工廠標準參數,因此ppi
就用作顯示設備的工業標準;
告訴業界人士,ppi
達到多少是高清屏,此時對應的dpr是多少,而不直接告訴你我現在的顯示設備dpr
是多少,畢竟人們直接聽到像素分辨率會更加有反應。
設備像素比與ppi相關,一般是ppi/160的整數倍:
?
6、倍率與邏輯像素
6.1 基本關系
用iPhone 3gs和4s來舉例。假設有個郵件列表界面,我們不妨按照PC端網頁設計的思維來想象。3gs上大概只能顯示4-5行,4s就能顯示9-10行,而且每行會變得特別寬。但兩款手機其實是一樣大的。如果照這種方式顯示,3gs上剛剛好的效果,在4s上就會小到根本看不清字。
在現實中,這兩者效果卻是一樣的。這是因為Retina屏幕把2x2個像素當1個像素使用。比如原本44像素高的頂部導航欄,在Retina
屏上用了88個像素的高度來顯示。導致界面元素都變成2倍大小,反而和3gs效果一樣了。畫質卻更清晰。
在以前,iOS應用的資源圖片中,同一張圖通常有兩個尺寸。你會看到文件名有的帶@2x字樣,有的不帶。其中不帶@2x的用在普通屏上,帶@2x的用在Retina
屏上。只要圖片準備好,iOS會自己判斷用哪張,Android
道理也一樣。
由此可以看出,蘋果以普通屏為基準,給Retin
a屏定義了一個2倍的倍率(iPhone 6plus
除外,它達到了3倍)。實際像素除以倍率,就得到邏輯像素尺寸。只要兩個屏幕邏輯像素相同,它們的顯示效果就是相同的。
6.2 Retina顯示屏
這是一種顯示技術,可以將把更多的像素點壓縮至一塊屏幕里,從而達到更高的分辨率并提高屏幕顯示的細膩程度,這種分辨率在正常觀看距離下足以使人肉眼無法分辨其中的單獨像素。
最先使用retina
屏幕是iphone 4,屏幕分辨率為960 * 640(326ppi)。
對比如下兩幅圖,可以清晰地看出是否?Retina
?屏的顯示差異:
圖2 iPhone 3GS
圖3 iPhone 4
兩代iPhone 的物理尺寸(屏幕寬高有多少英寸)是一樣的,從上圖可以看出,iphone 4的顯示效果要明顯好于iphone 3GS,雖然 iPhone 4 分辨率提高了,但它不同于普通的電腦顯示器那樣為了顯示更多的內容,而是提升顯示相同內容時的畫面精細程度。這種提升方式是靠提升單位面積屏幕的像素數量,即像素密度來提升分辨率,這樣做的主要目的是為了提高屏幕顯示畫面的精細程度。以第三代?MacBook Pro with Retina Display
為例, 工作時顯卡渲染出的2880x1880個像素每四個一組,輸出原來屏幕的一個像素顯示的大小區域內的圖像。這樣一來,用戶所看到的圖標與文字的大小與原來的1440x900分辨率顯示屏相同,但精細度是原來的4倍。
注意:在桌面顯示器中,我們調整了顯示分辨率,比如從 800 * 600 調整到 1024 * 768 時,屏幕的文字圖標會變小,顯示的內容更多了。但?Retina
?顯示方式不會產生這樣的問題,或者說,?Retina 顯示技術解決的是顯示畫面精細程度的問題,而不是解決顯示內容容量的問題。
7、分辨率、像素和屏幕尺寸
PPI
?說的是像素密度,而分辨率說的是塊屏幕的像素尺寸,譬如說 1334*750 就是 iPhone(6~7)的分辨率,說 iPhone(6~7)的分辨率是 326 是錯誤的表述,326 是它的像素密度,單位是?PPI
。
詢問別人一粒像素有多大是一個非常雞賊的問題(小心面試遇到這樣的題),雖然我們說像素是構成屏幕的發光的點,是物理的,但是像素在脫離了屏幕尺寸之后是沒有大小可言的,你可以將 1920 * 1080 顆像素放到一臺 40 寸的小米電視機里面,也可以將同樣多的像素全部塞到一臺 5.5 寸的 iPhone7 Plus 手機里面去,那么對于 40 寸的電視而言,每個像素顆粒當然會大于 5.5 寸的手機的像素。
所以光看屏幕的分辨率對于設計師來說是不具備多少實際意義的,通過分辨率計算得出的像素密度(PPI)才是設計師要關心的問題,我們通過屏幕分辨率和屏幕尺寸就能計算出屏幕的像素密度的。
再次使用 iPhone(6~7)作為例子。我們知道該屏幕的橫向物理尺寸為 2.3 英寸 ,且橫向具有 750 顆像素,根據下面的公式,我們能夠算出 iPhone(6~7)的屏幕是 326 PPI,意為每寸存在 326 顆像素。
其實不論我們怎么除,計算得出來的像素密度(PPI)
都會是這個數,寬存在像素除以寬物理長度,高存在像素除以高物理長度,得數都接近于 326。
8、Viewport
8.1 PPK的關于三個viewport的理論
ppk大神對于移動設備上的viewport有著非常多的研究(第一篇,第二篇,第三篇),有興趣的同學可以去看一下,本文中有很多數據和觀點也是出自那里。ppk認為,移動設備上有三個viewport。
首先,移動設備上的瀏覽器認為自己必須能讓所有的網站都正常顯示,即使是那些不是為移動設備設計的網站。但如果以瀏覽器的可視區域作為viewport
的話,因為移動設備的屏幕都不是很寬,所以那些為桌面瀏覽器設計的網站放到移動設備上顯示時,必然會因為移動設備的viewport
太窄,而擠作一團,甚至布局什么的都會亂掉。也許有人會問,現在不是有很多手機分辨率都非常大嗎,比如768x1024,或者1080x1920這樣,那這樣的手機用來顯示為桌面瀏覽器設計的網站是沒問題的吧?前面我們已經說了,css
中的1px并不是代表屏幕上的1px,你分辨率越大,css
中1px代表的物理像素就越多,devicePixelRatio
的值也越大,這很好理解,因為你分辨率增大了,但屏幕尺寸并沒有變大多少,必須讓css
中的1px代表更多的物理像素,才能讓1px的東西在屏幕上的大小與那些低分辨率的設備差不多,不然就會因為太小而看不清。所以在1080x1920這樣的設備上,在默認情況下,也許你只要把一個div的寬度設為300多px(視devicePixelRatio
的值而定),就是滿屏的寬度了。回到正題上來,如果把移動設備上瀏覽器的可視區域設為viewport的話,某些網站就會因為viewport
太窄而顯示錯亂,所以這些瀏覽器就決定默認情況下把viewport
設為一個較寬的值,比如980px,這樣的話即使是那些為桌面設計的網站也能在移動瀏覽器上正常顯示了。ppk把這個瀏覽器默認的viewport
叫做?layout viewport。
???
這個layout viewport
的寬度可以通過document.documentElement.clientWidth
?來獲取。
然而,layout viewport?的寬度是大于瀏覽器可視區域的寬度的,所以我們還需要一個viewport
來代表 瀏覽器可視區域的大小,ppk把這個viewport
叫做?visual viewport?。visual viewport
的寬度可以通過window.innerWidth?來獲取,但在Android 2, Oprea mini 和 UC 8中無法正確獲取。
?
現在我們已經有兩個viewport
了:layout viewport?和??visual viewport。但瀏覽器覺得還不夠,因為現在越來越多的網站都會為移動設備進行單獨的設計,所以必須還要有一個能完美適配移動設備的viewport
。所謂的完美適配指的是,首先不需要用戶縮放和橫向滾動條就能正常的查看網站的所有內容;第二,顯示的文字的大小是合適,比如一段14px大小的文字,不會因為在一個高密度像素的屏幕里顯示得太小而無法看清,理想的情況是這段14px的文字無論是在何種密度屏幕,何種分辨率下,顯示出來的大小都是差不多的。當然,不只是文字,其他元素像圖片什么的也是這個道理。ppk把這個viewport
叫做?ideal viewport,也就是第三個viewport
——移動設備的理想viewport
。
ideal viewport
并沒有一個固定的尺寸,不同的設備擁有有不同的ideal viewport
。所有的iphone
的ideal viewport
寬度都是320px,無論它的屏幕寬度是320還是640,也就是說,在iphone
中,css
中的320px就代表iphone
屏幕的寬度。
但是安卓設備就比較復雜了,有320px的,有360px的,有384px的等等,關于不同的設備ideal viewport
的寬度都為多少,可以到http://viewportsizes.com去查看一下,里面收集了眾多設備的理想寬度。
再總結一下:ppk把移動設備上的viewport
分為?layout viewport?、?visual viewport?和?ideal viewport?三類,其中的ideal viewport
是最適合移動設備的viewport
,ideal viewport
的寬度等于移動設備的屏幕寬度,只要在css中把某一元素的寬度設為ideal viewport
的寬度(單位用px),那么這個元素的寬度就是設備屏幕的寬度了,也就是寬度為100%的效果。ideal viewport
?的意義在于,無論在何種分辨率的屏幕下,那些針對ideal viewport
而設計的網站,不需要用戶手動縮放,也不需要出現橫向滾動條,都可以完美的呈現給用戶。
?
8.2 利用meta標簽對viewport進行控制
移動設備默認的viewport
是layout viewport
,也就是那個比屏幕要寬的viewport
,但在進行移動設備網站的開發時,我們需要的是ideal viewport
。那么怎么才能得到ideal viewport
呢?這就該輪到meta
標簽出場了。
我們在開發移動設備的網站時,最常見的的一個動作就是把下面這個東西復制到我們的head
標簽中:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
該meta
標簽的作用是讓當前viewport
的寬度等于設備的寬度,同時不允許用戶手動縮放。也許允不允許用戶縮放不同的網站有不同的要求,但讓viewport
的寬度等于設備的寬度,這個應該是大家都想要的效果,如果你不這樣的設定的話,那就會使用那個比屏幕寬的默認viewport
,也就是說會出現橫向滾動條。
這個nam
e為viewport
的meta
標簽到底有哪些東西呢,又都有什么作用呢?
meta viewport
?標簽首先是由蘋果公司在其safari
瀏覽器中引入的,目的就是解決移動設備的viewport
問題。后來安卓以及各大瀏覽器廠商也都紛紛效仿,引入對meta viewport
的支持,事實也證明這個東西還是非常有用的。
在蘋果的規范中,meta viewport
?有6個屬性(暫且把content
中的那些東西稱為一個個屬性和值),如下:
這些屬性可以同時使用,也可以單獨使用或混合使用,多個屬性同時使用時用逗號隔開就行了。
此外,在安卓中還支持??target-densitydpi
? 這個私有屬性,它表示目標設備的密度等級,作用是決定css
中的1px代表多少物理像素
特別說明的是,當?target-densitydpi=device-dpi
?時, css中的1px會等于物理像素中的1px。
因為這個屬性只有安卓支持,并且安卓已經決定要廢棄<strike>target-densitydpi</strike>
? 這個屬性了,所以這個屬性我們要避免進行使用? 。
8.3 把當前的viewport寬度設置為 ideal viewport 的寬度
要得到ideal viewport
就必須把默認的layout viewport
的寬度設為移動設備的屏幕寬度。因為meta viewport
中的width
能控制layout viewport
的寬度,所以我們只需要把width
設為width-device
這個特殊的值就行了。
<meta name="viewport" content="width=device-width">
下圖是這句代碼在各大移動端瀏覽器上的測試結果:
可以看到通過width=device-width
,所有瀏覽器都能把當前的viewport
寬度變成ideal viewport
的寬度,但要注意的是,在iphone和ipad上,無論是豎屏還是橫屏,寬度都是豎屏時ideal viewport
的寬度。
這樣的寫法看起來誰都會做,沒吃過豬肉,誰還沒見過豬跑啊~,確實,我們在開發移動設備上的網頁時,不管你明不明白什么是viewport
,可能你只需要這么一句代碼就夠了。
可是你肯定不知道
<meta name="viewport" content="initial-scale=1">
這句代碼也能達到和前一句代碼一樣的效果,也可以把當前的的viewport
變為?ideal viewport
。
呵呵,傻眼了吧,因為從理論上來講,這句代碼的作用只是不對當前的頁面進行縮放,也就是頁面本該是多大就是多大。那為什么會有?width=device-width
?的效果呢?
要想清楚這件事情,首先你得弄明白這個縮放是相對于什么來縮放的,因為這里的縮放值是1,也就是沒縮放,但卻達到了 ideal viewport 的效果,所以,那答案就只有一個了,縮放是相對于?ideal viewport
來進行縮放的,當對ideal viewport
進行100%的縮放,也就是縮放值為1的時候,不就得到了?ideal viewport
?嗎?事實證明,的確是這樣的。下圖是各大移動端的瀏覽器當設置了<meta name="viewport" content="initial-scale=1">
后是否能把當前的viewport
?寬度變成?ideal viewport
?的寬度的測試結果。
測試結果表明?initial-scale=1
?也能把當前的?viewport
?寬度變成?ideal viewport
?的寬度,但這次輪到了windows phone 上的IE 無論是豎屏還是橫屏都把寬度設為豎屏時?ideal viewport
?的寬度。但這點小瑕疵已經無關緊要了。
但如果?width
?和?initial-scale=1
?同時出現,并且還出現了沖突呢?比如:
<meta name="viewport" content="width=400, initial-scale=1">
width=400
?表示把當前?viewport
?的寬度設為400px
,initial-scale=1
?則表示把當前?viewport
?的寬度設為ideal viewport的寬度,那么瀏覽器到底該服從哪個命令呢?是書寫順序在后面的那個嗎?不是。當遇到這種情況時,瀏覽器會取它們兩個中較大的那個值。例如,當width=400
,ideal viewport
?的寬度為320時,取的是400;當width=400, ideal viewport的寬度為480時,取的是ideal viewport
的寬度。(ps:在uc9瀏覽器中,當initial-scale=1時,無論width屬性的值為多少,此時viewport的寬度永遠都是ideal viewport的寬度)
最后,總結一下,要把當前的viewport寬度設為ideal viewport的寬度,既可以設置 width=device-width,也可以設置 initial-scale=1,但這兩者各有一個小缺陷,就是iphone、ipad以及IE 會橫豎屏不分,通通以豎屏的ideal viewport寬度為準。所以,最完美的寫法應該是,兩者都寫上去,這樣就 initial-scale=1 解決了 iphone、ipad的毛病,width=device-width則解決了IE的毛病:
<meta name="viewport" content="width=device-width, initial-scale=1">
8.4 關于meta viewport的更多知識
8.4.1 關于縮放以及initial-scale的默認值
首先我們先來討論一下縮放的問題,前面已經提到過,縮放是相對于?ideal viewport
?縮放的,縮放值越大,當前viewport的寬度就會越小,反之亦然。例如在iphone中,ideal viewport
?的寬度是320px,如果我們設置?initial-scale=2
?,此時?viewport
?的寬度會變為只有160px了,這也好理解,放大了一倍嘛,就是原來1px的東西變成2px了,但是1px變為2px并不是把原來的320px變為640px了,而是在實際寬度不變的情況下,1px變得跟原來的2px的長度一樣了,所以放大2倍后原來需要320px才能填滿的寬度現在只需要160px就做到了。因此,我們可以得出一個公式:
visual viewport寬度 = ideal viewport寬度 / 當前縮放值
當前縮放值 = ideal viewport寬度 / visual viewport寬度
ps:?visual viewport
?的寬度指的是瀏覽器可視區域的寬度。
大多數瀏覽器都符合這個理論,但是安卓上的原生瀏覽器以及IE有些問題。安卓自帶的webkit
瀏覽器只有在?initial-scale = 1
?以及沒有設置width
屬性時才是表現正常的,也就相當于這理論在它身上基本沒用;而IE則根本不甩initial-scale這個屬性,無論你給他設置什么,initial-scale
表現出來的效果永遠是1。
好了,現在再來說下?initial-scale
?的默認值問題,就是不寫這個屬性的時候,它的默認值會是多少呢?很顯然不會是1,因為當?initial-scale = 1
?時,當前的?layout viewport
?寬度會被設為?ideal viewport
?的寬度,但前面說了,各瀏覽器默認的?layout viewport
?寬度一般都是980啊,1024啊,800啊等等這些個值,沒有一開始就是?ideal viewport
?的寬度的,所以?initial-scale
?的默認值肯定不是1。安卓設備上的?initial-scale
?默認值好像沒有方法能夠得到,或者就是干脆它就沒有默認值,一定要你顯示的寫出來這個東西才會起作用,我們不管它了,這里我們重點說一下iphone和ipad上的?initial-scale
?默認值。
根據測試,我們可以在iphone和ipad上得到一個結論,就是無論你給?layout viewpor
?設置的寬度是多少,而又沒有指定初始的縮放值的話,那么iphone和ipad會自動計算?initial-scale
?這個值,以保證當前?layout viewport
?的寬度在縮放后就是瀏覽器可視區域的寬度,也就是說不會出現橫向滾動條。比如說,在iphone上,我們不設置任何的?viewport meta
?標簽,此時?layout viewport
?的寬度為980px,但我們可以看到瀏覽器并沒有出現橫向滾動條,瀏覽器默認的把頁面縮小了。根據上面的公式,當前縮放值 = ideal viewport寬度 / visual viewport寬度
,我們可以得出:
當前縮放值 = 320 / 980
也就是當前的?initial-scale
?默認值應該是 0.33這樣子。當你指定了?initial-scale
?的值后,這個默認值就不起作用了。
總之記住這個結論就行了:在iphone和ipad上,無論你給viewport設的寬的是多少,如果沒有指定默認的縮放值,則iphone和ipad會自動計算這個縮放值,以達到當前頁面不會出現橫向滾動條(或者說viewport的寬度就是屏幕的寬度)的目的。
?
8.4.2 動態改變meta viewport標簽
第一種方法
可以使用?document.write
?來動態輸出?meta viewport
?標簽,例如:
document.write('<meta name="viewport" content="width=device-width,initial-scale=1">')
第二種方法
通過?setAttribute
?來改變
<meta id="testViewport" name="viewport" content="width = 380"> <script> var mvp = document.getElementById('testViewport'); mvp.setAttribute('content','width=480'); </script>
安卓2.3自帶瀏覽器上的一個?bug
<meta name="viewport" content="width=device-width"><script type="text/javascript"> alert(document.documentElement.clientWidth); //彈出600,正常情況應該彈出320 </script><meta name="viewport" content="width=600"><script type="text/javascript"> alert(document.documentElement.clientWidth); //彈出320,正常情況應該彈出600 </script>
測試的手機?ideal viewport
?寬度為320px,第一次彈出的值是600,但這個值應該是第行meta標簽的結果啊,然后第二次彈出的值是320,這才是第一行meta標簽所達到的效果啊,所以在安卓2.3(或許是所有2.x版本中)的自帶瀏覽器中,對?meta viewport
?標簽進行覆蓋或更改,會出現讓人非常迷糊的結果。
最后我們來看一個栗子來加深上面概念的印象:
一只筆的像素如下:
這只筆在屏幕c,d,e下的顯示效果如下:
看到同一張圖片在各屏幕顯示大小不一。
我們希望不同屏幕顯示圖片的大小要一致。
我們要計算圖片縮放比例。
計算公式:
(圖片邏輯像素大小px1) / (圖片縮放后實際像素大小px2) = (設備像素dp) / (設備獨立像素dips)
px2 = px1 * (dp / dips)
px2 = px1 * dpr
此時,這只筆在屏幕c,d,e下的顯示效果如下:
通過上面的我們可以看到,不同的?
DPR
?(設備像素比)要想顯示大小一樣,必須準備三張不同分辨率的圖片,那么,我想一張圖片就在三種不同的屏幕下顯示一樣的大小,能做到嗎?當然能做到,這就需要縮放了,要自己計算縮放多麻煩,那有沒有一種簡單的方式呢?當然有,那就是你在熟悉不過的px,你會發現設置圖片寬度為50px以后,在各個移動終端的大小看起來都一樣,這是什么原因呢。
按照?CSS
?規范的定義,CSS
?中的?px
?是一個相對長度,它相對的,是?viewing device
?的分辨率。這個viewing device
,通常就是電腦顯示器。典型的電腦顯示器的分辨率是96DPI
,也就是1像素為1/96英寸(實際上,假設我們的顯示器分辨率都與物理分辨率一致,而液晶點距其實是0.25mm到0.29mm之間,所以不太可能是正好1/96英寸,而只是接近)。
一般來說,px
?就是對應設備的物理像素,然而如果輸出設備的解析度與電腦顯示器大不相同,輸出效果就會有問題。例如打印機輸出到紙張上,其解析度比電腦屏幕要高許多,如果不縮放,直接使用設備的物理像素,那電腦上的照片由?600DPI
?的打印機打出來就比用顯示器看小了約6倍。
所以?CSS
?規定,在這種情況下,瀏覽器應該對像素值進行縮放調節,以保持閱讀體驗的大體一致。也就是要保持一定像素的長度在不同設備輸出上看上去的大小總是差不多。
怎樣確保這一點呢?直接按照設備物理像素的大小進行換算當然是一個方式,但是CSS考慮得更多,它建議,轉換應按照“參考像素”(reference pixel
)來進行。
眼睛看到的大小,取決于可視角度。而可視角度取決于物體的實際大小以及物體與眼睛的距離。10米遠處一個1米見方的東西,與1米遠處的10厘米見方的東西,看上去的大小差不多是一樣的,所謂一葉障目不見泰山,講的就是這個常識。
因此CSS規范使用視角來定義“參考像素”,1參考像素即為從一臂之遙看解析度為96DPI的設備輸出(即1英寸96點)時,1點(即1/96英寸)的視角。
請注意這個差別——CSS
規范定義的參考像素并不是1/96英寸,而是1/96英寸在一臂之遙的看起來的視角。通常認為常人臂長為28英寸,所以其視角可以計算出來是0.0213度。(即(1/96)in / (28in * 2 * PI / 360deg) )
我們在使用不同設備輸出時,眼睛與設備輸出的典型距離是不同的。比如電腦顯示器,通常是一臂之距,而看書和紙張時(對應于打印機的設備輸出),則通常會更近一些。看電視時則會更遠,比如一般建議是電視機屏幕對角線的2.5到3倍長——如果你是個42'彩電,那就差不多是3米遠。看電影的話……我就不知道多遠了,您自己量吧。
因此,1參考像素:
對于電腦顯示器是0.26mm(即1/96英寸);
對于激光打印機是0.20mm(假設閱讀距離通常為55cm,即21英寸);
而換算時,對于300DPI的打印機(即每個點是1/300英寸),1px通常會四舍五入到3dots,也就是0.25mm左右;而對于600DPI的打印機,則可能四舍五入到5dots,也就是0.21mm。
上圖中,左邊的屏幕(可以認為是電腦屏幕)的典型視覺距離是71厘米即28英寸,其1px對應了0.28mm;
而右邊的屏幕(可以認為是你的42寸高清電視)的典型視覺距離是3.5米即120英寸,其1px對應1.3mm。42寸的1080p電視,分辨率是1920*1080,則其物理像素只有0.5mm左右,可見確實是高清哦。
綜上,px
?是一個相對單位,而且在特定設備上總是一個近似值(原則是盡量接近參考像素)。
然而,如果你把絕對單位理解為對輸出效果的絕對掌控,事情卻大相徑庭。就網頁輸出的最主要對象——電腦屏幕來說,px
?可被視為一個基準單位——與桌面分辨率一致,如果是液晶屏,則幾乎總是與液晶屏物理分辨率一致——也就是說網頁設計者設定的1px,就是“最終看到這個網頁的用戶的顯示器上的1個點距”!反倒是那些絕對單位,其實一點也不絕對。
轉載:https://blog.csdn.net/qq_33834489/article/details/79247119
參考文章
深入理解移動端像素知識與Viewport知識
移動端H5頁面的設計稿尺寸(上)
移動端H5頁面的設計稿尺寸(下)
你真的了解像素嗎
移動前端開發之viewport的深入理解
設備像素,設備獨立像素,CSS像素
移動端開發系列——像素與viewport
移動端高清、多屏適配方案?
像素(px)到底是個什么單位
CSS 長度單位
徹底理解 UI 及 Web 的尺寸單位:基本概念
針對iPhone的pt、Android的dp、HTML的css像素與dpr、設計尺寸和物理像素的淺分析
原文地址:https://github.com/jawil/blog/issues/21