概念
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>