響應(yīng)式設(shè)計(jì)——理解設(shè)備像素、設(shè)備獨(dú)立像素和css像素

像素單位

像素單位有設(shè)備像素、邏輯像素和CSS像素3種。

設(shè)備像素(device pixels)、設(shè)備分辨率

設(shè)備像素也叫物理像素。

設(shè)備像素指的是顯示器上的真實(shí)像素,每個(gè)像素的大小是屏幕固有的屬性,屏幕出廠以后就不會(huì)改變了。
設(shè)備分辨率描述的就是這個(gè)顯示器的寬和高分別是多少個(gè)設(shè)備像素。
設(shè)備像素和設(shè)備分辨率交給操作系統(tǒng)來管理,瀏覽器不知道、也不需要知道設(shè)備分辨率的大小,瀏覽器只需要知道邏輯分辨率就可以了。

設(shè)備獨(dú)立像素(Device Independent Pixels)、邏輯分辨率

設(shè)備獨(dú)立像素也叫邏輯像素。

設(shè)備獨(dú)立像素(dips)是操作系統(tǒng)定義的一種像素單位,應(yīng)用程序?qū)⒃O(shè)備獨(dú)立像素告訴操作系統(tǒng),操作系統(tǒng)再將設(shè)備獨(dú)立像素轉(zhuǎn)化為設(shè)備像素,從而控制屏幕上真正的物理像素點(diǎn)。

為什么需要在應(yīng)用程序與設(shè)備像素之間定義這么一種單位呢?為什么應(yīng)用程序不應(yīng)該直接使用設(shè)備像素?
隨著顯示器制造技術(shù)越來越先進(jìn),屏幕像素密度越來越高。同樣是19201080顆像素,以前要放在寬大的顯示器中,現(xiàn)在都可以放在手機(jī)屏幕上了。原本高度為12個(gè)設(shè)備像素的字體,現(xiàn)在高度為24個(gè)設(shè)備像素才能得到相近的大小(這也說明字變得更加清晰銳利了),如果應(yīng)用程序直接使用設(shè)備像素,那么編寫應(yīng)用程序?qū)⒆兊梅浅@щy:字體在一些屏幕上高度為12個(gè)設(shè)備像素,在另一些屏幕上卻要變?yōu)?4個(gè)設(shè)備像素。
因此操作系統(tǒng)定義了一個(gè)單位:設(shè)備獨(dú)立像素。操作系統(tǒng)保證:用設(shè)備獨(dú)立像素定義的尺寸,不管屏幕的參數(shù)如何,都能以合適的大小顯示(這也是設(shè)備獨(dú)立像素名字的由來)。操作系統(tǒng)是如何做到的呢?
對(duì)于那些像素密度高的屏幕,將多個(gè)設(shè)備像素劃分為一個(gè)邏輯像素。至于將多少設(shè)備像素劃分為一個(gè)邏輯像素,這由操作系統(tǒng)決定*。
對(duì)于上面的例子:“原本高度為12個(gè)設(shè)備像素的字體,現(xiàn)在高度為24個(gè)設(shè)備像素才能得到相同的大小”,操作系統(tǒng)會(huì)將一個(gè)邏輯像素定義為2*2個(gè)真實(shí)像素,從而設(shè)備獨(dú)立像素尺寸不需要改變,而且不管在新、舊設(shè)備上,顯示的尺寸大致相同。

用4個(gè)設(shè)備像素來顯示一個(gè)設(shè)備獨(dú)立像素

設(shè)備獨(dú)立像素與設(shè)備像素之間的比例是多少,顯示器廠商和操作系統(tǒng)廠商會(huì)通過調(diào)查研究來得出最利于觀看的比例。普遍規(guī)律是,屏幕的像素密度越高,就需要更多的設(shè)備像素來顯示一個(gè)設(shè)備獨(dú)立像素。

通過screen.width/height得到的數(shù)值就是整個(gè)屏幕(不僅僅是瀏覽器的區(qū)域)的寬度和高度(單位:設(shè)備獨(dú)立像素)。這個(gè)數(shù)值不隨頁面縮放、瀏覽器窗口大小而改變。

邏輯分辨率用屏幕的寬*高來表示(單位:設(shè)備獨(dú)立像素)。

你可以通過操作系統(tǒng)的分辨率設(shè)置來改變?cè)O(shè)備獨(dú)立像素的大小,但在前端開發(fā)的時(shí)候我們完全可以將它們當(dāng)作定值。(沒人會(huì)閑著無聊頻繁改變操作系統(tǒng)分辨率)

通過操作系統(tǒng)設(shè)置來手動(dòng)調(diào)節(jié)邏輯像素

我屏幕的設(shè)備分辨率是1920*1200(單位:設(shè)備像素),當(dāng)前的分辨率設(shè)置下邏輯分辨率是1280*800(單位:設(shè)備獨(dú)立像素)。從圖中可以驗(yàn)證,橫、縱方向的設(shè)備像素?cái)?shù)量恰好是設(shè)備獨(dú)立像素的1.5倍。這也意味著,設(shè)備獨(dú)立像素的邊長(zhǎng)是設(shè)備像素邊長(zhǎng)的1.5倍。

window.devicePixelRatio在下文會(huì)解釋。

css像素

在CSS中使用的px都是指css像素,比如width: 128px。css像素的大小是很容易變化的。當(dāng)我們縮放頁面的時(shí)候,元素的css像素?cái)?shù)量不會(huì)改變,改變的只是每個(gè)css像素的大小。也就是說width: 128px的元素在縮放200%以后,寬度依然是128個(gè)css像素,只不過每個(gè)css像素的寬度和高度變?yōu)樵瓉淼膬杀丁H绻驹貙挾葹?28個(gè)設(shè)備獨(dú)立像素,那么縮放200%以后元素寬度為256個(gè)設(shè)備獨(dú)立像素(css像素寬度始終是128)。

開發(fā)者在開發(fā)的時(shí)候基本上只用考慮css像素,在這里介紹設(shè)備像素和設(shè)備獨(dú)立像素只是為了講述頁面縮放的原理,以及方便以后理解viewport。

css像素與設(shè)備獨(dú)立像素的關(guān)系

縮放比例就是css像素邊長(zhǎng)/設(shè)備獨(dú)立像素邊長(zhǎng)
縮放比例為100%的情況下,一個(gè)css像素大小等于一個(gè)設(shè)備獨(dú)立像素。

css像素與設(shè)備像素的關(guān)系

window.devicePixelRatio設(shè)備像素比,devicePixelRatio = (在相同長(zhǎng)度的直線上)設(shè)備像素的數(shù)量 / CSS像素的數(shù)量。這個(gè)比例也等價(jià)于CSS像素邊長(zhǎng)/設(shè)備像素邊長(zhǎng)。如devicePixelRatio=2,表示在相同長(zhǎng)度的直線上,設(shè)備像素的數(shù)量是CSS像素?cái)?shù)量的2倍,因此CSS像素的邊長(zhǎng)是設(shè)備像素的2倍。
縮放會(huì)導(dǎo)致CSS像素邊長(zhǎng)的改變,從而導(dǎo)致window.devicePixelRatio的改變!

例子


我的屏幕寬度是1280個(gè)設(shè)備獨(dú)立像素,我將div寬度設(shè)為了1280px(css像素),當(dāng)縮放為100%的時(shí)候,DIV恰好撐滿整個(gè)屏幕,不會(huì)出現(xiàn)橫向滾動(dòng)條。(這說明縮放比例為100%的時(shí)候一個(gè)CSS像素完全等于一個(gè)設(shè)備獨(dú)立像素。)

這里有一個(gè)小坑點(diǎn)。如果縱向滾動(dòng)條存在的話,它會(huì)占據(jù)一點(diǎn)點(diǎn)寬度,這時(shí)如果我還將元素寬度設(shè)為屏幕寬度1280px,屏幕就無法裝下整個(gè)元素,然后就會(huì)出現(xiàn)橫向滾動(dòng)條。
在上面這個(gè)例子中因?yàn)榭v向滾動(dòng)條不存在,所以沒有這個(gè)問題,將來在開發(fā)的時(shí)候要注意。

注意到我設(shè)置了5px的橙色邊框,為什么最終的寬度不是1280+5+5=1290呢?因?yàn)槲医o所有元素加上了box-sizing: border-box的樣式,這樣我設(shè)置的邊框?qū)挾染蜁?huì)包含在width中,也就是最終加上邊框以后寬度為1280px


當(dāng)我縮小瀏覽器窗口的時(shí)候滾動(dòng)條出現(xiàn)了。因?yàn)閐iv的寬度沒有改變,無論以什么單位衡量(設(shè)備像素、設(shè)備獨(dú)立像素還是CSS像素)。

因?yàn)榭s放依然是100%,css像素邊長(zhǎng)/設(shè)備獨(dú)立像素邊長(zhǎng)依然是1:1。


窗口最大化,當(dāng)我縮放200%時(shí),屏幕只能顯示DIV的左半部分了,這時(shí)DIV的寬度依然是1280個(gè)css像素,但是它寬度變成了2560個(gè)設(shè)備獨(dú)立像素。


以下是測(cè)試用的簡(jiǎn)單代碼,大家可以自己在Chrome DevTools中試試!

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
    <title>test</title>
    <style>
        * {
            padding: 0;
            margin: 0;
            box-sizing: border-box;
        }
        
        body {
            text-align: center;
            width: 100%;
        }
        
        #box {
            background: lightblue;
            width: 100%;
            height: 1000px;
            border-radius: 20px;
            border: 5px solid orangered;
        }
    </style>
</head>

<body>
    <div id="box">this is box<br> 1
        <br> 2
        <br> 3
        <br> 4
        <br> 5
        <br> 6
        <br> 7
        <br> 8
        <br> 9
        <br> 10
        <br>
    </div>
</body>

</html>

參考文章:http://weizhifeng.net/viewports.html


歡迎閱讀我的下一篇文章,它使用這篇文章介紹的3個(gè)概念,來解釋前端開發(fā)中與尺寸有關(guān)的概念和屬性。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容