1px有多大?
我們先了解幾個概念:
關鍵概念
設備像素:設備屏幕實際擁有的像素點一般來說:寬度方向有1920個像素點,長度方向有1080個像素點。
邏輯像素:CSS 的像素單位(就是我們這次要討論的css的px),其尺寸大小是相對的,也稱爲獨立像素
分辨率:屏長的設備像素 × 屏寬的設備像素(1920 * 1080)
ppi(pixels per inch):像素密度,表示沿對角線每英寸長度的像素數目(單位是dpi),越大顯示的越細膩
縮放因子(Scale Factor):邏輯像素相對於設備像素的放大比例,可通過` window.devicePixelRatio `獲得,pc上可以用個個性化來設置,但二者並不完全等同
上面概念直接的關係
關係一:
設備尺寸 × 像素密度 = 分辨率(設備像素)
舉例:
iphone6s 對角線長度爲5.5 inches,像素密度401 ppi,分辨率 1920 * 1080,計算可得對角線的設備像素爲2205.5。
5.5 * 401 = 2205.5
關係二:
邏輯像素(css的px) = 設備像素 × 縮放因子
舉例:
iphone6邏輯像素爲375 * 667,分辨率爲750 * 1334,縮放因子爲2
1個邏輯像素(1px) = 設備寬度的1/375
1個設備像素 = 設備寬度的1/750
1/375 = 1/750 * 2
以上參考: 1px 究竟是多大
由公式得出的結論
PC端分辨率一樣的情況下,屏幕尺寸越大,顯示的越模糊(因爲dpi越小)。
舉例說明:
我們的臺式機電腦屏幕一般是32英寸,分辨率爲:1920 * 1080。而一般筆記本是15.6英寸,分辨率也是:1920*1080的。由公式一:當分辨率一樣時,設備尺寸越大,像素密度越小。所以32寸的臺式電腦看上去模糊一些。
相同分辨率,相同縮放因子情況下,不同設備尺寸下,表現是一致的
舉例說明:
平時我們在pc上24英寸的電腦上開發的網頁直接寫的(px),在不做任何兼容處理的情況下,在15.6英寸的筆記本上也能正常顯示。由公式二:因爲一般pc端,默認情況下縮放因子爲1(window.devicePixelRatio = 1),分辨率也一樣(1920 * 1080),那麼得到的**邏輯像素(css的px)**也是一樣的。所以你在分辨率一樣的情況下,在大屏電腦上設置的100px,在小屏電腦上也是100px。只是他們表現出來的大小不一致,小屏上面的1px更小。
如何將pc網頁放到手機上展示?
我們可以調整網頁在移動端上的縮放比例,這個值就是viewport
。默認情況下,移動端瀏覽器會將 viewport 寬度設爲980px(也有可能是1024px 或其它值),也就是說1px = 設備屏幕寬度的1/980。這跟縮放因子沒有任何關係。
這時的1px 非常小,所有的元素都變得非常小,移動端瀏覽器之所以這麼做,是爲了儘可能完整的顯示 PC 端的網頁,然後允許用戶通過縮放來查看細節。
顯然體驗就別的特別差了,很多本來就比較小的元素看都看不清了。
第二種方式是我們設置一個適當的縮放比例。一般我們這樣設置:
<meta name="viewport" content="width=device-width">
那麼對於iphone6來說根據公式:1px = 1/750(分辨率) * 2(縮放因子) = 1/ 375。顯然比剛纔的1/980大了不少,那麼我們的元素如果還是按照原來的px去設置,那麼屏幕肯定展示不下去了,這時候,如果我們的元素的px值能根據1px的大小是動態調整,我們的網頁就完美了,這時候em,rem
就派上用場了。
em是什麼?
上面提到,想讓我們的網頁在不同分辨率的設備(移動端)上正常顯示,最好我們的元素長寬,外邊距,內邊距等都是動態的
方式一:
上面說到,我們在移動端一般這樣設置:
<meta name="viewport" content="width=device-width;initial-scale=1" >
這個時候我們1px的大小就已知,iPhone6上爲:1px = 1/750(分辨率) * 2(縮放因子) = 1/ 375。既然1px的大小固定了,那麼我們只能動態改變一個元素設置的px了,比如說在iPhone8上是120px;而在iPhone6上需要是100px。這時候我們可以用js去動態計算,根據屏幕大小。但是顯然很麻煩,需要對每一個元素的長寬,內邊距,外邊距都需要調整,這顯然是一個巨大的工程。
這時候我們就可以用到em
這個單位了,em單位的名稱爲相對長度單位,是根據它父元素的字體大小來計算的,一般默認情況下:16px = 1em。如果父元素font-size:16px
,子元素margin:0.8em
。那麼得到的大小就是:0.8 * 16 =12.8
。當所有單位都採用em
時,我們只需要改變body
的font-size
,那麼其他子元素寬度就能動態變化了,顯然方便很多。
rem是什麼?
'rem’是’css3’新增的一個相對長度單位,它的出現是爲了解決em的缺點,em可以說是相對於父級元素的字體大小,當父級元素字體大小改變時,又得重新計算。rem出現就可以解決這樣的問題,rem只相對於根目錄,即HTML元素。有了rem這個單位,我們只需要調整根元素html
的font-size
就能達到所有元素的動態適配了,附上一段常用適配代碼:
/**
* ================================================
* 設置根元素font-size
* 當設備寬度爲375(iPhone6)時,根元素font-size=16px;
× ================================================
*/
(function (doc, win) {
var docEl = win.document.documentElement;
var resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize';
var refreshRem = function () {
var clientWidth = win.innerWidth
|| doc.documentElement.clientWidth
|| doc.body.clientWidth;
console.log(clientWidth)
if (!clientWidth) return;
var fz;
var width = clientWidth;
fz = 16 * width / 375;
docEl.style.fontSize = fz + 'px';//這樣每一份也是16px,即1rem=16px
};
if (!doc.addEventListener) return;
win.addEventListener(resizeEvt, refreshRem, false);
doc.addEventListener('DOMContentLoaded', refreshRem, false);
refreshRem();
})(document, window);
總結
- 邏輯像素(css的px) = 設備像素 × 縮放因子
- 爲了移動端更好的適配我們引入了
em
和rem
這2個動態單位 em
的大小與父元素的font-size
有關,rem
的大小與根元素html
的font-size
有關- 一般在移動端我們會使用
js
動態計算跟節點html
的font-size
來達到自適應的目的。