网络知识

px、em、rem三者的区别

概念

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

px

px是html长度单元像素。譬如我们电脑、手机显示屏均使用于是像素为单元,也就是px为单位。表示屏甄别率1200*800实际上便是指1200px * 800px。

px等于pixel的缩写啦,pixel即像素,它不是自然界的长度单元。px是即是一张图片中最小的点,一张位图等于由这些点构成的。1024px便是1024像素,最容易的你梗概在windows桌面属性里的“设置”看到,要是是1024×768,也即是说水准倾向上有1024个点,垂直左袒上有768个点。谁能说出一个“点”有多长多大么?或是画的很小,也或许很大。要是点很小,那画面就清晰,咱们称它为“判别率高”,反之,便是“分辨率低”。所以,像素的大小是会“变”的,也喻为“相对于长度”。

px:像素(Pixel),相对长度单位。像素px是相对于显示器屏幕分辨率而言的,手机上的100px和电脑上的100px其实绝对长度是不一样的,肉眼就能看出来,严谨的你可以用尺子量一下,这就是因为他们的分辨率不同。还有相当多的人认为px是绝对单位,这里告诉大家不要人与亦云,多思考。

  • px像素(Pixel),像素px是相对于显示器屏幕分辨率而言的
  • px作为单位是固定不变的,不能适应浏览器缩放时产生的变化,因此一般不用于响应式网站。

em

em:相对于当前对象内文本的字体尺寸,会继承父级的字体尺寸。也就是说 1em=1*父级元素的font-size。明显,在多层嵌套的结构下使用em的话,由于层层继承的缘故,要确定最终呈现出来的尺寸会非常麻烦,过于混乱。

  • em的值不固定,会继承父元素的字体大小,是一个相对单位
div { font-size: 12px;}
div > p { width: 10em;    /* 结果为120px */
 height: 10em;   /* 结果为120px */}

上述代码中,em单位是相对于父元素计算的,子元素的1em等于12px,因此10em就相当于120px。

rem

rem:相对于html根元素文本的字体尺寸,与中间层字体尺寸无关。也就是说 1rem=1*html元素的font-size。rem就相当于是一个全局缩放因子,改变它一个就可以缩放所有以它为单位的元素,只要将它与屏幕分辨率关联起来,就可以完成屏幕自适应展现。

  • rem是css3中新增的相对单位,相对于html根元素
  • 可以通过修改根元素字体大小就可以调整所有字体大小
  • 可以避免字体大小逐层复合的连锁反应
html {
 font-size: 14px;
}
div {
 font-size: 12px;
}
div > p {
 width: 10rem;    /* 结果为140px */
 height: 10rem;   /* 结果为140px */
}

上述代码中,rem单位是相对于<html>元素计算的,因此10rem的结果为140px。

与em单位相比,rem单位的优势在于,只通过修改<html>的文字大小,就可以改变整个页面中的元素大小,使用起来更加方便。

注意:任意浏览器的默认字体都是16px                                                                                   

区别

通过上述概念介绍可以看出区别如下:

  • px相对其他两个单位是固定不变的,不能适应浏览器缩放时产生的变化
  • em是根据父元素继承相应大小而不是固定的,rem是继承html根元素的大小

下面通过代码演示一下:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <style type="text/css">
            .em{
                width: 10em;
                height: 10em;
                background-color: red;
            }
            .rem{
                width: 10rem;
                height: 10rem;
                background-color: blue;
            }
        </style>
    </head>
    <body>
        <div class="box">
            <div class="em"></div>
            <div class="rem"></div>
        </div>
    </body>
</html>

运行效果如下:

因为父盒子box没有设置字体大小,即自动继承html根元素,默认字体大小为16px,所以两个子元素盒子都是:16 * 10 = 160

下面给box父盒子设置一个自己的字体大小:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <style type="text/css">
            .em{
                width: 10em;
                height: 10em;
                background-color: red;
            }
            .rem{
                width: 10rem;
                height: 10rem;
                background-color: blue;
            }
        </style>
    </head>
    <body>
        <div class="box" style="font-size: 8px;">
            <div class="em">em</div>
            <div class="rem">rem</div>
        </div>
    </body>
</html>

运行效果:

这里将父盒子box设置了font-size:8px ,所以em盒子就相对父盒子box的字体大小为:8 * 10 = 80 ,而rem盒子还是相对html根元素字体大小为:16 * 10 = 160

这就是em和rem两个计量单位的区别,个人感觉还是rem更香,修改根元素字体大小就能更改响应所有字体大小,而em存在字体大小逐层复合的连锁反应。所以用rem作为单位可以更好地适配移动端开发

rem 修改根元素字体大小


rem的优势                                                                                

使用rem的优势非常明显了,尤其是在现在屏幕分辨率千差万别的时代,只要将rem与屏幕分辨率关联起来就可以实现页面的整体缩放,所以设备上的展现都统一起来了。而且现在浏览器基本都已经支持rem了,兼容性也非常的好。在上文提问区中还有一些人说“QQX5内核浏览器不支持rem单位,在大部分android 机上的微信页面不起作用”,我表示没这样的事,还是那句话,多思考多验证。

rem的劣势                                                                                           

其实rem的优势也正是他的缺点,rem的屏幕自适应与当前两大平台的设计哲学不一致!从用户体验上来看,文字阅读的舒适度跟媒体介质大小是没关系的。简单的来说,你本来喜欢麻将那么大的红烧肉,一口一块爽爆了,但是服务员换了个大盘子,就给你上了砂锅那么大的一整块肉。因为盘子大了肉也要成比例放大~~

无论盘子大小,你都希望能一口吃下那块肉,文字阅读也是一样。字体根据媒介缩放是因为屏幕太小的时候,为了呈现更多的内容,因为频繁翻页的用户体验也是很差的。另外,图片视频的尺寸不应该随意缩放,如果图片视频的宽高都用rem关联起来, 这样虽然是等比缩放了,但是有时候我们并不想图片被放大。你看下图,对吧。

还有就是图片像素不高的时候,小屏到大屏的放大会让图片变模糊,这样还不如小尺寸看着顺眼。

关于优劣势的讨论可以看知乎上的讨论,我也引用了大神们的观点,标明一下出处哈。http://www.zhihu.com/question/21504656?

总体上来说,使用rem的优势远远大于劣势,对于上文提到的问题点,使用px+rem的方式还是可以得到很好的用户体验的。一般rem用于需要跟随屏幕变化的尺寸(这不是废话吗?),px用于字号,细边框等不应该随屏幕变化的元素上。在web APP中,rem的使用肯定会越来越普遍的,大家就慢慢探索吧。还是那句话,多思考,多从用户的角度思考问题,这才是前端思维。

关于rem实现自适应的具体解释可以看看isux组的这篇文章:https://isux.tencent.com/web-app-rem.html,里面实现自适应有两个途径,分别是media查询和js动态计算。提问区里面说到如果只是在页面底部用js动态计算的话,页面元素尺寸改变时会有一定的闪烁现象。建议是先在css里根据屏幕用@media初始化一遍html 的font-size,然后再用js计算。提问区里面还有人问js代码的,这样的问题博主都没兴趣回答了,我贴一份吧。

<script>

         (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 = 20 * (clientWidth / 320) + 'px';

             };

           if (!doc.addEventListener) return;

           win.addEventListener(resizeEvt, recalc, false);

           doc.addEventListener('DOMContentLoaded', recalc, false);

         })(document, window);

 </script>