古語有云,沒有規矩則不成方圓。秦滅六國以後爲了促進國內生產力的發展,也是大力推動全國度量衡的統一。車同軌,書同文。與「尺寸」相關的問題(手動滑稽),從古至今一直爲人們所關注。因此在個人處女文章中,也決定大致講講在前端領域裏面的「尺寸」問題。css
目前的國內的前端開發圈子中,最常使用到的關於「尺寸」的單位,應該是 px , rem , em 這三位。本文主要介紹這三種尺寸單位是怎麼來的,能作什麼,要怎麼用。html
在通常的計算機應用中,px表示像素點,即屏幕上每個可發光的單元點,好比咱們所說的1080p屏幕,那指的就是寬度達到1080px的屏幕,還有2k屏,4k屏,也是經過計算像素點的數量而得出的屏幕分類與稱呼。從理論上來講,像素點是顯示終端最小的可顯示單位,小於1個像素的內容,是沒有辦法完美的顯示在屏幕上。這也是爲何早期屏幕的畫面容易出現鋸齒的緣由。前端
上面這一段所介紹的是硬件上的像素,通常咱們稱爲「物理像素」。而在前端的長度單位裏面的px的概念,與「物理像素」略有不一樣。瀏覽器在某些設備(如iphone系列)上,會將兩個甚至更多的物理像素點合併爲一個顯示上的「點」去進行計算和渲染。這就涉及到另外一個概念:「dpr」,這個在後面的文章會進一步深刻介紹。而在瀏覽器上的一個「點」,咱們稱爲「邏輯像素」,與「物理像素」概念相對應,也就是咱們在css上所使用的 px 。chrome
px單位的使用很是簡單,好比咱們須要一個寬度爲300px,高度爲100px的長方形div:瀏覽器
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title>px單位長方形</title> <style> #test1{width:300px;height:100px;background:#bfa;} </style> </head> <body> <div id="test1"></div> </body> </html>
使用px做爲單位,對於pc端的開發來講具備較大的優點:iphone
但若是是在移動端的開發上,px做爲單位則顯得有些力不從心了。模塊化
因爲手機以及平板電腦等移動終端的普及,移動端的開發也已經佔了前端開發的半壁江山。而移動端因爲其設備終端分辨率尺寸的多樣化,以及橫豎屏切換致使寬高比差別較大等緣由。使用固定的px做爲尺寸單位就很容易出現字體、形狀的過大或太小,對於用戶瀏覽和使用網站來講形成困擾。而爲了解決這一問題,w3c標準也從最初的px單位開始,衍生出瞭如 em , rem , vh ,vh 等一系列單位。而在中國國內,使用最爲普遍的就是 rem 單位。但要說 rem 單位以前,咱們首先要來講一說 em 這個單位。字體
em 與 rem 只差了一個字母,他們的概念也是相近。理解了 em 就能更好的理解 rem 這個單位。網站
相傳從3000多年前古埃及的紙草書中,發現了人前臂的圖形。用人的前臂做爲長度單位叫「腕尺」;10世紀英國國王埃德加,把他的拇指關節之間的長度定爲「1寸」。這裏的「腕尺」和「寸」,其實是一種相對的單位,若是兩個埃及法老,一個身高一米五不到,一個身高兩米,那他們的「腕尺」長度確定是不同的。但毫無疑問的是,他們的子民都會跟隨他們的法老使用一樣的「腕尺」做爲他們的長度量度單位。因此只要新法老一上任,全國子民的「腕尺」也會跟着改變。而em單位,在原理上與這一制度至關接近。ui
em 的定義是元素所屬的父元素的字體大小。若是某個元素的字體大小(font-size)爲20px,那麼它裏面的元素的 1em 換算過來也是20px。
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title>em單位</title> <style> .content{ background: #bfa; } </style> </head> <body> <div id="test1" style="font-size: 50px"> <!-- test1的字體大小是50px,因此裏面的content 實際寬度是150px;實際高度是50px--> <div class="content" style="width: 3em;height: 1em;"></div> </div> <br/><br/> <div id="test2" style="font-size: 20px"> <!-- test2的字體大小是20px,因此裏面的content 實際寬度是60px;實際高度是20px--> <div class="content" style="width: 3em;height: 1em;"></div> </div> </body> </html>
em的單位通常的使用場景爲段前段後的空行,或是在按字號倍數設置行高(如word中經常使用的1.5倍/2倍行高等),另外,對於模塊化的設計而言,採用em單位應該也是一個不錯的方案(模塊內的元素統一度量單位,編輯時只需修改模塊字體大小一個參數)。
理解了 em 單位以後,rem 這個就比較好理解了。rem 裏面的這個「r」表明的就是 root ,也就是根。rem所指的也是整個html文檔的根節點(html)的字體大小。若是說 em 是一方諸侯,那 rem 那就是號令四海八荒的天子了。只要元素是在html文檔中顯示,不管其是否脫離文檔流,是否有絕對定位、固定定位等影響,元素中的1rem都是html標籤上所定義的font-size。
也正是rem的這一種惟一性,使其在移動端的開發中備受青睞。還在使用px的日子裏,每適配一個屏幕,各個元素的尺寸大小所有要算一遍,心好累。自從使用了rem,屏幕大小有變化,那隻要根節點(html)的字體大小一變,就如同皇上下的聖旨,八荒六合無不拜服,各個元素麻溜地就把本身的尺寸給跟着調整過來了,順心!
在這裏我分享一套rem適配方案,並補充一些自個人註釋:
<!DOCTYPE html> <html> <head lang="en"> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <!-- viewport設置視口參數,寬度爲設備寬度,縮放比例固定爲1--> <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=0, minimal-ui"> <title>rem解決方案</title> <script> (function(win) { var doc = win.document; var html = doc.documentElement; // 基於640px方案的設計稿 //////////////////////////////////////////////////// // 通用的作法是將設計稿中的100px換算爲1rem // 所以,當咱們已知設計稿的寬度baseWidth,還有屏幕的實際寬度clientWidth時,1rem對於屏幕的實際寬度爲: // html-font-size = clientWidth / (baseWidth/100) px /////////////////////////////////////////////////// var baseWidth = 640, grids = baseWidth / 100, resizeEvt = 'orientationchange' in win ? 'orientationchange' : 'resize', recalc = function() { // 默認尺寸爲320px var clientWidth = html.clientWidth || 320; // 若是屏幕尺寸大於640,則按640寬度進行計算 if (clientWidth > 640) { clientWidth = 640 } html.style.fontSize = clientWidth / grids + 'px'; document.querySelector('.content').style.display = 'block'; }; if (!doc.addEventListener) return; win.addEventListener(resizeEvt, recalc, false); doc.addEventListener('DOMContentLoaded', function() { setTimeout(recalc) }, false); })(window); </script> <style> @media screen and (min-width: 641px) { /*當屏幕大小大於640px時,顯示區域寬度爲640px並水平居中*/ .content { width: 640px; margin: auto; } } .content{background: #baf;} .rem_box{ width: 3.2rem; background: #fba; font-size: 0.2rem; margin: auto; } </style> </head> <body> <div class="content"> <div class="rem_box"> 不管屏幕如何縮放,橙色區域的寬度永遠是紫色區域寬度的一半,裏面的字體大小也會隨屏幕大小變化而同步變化(除非小於12px) </div> </div> </body> </html>
rem的使用比較普遍並且成熟,包括像手機淘寶等網站項目,也是使用了rem做爲其解決方案。目前現代瀏覽器對於rem的支持也是至關不錯,下面是canIuse上提供的rem的兼容性查詢結果。
本文到這裏也就接近尾聲了,px rem 和 em 這三個概念在前端的知識中理解起來不算困難,一樣也不須要死記硬背。只要肯多寫,多試,多練,相信不用多久,你也能熟練掌握這三種利器,而且運用到實際的開發過程當中。