pxemrem讲解与应用

44次阅读

共计 3000 个字符,预计需要花费 8 分钟才能阅读完成。

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 英寸,分辨率也是:19201080 的。由公式一:当分辨率一样时,设备 尺寸越大,像素密度越小。所以 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 时,我们只需要改变 bodyfont-size,那么其他子元素宽度就能动态变化了,显然方便很多。

rem 是什么?

‘rem’ 是 ’css3’ 新增的一个相对长度单位,它的出现是为了解决 em 的缺点,em 可以说是相对于父级元素的字体大小,当父级元素字体大小改变时,又得重新计算。rem 出现就可以解决这样的问题,rem 只相对于根目录,即 HTML 元素。有了 rem 这个单位,我们只需要调整根元素 htmlfont-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);

总结

  1. 逻辑像素(css 的 px) = 设备像素 × 缩放因子
  2. 为了移动端更好的适配我们引入了 emrem这 2 个动态单位
  3. em的大小与父元素的 font-size 有关,rem的大小与根元素 htmlfont-size有关
  4. 一般在移动端我们会使用 js 动态计算跟节点 htmlfont-size来达到自适应的目的。

正文完
 0