一、写在前面的话

  作为一面前端开发者,对 px 、em 、 rem 应该是再熟悉不过了,但大多数小伙伴应该都和我一样仅仅停留在了解的层面,并不是实质性的掌握它们。本文对三者进行了详细的总结和详细说明,不熟悉的各位小伙伴阅读本文一定会有所收获,如果你对这三者已经了解的非常透彻,那本文可能对你的帮助不大。

二、简述

  px、em、rem都是计量单位,都能表示尺寸,但是有有所不同,而且其各有各的优缺点。

三、PX (pixel)

  Px 表示“绝对尺寸”(并非真正的绝对),实际上就是css中定义的像素(此像素与设备的物理像素有一定的区别),利用px设置字体大小及元素宽高等比较稳定和精确。Px的缺点是其不能适应浏览器缩放时产生的变化,因此一般不用于响应式网站。

注:
1、像素 1024x768 的,表示的是水平方向是 1024 个像素点,垂直方向是 768个 像素点。  
2、以上所述 px 为 css 中定义的像素(以下简称 css 像素),与实际的物理像素是有区别的,早期电脑屏幕的物理像素与 css 像素相同,但是随着科技的发展,高精度屏幕开始出现在人们的视野中。以 iPhone 的 Retina
  屏为例,其物理像素与 css 像素关系见下图。

响应式布局之 px、em、 rem-LMLPHP

  为此移动端浏览器以及某些桌面浏览器引入了 devicePixelRatio(DPR 设备像素比)属性,其官方的定义为:设备物理像素和设备独立像素的比例,也就是 devicePixelRatio = 物理像素 / 独立像素。而 css 像素=独立像素,由此我们可以得出 devicePixelRatio = 物理像素 / css 像素,进而可以推算出该设备上一个 css 像素代表几个物理像素。例如 iPhone 的 retina 屏的 devicePixelRatio = 2,那么该设备上一个 css 像素相当于 2 个物理像素。了解更多像素相关知识,可以参考:https://github.com/jawil/blog/issues/21

四、em

  em是相对长度单位。相对于当前对象内文本的字体尺寸。如当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸。

 响应式布局之 px、em、 rem-LMLPHP

注意:
1、em 的值并不是固定的

 2、em 会继承父级元素的字体大小。

3、任意浏览器的默认字体高都是 16px。所有未经调整的浏览器都符合: 1em=16px。那么 12px=0.75em,10px=0.625em。为了简化 font-size 的换算,需要在 css 中的 body 选择器中声明 Font-size=62.5%,这就使 
em 值变为 16px*62.5%=10px, 这样 12px=1.2em, 10px=1em, 也就是说只需要将你的原来的px数值除以 10,然后换上 em 作为单位就行了

 综上所述,em 作为响应式布局的单位仍旧会有一些问题, 当设置父元素的字体大小后,子元素的 em 就发生了变化,需要进行重新计算,为了解决这个问题便出现了 rem 。

五、rem

  rem是CSS3新增的一个相对单位(root em,根em),这个单位引起了广泛关注。这个单位与em有什么区别呢?区别在于使用rem为元素设定字体大小时,仍然是相对大小,但相对的只是HTML根元素。这个单位可谓集相对大小和绝对大小的优点于一身,通过它既可以做到只修改根元素就成比例地调整所有字体大小,又可以避免字体大小逐层复合的连锁反应。目前,除了IE8及更早版本外,所有浏览器均已支持rem。对于不支持它的浏览器,应对方法也很简单,就是多写一个绝对单位的声明。这些浏览器会忽略用rem设定的字体大小。下面就是一个例子:

p {font-size:14px; font-size:.875rem;}
/*
  注: 选择使用什么字体单位主要由你的项目来决定,如果你的用户群都使用最新版的浏览器,那推荐使用rem,如果要考虑兼容性,那就使用px,或者两者同时使用。
*/

  浏览器的默认字体大小为 16px , px 与 rem 转换如下:

响应式布局之 px、em、 rem-LMLPHP

rem 的适配原理  

动态获取当前视口宽度 width,除以一个固定的数 W(通常取设计稿宽度),得到 rem 的值。表达式为 n = width / W,html{ font-size: n(px)},此时的 rem = n,
因为 rem 等于根标签的字体大小。
计算:
  设计稿宽度为 W
  屏幕宽度为 CW
  n(px) = CW / W
  html {font-size: n(px);} ==> n(px) = 1 rem (例:html: { font-size: 16px;} ==> 1rem = 16px)
  
  假设我们需要计算一个设计稿上测得宽度为 x(px) 的 div 的 rem 值为多少,可以有以下等式:
    x(px) / W = xRem / CW
 ==> xRem = (CW * x(px)) / W
 ==> xRem = (CW / W) * x(px)
 ==> xRem = 1rem * x(px)
 假设 x = 20px --> xRem = 20rem
 
注: 但是注意当设计稿宽度 W = 750px 时,n = CW / W 得到的值会很小,浏览器会有最小字体大小为 12px 的限制,因此建议做放大 100 倍处理,即将 html 的字体大小
   设置为当前计算值得 100 倍,html{font-size: (CW / W) * 100;},此时计算 rem 只需要将设计稿尺寸除以 100 即可。
// 适配代码如下
<script type="text/javascript">
//手机端的适配
document.addEventListener("DOMContentLoaded",function(){
document.getElementsByTagName("html")[0].style.fontSize=(document.documentElement.clientWidth/750)*100+"px";
}); window.onresize = function(){
document.getElementsByTagName("html")[0].style.fontSize=(document.documentElement.clientWidth/750)*100+"px";
}
</script>

px 与 rem 的选择?

  1、对于只需要适配少部分手机设备,且分辨率对页面影响不大的,使用px即可 。

  2、对于需要适配各种移动设备,使用rem,例如只需要适配iPhone和iPad等分辨率差别比较挺大的设备。

六、结语

  好吧,好像没啥要总结的,能坚持别人不能的坚持得,才能拥有别人不能拥有的!致大家及自己。

05-19 00:10