前端開發過程當中,尺寸單位是咱們必須用到的,下面咱們對css中常見的幾種尺寸單位px,em,rem,rpx進行逐一介紹
在這以前,須要先對幾個概念進行普及介紹javascript
(如下概念讀起來可能有些晦澀,若是看不懂也不要緊)css
它不是天然界的物理長度,指基本原色素及其灰度的基本編碼。html
css中的像素只是一個抽象的單位,在不一樣的設備或不一樣的環境中,css中的1px所表明的設備物理像素是不一樣的。
在爲桌面瀏覽器設計的網頁中,咱們無需對這個津津計較,但在移動設備上,必須弄明白這點。
在早先的移動設備中,屏幕像素密度都比較低,如iphone3,它的分辨率爲320x480,在iphone3上,一個css像素確實是等於一個屏幕物理像素的。
後來隨着技術的發展,移動設備的屏幕像素密度愈來愈高,從iphone4開始,蘋果公司便推出了所謂的Retina屏,分辨率提升了一倍,變成640x960,但屏幕尺寸卻沒變化,這就意味着一樣大小的屏幕上,像素卻多了一倍,這時,一個css像素是等於兩個物理像素的。其餘品牌的移動設備也是這個道理。前端
它是顯示器(電腦、手機屏幕)最小的物理顯示單位,物理像素指的是顯示器上最小的點。物理像素的大小取決於屏幕。是一個沒法改變的屬性。java
我上一張圖,你就會理解什麼是設備獨立像素小程序
就是咱們開發過程當中使用的css中的pxwindows
設備像素比 = 物理像素 / 設備獨立像素,單位是dpr!(device pixel radio)微信小程序
所謂「Retina」是一種顯示標準,是把更多的像素點壓縮至一塊屏幕裏,從而達到更高的分辨率並提升屏幕顯示的細膩程度。也被稱爲視網膜顯示屏 ——百度百科
由於Retina屏幕的出現,在pc端默認狀況下,css中的1px等於1物理像素,但在移動端1px不必定等於1物理像素,好比說iPhone的設備獨立像素是375 667,由於它使用了Retina屏幕,他的dpr是2,因此iPhone 6 的物理像素爲 750 1334瀏覽器
在不一樣的屏幕上(普通屏幕 vs retina屏幕),css中1px所呈現的大小(物理尺寸)是一致的,不一樣的是1px所對應的物理像素個數是不一致的。微信
在普通屏幕下,1px 對應 1個物理像素(1:1)。 在Retina屏幕下(dpr=2),1px對應 2x2個物理像素(1:4)。
你會發現,在移動端開發中使用了圖片(img標籤),2倍圖要比1倍圖清晰,就是這個緣故
默認狀況下像素px是相對於屏幕分辨率而言,好比說咱們的屏幕分辨率是1440 X 900,說的就是像素1440px X 900px;
這裏會遇到另外一種狀況
縮放是縮放CSS像素(縮放比例爲1時,一個CSS像素等於一個屏幕像素),就是在屏幕分辨率不變的狀況下,用戶對瀏覽進行了縮放
強調一點,用戶的縮放行爲是對瀏覽器進行的,縮放的是css像素,而非分辨率,分辨率是屏幕的分辨率,不論你怎麼縮放當前頁面,屏幕分辨率都不會改變
咱們知道在移動端能夠在必定程度上控制用戶的縮放行爲,也能夠禁止用戶縮放
<meta name="viewport" content="width=device-width,initial-scale=1.0">
content屬性值 :
可是在pc端就麻煩了
windows:
mac:
因爲瀏覽器菜單欄屬於系統軟件權限,沒發控制,咱們能夠經過js控制ctrl/cammond + +/- 或 Windows下ctrl + 滾輪 縮放頁面的狀況
本人在實際開發過程當中並無使用過em單位,可是後面要說的rem是基於em的,因此,對em進行簡單介紹
em 是相對長度單位。相對於當前對象內文本的字體尺寸。如當前對行內文本的字體尺寸未被人爲設置,則相對於瀏覽器的默認字體尺寸。
看個栗子吧
<body> <style> html { font-size: 50px; } .my-div { width: 100%; height: 500px; margin-top: 50px; background-color: gray; font-size: 40px; } .my-div .parent-font { font-size: 30px; } .my-div .parent-font .child-font { font-size: 0.5em; } </style> <div class="my-div"> <p class="parent-font"> 我是父級文字 <span class="child-font">我是子級文字</span> </p> </div> </body>
html代碼中,
第一級,html的 font-size: 50px;
第二級,my-div 的 font-size: 40px;
第三級,parent-font 的 font-size:30px;
第四級,child-font 的 font-size: 0.5em;
咱們經過瀏覽器查看,發現第四級的fong-size爲15px;
咱們取消第三級parent-font 的字體大小
咱們經過瀏覽器查看,發現第四級的fong-size爲20px;
當咱們取消第三級font-size後,第三級的字體大小爲40px;
因此咱們說em的字體大小不是固定的,em的大小取決於父級的字體大小
當父級的字體大小爲20px,子級的1em就是20px
當父級的字體大小爲30px,子級的1em就是30px
那麼說font-size存在着繼承父級的特色
咱們在第一級html中設置font-size,第二級繼承第一級,第三級繼承第二級,第四級繼承第三級,以此類推
每一級都繼承自它的父級,也就是說每一級的em所表明的px大小都不是固定的,由於他們的父級不是同一個,因此em的應用場景並很少。
那麼若是是em的都繼承自同一個地方,是否是能夠解決不少問題呢?
這時候rem出現了
rem 是CSS3的一個相對單位(root em,根em)
使用rem爲元素設定字體大小時,仍然是相對大小,但相對的只是HTML根元素
只要html的font-size大小不變,1rem所表明的font-size大小就不會變,rem只取決於html的font-size
移動設備的寬度是各類各樣的,每一個設備的dpr也不一樣,換句話說就是不一樣設備每一行的物理像素數不一樣,能顯示的css的px數也不一樣,
若是咱們寫一個div,寬度是375px,375px在這個屏幕(iPhone6)上是剛剛滿屏,由於這個屏幕寬度剛剛是375px( 設備獨立像素),
當咱們換另外一個寬度是414px的設備(iPhone6Plus)時,這個寬度375px的div就沒法鋪滿這個屏幕,一樣的當換一個iPhone5(320px),又會出現滾動條,安卓機的寬度更是五花八門,使用media媒體查詢不靠譜,由於它不能覆蓋全部的機型寬度
咱們以前說rem的大小是相對於html的font-size的,若是html的font-size根據不一樣設備的寬度作動態計算,問題就會獲得解決
咱們寫頁面都是根據UI設計稿來作的,咱們假設UI設計稿的寬度是750px(750px是常規寬度,固然也能夠是640px或是其餘寬度,可是整個項目,寬度必須統一),惟一不變就是就屏幕寬度,咱們的html的font-size(rem)只取決於設備寬度
因而
document.documentElement.style.fontSize = 100 * ( document.documentElement.clientWidth / 750) + 'px'
html的font-size:document.documentElement.style.fontSize
設備的寬度:document.documentElement.clientWidth
750:UI設計稿的寬度
爲了方便計算咱們將font-size x 100,方便計算(乘100不是必須的,我接觸過一些項目就不是乘以100,可是UI設計稿中使用了sketch作了動態計算,但我仍是建議乘100,否則遇到psd的設計圖就很麻煩了)
對上面的js作些完善
const fontFun = function () { let docEl = document.documentElement let resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize' const recalc = function () { let clientWidth = docEl.clientWidth if (!clientWidth) return docEl.style.fontSize = 100 * (clientWidth / 750) + 'px' } if (!document.addEventListener) return window.addEventListener(resizeEvt, recalc, false) window.addEventListener('pageshow', recalc, false) document.addEventListener('DOMContentLoaded', recalc, false) } export { fontFun }
對以上代碼不作過多解釋
也能夠這樣寫
(function(doc, win) { var docEl = doc.documentElement, resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize', recalc = function() { var clientWidth = docEl.clientWidth if (!clientWidth) return docEl.style.fontSize = 100 * (clientWidth / 750) + 'px' } if (!doc.addEventListener) return win.addEventListener(resizeEvt, recalc, false) win.addEventListener('pageshow', recalc, false) doc.addEventListener('DOMContentLoaded', recalc, false) })(document, window)
iPhone5(320px)下html的font-size:42.6667px,1rem=42.6667px
iPhone6(375px)下html的font-size:50px,1rem=50px
iPhone6Plus(414px)下html的font-size:55.2px,1rem=55.2px
rem是繼承自html的font-size,可是小程序中沒有html,那怎麼辦呢?
我不基於html的font-size了,我基於一個別的值就好了,你也不須要計算這個值,我給你計算了,這就是rpx。
最終的效果就是,你開發時在iphon6的設計稿上量了多少px,就寫多少rpx就好了,完美適配,perfect!
更多前端資源請關注微信公衆號「前端陌上寒」
參考連接