CSS尺寸單位介紹

陌上寒發表於2019-03-13

前端開發過程中,尺寸單位是我們必須用到的,下面我們對css中常見的幾種尺寸單位px,em,rem,rpx進行逐一介紹 在這之前,需要先對幾個概念進行普及介紹

基本概念

(以下概念讀起來可能有些晦澀,如果看不懂也沒關係)

畫素

它不是自然界的物理長度,指基本原色素及其灰度的基本編碼。

css中的畫素只是一個抽象的單位,在不同的裝置或不同的環境中,css中的1px所代表的裝置物理畫素是不同的。
在為桌面瀏覽器設計的網頁中,我們無需對這個津津計較,但在移動裝置上,必須弄明白這點。
在早先的移動裝置中,螢幕畫素密度都比較低,如iphone3,它的解析度為320x480,在iphone3上,一個css畫素確實是等於一個螢幕物理畫素的。
後來隨著技術的發展,移動裝置的螢幕畫素密度越來越高,從iphone4開始,蘋果公司便推出了所謂的Retina屏,解析度提高了一倍,變成640x960,但螢幕尺寸卻沒變化,這就意味著同樣大小的螢幕上,畫素卻多了一倍,這時,一個css畫素是等於兩個物理畫素的。其他品牌的移動裝置也是這個道理。

物理畫素

它是顯示器(電腦、手機螢幕)最小的物理顯示單位,物理畫素指的是顯示器上最小的點。物理畫素的大小取決於螢幕。是一個無法改變的屬性。

裝置獨立畫素

我上一張圖,你就會理解什麼是裝置獨立畫素

CSS尺寸單位介紹
就是我們開發過程中使用的css中的px

裝置畫素比(device pixel radio)

裝置畫素比 = 物理畫素 / 裝置獨立畫素,單位是dpr!(device pixel radio)

Retina螢幕

所謂“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

預設情況下畫素px是相對於螢幕解析度而言,比如說我們的螢幕解析度是1440 X 900,說的就是畫素1440px X 900px;

這裡會遇到另一種情況

瀏覽器縮放

縮放是縮放CSS畫素(縮放比例為1時,一個CSS畫素等於一個螢幕畫素),就是在螢幕解析度不變的情況下,使用者對瀏覽進行了縮放

強調一點,使用者的縮放行為是對瀏覽器進行的,縮放的是css畫素,而非解析度,解析度是螢幕的解析度,不論你怎麼縮放當前頁面,螢幕解析度都不會改變

我們知道在移動端可以在一定程度上控制使用者的縮放行為,也可以禁止使用者縮放

<meta name="viewport" content="width=device-width,initial-scale=1.0">
複製程式碼

content屬性值 :

  1. width:可視區域的寬度,值可為數字或關鍵詞device-width
  2. height:可視區域的高度,值可為數字或關鍵詞device-height
  3. intial-scale:頁面首次被顯示是可視區域的縮放級別,取值1.0則頁面按實際尺寸顯示,無任何縮放
  4. maximum-scale=1.0, minimum-scale=1.0;可視區域的縮放級別,
  5. maximum-scale使用者可將頁面放大的程式,1.0將禁止使用者放大到實際尺寸之上。
  6. user-scalable:是否可對頁面進行縮放,no 禁止縮放

但是在pc端就麻煩了 windows:

  • ctrl + +/-
  • ctrl + 滾輪
  • 瀏覽器選單欄

mac:

  • cammond + +/-
  • 瀏覽器選單欄

由於瀏覽器選單欄屬於系統軟體許可權,沒發控制,我們可以通過js控制ctrl/cammond + +/- 或 Windows下ctrl + 滾輪 縮放頁面的情況

em

本人在實際開發過程中並沒有使用過em單位,但是後面要說的rem是基於em的,所以,對em進行簡單介紹

em 是相對長度單位。相對於當前物件內文字的字型尺寸。如當前對行內文字的字型尺寸未被人為設定,則相對於瀏覽器的預設字型尺寸。

  • em的值並不是固定的;
  • em會繼承父級元素的字型大小;
  • 任意瀏覽器的預設字型高都是16px。所有未經調整的瀏覽器都符合: 1em=16px。body選擇器中宣告Font-size=62.5%<==>1em=10px。

看個栗子吧

<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;

CSS尺寸單位介紹

我們通過瀏覽器檢視,發現第四級的fong-size為15px;

我們取消第三級parent-font 的字型大小

CSS尺寸單位介紹

我們通過瀏覽器檢視,發現第四級的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

rem 是CSS3的一個相對單位(root em,根em)

使用rem為元素設定字型大小時,仍然是相對大小,但相對的只是HTML根元素

只要html的font-size大小不變,1rem所代表的font-size大小就不會變,rem只取決於html的font-size

rem解決了哪些問題

移動裝置的寬度是各種各樣的,每個裝置的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,那怎麼辦呢?

rpx

我不基於html的font-size了,我基於一個別的值就行了,你也不需要計算這個值,我給你計算了,這就是rpx。 最終的效果就是,你開發時在iphon6的設計稿上量了多少px,就寫多少rpx就行了,完美適配,perfect!

CSS尺寸單位介紹
原文連結

參考連結

【微信小程式】——rpx、px、rem等尺寸間關係淺析

px、物理畫素、rem、rpx的關係

阻止pc端瀏覽器縮放js程式碼

viewport解釋 CSS中大小單位px,em,rem 以及微信小程式的rpx