从理解开始 谈谈px rem 和 em 的区别与联系
概述
古语有云,没有规矩则不成方圆。秦灭六国之后为了促进国内生产力的发展,也是大力推进全国度量衡的统一。车同轨,书同文。与“尺寸”相关的问题(手动滑稽),从古至今一直为人们所关注。所以在我的处女文章中,也决定大体讲讲在前端领域里面的“尺寸”问题。
目前的国内的前端开发圈子中,最常使用到的关于“尺寸”的单位,应该是 px , rem , em 这三位。本文主要介绍这三种尺寸单位是怎么来的,能做什么,要怎么用。
px(逻辑像素)
在一般的计算机应用中,px表示像素点,即屏幕上每一个可发光的单元点,比如我们所说的1080p屏幕,那指的就是宽度达到1080px的屏幕,还有2k屏,4k屏,也是通过计算像素点的数量而得出的屏幕分类与称呼。从理论上来说,像素点是显示终端最小的可显示单位,小于1个像素的内容,是没有办法完美的显示在屏幕上。这也是为什么早期屏幕的画面容易出现锯齿的原因。
上面这一段所介绍的是硬件上的像素,一般我们称为“物理像素”。而在前端的长度单位里面的px的概念,与“物理像素”略有不同。浏览器在某些设备(如iphone系列)上,会将两个甚至更多的物理像素点合并为一个显示上的“点”去进行计算和渲染。这就涉及到另一个概念:“dpr”,这个在后面的文章会进一步深入介绍。而在浏览器上的一个“点”,我们称为“逻辑像素”,与“物理像素”概念相对应,也就是我们在css上所使用的 px 。
px单位的使用非常简单,比如我们需要一个宽度为300px,高度为100px的长方形div:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>px单位长方形</title>
<style>
#test1{width:300px;height:100px;background:#bfa;}
</style>
</head>
<body>
<div id="test1"></div>
</body>
</html>
使用px作为单位,对于pc端的开发来说具有较大的优势:
- PC端的项目设计图的宽度和高度比例基本固定,而且屏幕相对较宽,使用px单位对于普通项目不会造成太多不友好的显示效果。
- 对于设计师与前端开发者对接而言,使用px单位能够降低单位转换的成本,提高开发速度。
- px概念比较清晰,对于入门开发者而言使用门槛低,比较友好。
但如果是在移动端的开发上,px作为单位则显得有些力不从心了。
由于手机以及平板电脑等移动终端的普及,移动端的开发也已经占了前端开发的半壁江山。而移动端由于其设备终端分辨率尺寸的多样化,以及横竖屏切换导致宽高比差异较大等原因。使用固定的px作为尺寸单位就很容易出现字体、形状的过大或过小,对于用户浏览和使用网站来说造成困扰。而为了解决这一问题,w3c标准也从最初的px单位开始,衍生出了如 em , rem , vh ,vh 等一系列单位。而在中国国内,使用最为广泛的就是 rem 单位。但要说 rem 单位之前,我们首先要来说一说 em 这个单位。
em(父元素字体大小)
em 与 rem 只差了一个字母,他们的概念也是相近。理解了 em 就能更好的理解 rem 这个单位。
相传从3000多年前古埃及的纸草书中,发现了人前臂的图形。用人的前臂作为长度单位叫“腕尺”;10世纪英国国王埃德加,把他的拇指关节之间的长度定为“1寸”。这里的“腕尺”和“寸”,实际上是一种相对的单位,如果两个埃及法老,一个身高一米五不到,一个身高两米,那他们的“腕尺”长度肯定是不一样的。但毫无疑问的是,他们的子民都会跟随他们的法老使用同样的“腕尺”作为他们的长度量度单位。所以只要新法老一上任,全国子民的“腕尺”也会跟着改变。而em单位,在原理上与这一制度相当接近。
em 的定义是元素所属的父元素的字体大小。如果某个元素的字体大小(font-size)为20px,那么它里面的元素的 1em 换算过来也是20px。
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>em单位</title>
<style>
.content{ background: #bfa; }
</style>
</head>
<body>
<div id="test1" style="font-size: 50px">
<!-- test1的字体大小是50px,所以里面的content 实际宽度是150px;实际高度是50px-->
<div class="content" style="width: 3em;height: 1em;"></div>
</div>
<br/><br/>
<div id="test2" style="font-size: 20px">
<!-- test2的字体大小是20px,所以里面的content 实际宽度是60px;实际高度是20px-->
<div class="content" style="width: 3em;height: 1em;"></div>
</div>
</body>
</html>
em的单位一般的使用场景为段前段后的空行,或是在按字号倍数设置行高(如word中常用的1.5倍/2倍行高等),另外,对于模块化的设计而言,采用em单位应该也是一个不错的方案(模块内的元素统一度量单位,编辑时只需修改模块字体大小一个参数)。
rem(根节点字体大小)
理解了 em 单位之后,rem 这个就比较好理解了。rem 里面的这个“r”代表的就是 root ,也就是根。rem所指的也是整个html文档的根节点(html)的字体大小。如果说 em 是一方诸侯,那 rem 那就是号令四海八荒的天子了。只要元素是在html文档中显示,无论其是否脱离文档流,是否有绝对定位、固定定位等影响,元素中的1rem都是html标签上所定义的font-size。
也正是rem的这一种唯一性,使其在移动端的开发中备受青睐。还在使用px的日子里,每适配一个屏幕,各个元素的尺寸大小全部要算一遍,心好累。自从使用了rem,屏幕大小有变化,那只要根节点(html)的字体大小一变,就如同皇上下的圣旨,八荒六合无不拜服,各个元素麻溜地就把自己的尺寸给跟着调整过来了,顺心!
在这里我分享一套rem适配方案,并补充一些自我的注释:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<!-- viewport设置视口参数,宽度为设备宽度,缩放比例固定为1-->
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=0, minimal-ui">
<title>rem解决方案</title>
<script>
(function(win) {
var doc = win.document;
var html = doc.documentElement;
// 基于640px方案的设计稿
////////////////////////////////////////////////////
// 通用的做法是将设计稿中的100px换算为1rem
// 因此,当我们已知设计稿的宽度baseWidth,还有屏幕的实际宽度clientWidth时,1rem对于屏幕的实际宽度为:
// html-font-size = clientWidth / (baseWidth/100) px
///////////////////////////////////////////////////
var baseWidth = 640,
grids = baseWidth / 100,
resizeEvt = 'orientationchange' in win ? 'orientationchange' : 'resize',
recalc = function() {
// 默认尺寸为320px
var clientWidth = html.clientWidth || 320;
// 如果屏幕尺寸大于640,则按640宽度进行计算
if (clientWidth > 640) {
clientWidth = 640
}
html.style.fontSize = clientWidth / grids + 'px';
document.querySelector('.content').style.display = 'block';
};
if (!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', function() {
setTimeout(recalc)
}, false);
})(window);
</script>
<style>
@media screen and (min-width: 641px) {
/*当屏幕大小大于640px时,显示区域宽度为640px并水平居中*/
.content {
width: 640px;
margin: auto;
}
}
.content{background: #baf;}
.rem_box{
width: 3.2rem;
background: #fba;
font-size: 0.2rem;
margin: auto;
}
</style>
</head>
<body>
<div class="content">
<div class="rem_box">
无论屏幕如何缩放,橙色区域的宽度永远是紫色区域宽度的一半,里面的字体大小也会随屏幕大小变化而同步变化(除非小于12px)
</div>
</div>
</body>
</html>
rem的使用比较广泛而且成熟,包括像手机淘宝等网站项目,也是使用了rem作为其解决方案。目前现代浏览器对于rem的支持也是相当不错,下面是canIuse上提供的rem的兼容性查询结果。

本文到这里也就接近尾声了,px rem 和 em 这三个概念在前端的知识中理解起来不算困难,同样也不需要死记硬背。只要肯多写,多试,多练,相信不用多久,你也能熟练掌握这三种利器,并且运用到实际的开发过程中。
从理解开始 谈谈px rem 和 em 的区别与联系的更多相关文章
- CSS中rem、em的区别
引用文档:http://www.divcss5.com/html/h529.shtml:http://blog.csdn.net/qq_35432904/article/details/5180422 ...
- rem和em的区别
原文链接:http://caibaojian.com/rem-vs-em.html rem 单位如何转换为像素值 当使用 rem 单位,他们转化为像素大小取决于页根元素的字体大小,即 html 元素的 ...
- rem与em的区别
这两个单位都是相对元素 rem相对根元素 em相对于父级元素
- rem、em、px的区别
px 像素(Pixel).相对长度单位.像素px是相对于显示器屏幕分辨率而言的. 特点: 1. IE无法调整那些使用px作为单位的字体大小: 2. 国外的大部分网站能够调整的原因在于其使用了em或re ...
- Rem与em的简单理解
Rem与em的简单理解 Em单位与像素px的转换 所得的像素值 = 当前元素的font-size * em的值 比如:div的font-size:12px 10em等同于120px 12*10 =12 ...
- CSS中px,em,rem,pt的区别及四者换算?
本文章重要说明px,em,rem,pt的区别以及四者之间的换算. em单位有如下特点 1. em的值并不是固定的; 2. em会继承父级元素的字体大小. 我们在写CSS的时候如果要用em为单位,需要注 ...
- 浅谈rem、em、px
1.px:像素(Pixel) px是相对长度单位,他是相对于显示器屏幕分辨率而言的 优点:比较稳定.精确 缺点:在浏览器 中放大或者缩小浏览页面,会出现页面混乱的情况. 如下例子: .buttonPX ...
- rem和em,px的使用
rem是CSS3中新增加的一个单位值,他和em单位一样,都是一个相对单位.不同的是em是相对于元素的父元素的font-size进行计算:rem是相对于根元素html的font-size进行计算.这样一 ...
- rem和em和px vh vw和% 移动端长度单位
1.rem和em.px 首先来说说em和px的关系 em是指字体高度 浏览器默认1em=16px,所以0.75em=12px;我们经常会在页面上看到根元素写的font-size:65%; 这样em就成 ...
随机推荐
- JavaScript学习笔记(散)——继承、构造函数super
构造函数中的super 今天看<JavaScript设计模式与开发实践>时,在书中看到一段代码出现super语句,第一次看到这个关键字,所以上网查了下它的作用,发现这个关键字是来自java ...
- Java基础(3) -字符串
字符串-String 1.定义&&初始化 使用双引号把字符括起来 String str = "test"; 2.字符串的提取-substring String a ...
- c++有关构造函数和析构函数中调用虚函数问题
今天看了一道迅雷的笔试题目,然后引起一段思考,题目如下: 下列关于虚函数的说法正确的是()A.在构造函数中调用类自己的虚函数,虚函数的动态绑定机制还会生效.B.在析构函数中调用类自己的虚函数,虚函数的 ...
- angular.js ng-repeat渲染时出现闪烁问题解决
当我们前端运用到angular.js框架时,想必大家都会遇到一些坑.其中,我也来分享一个常见的angular.js渲染时出现的坑. 当我们进行页面渲染时,绑定表达式最开始会用{{data.name}} ...
- office 2013幻灯片中插入SmartArt图形时出现错误下列一个或多个文件由于包含错误而无法运行
office 2013幻灯片中插入SmartArt图形时出现错误下列一个或多个文件由于包含错误而无法运行 系统:win8 64位 PowerPoint2013 64位 在幻灯片中插入SmartArt图 ...
- JanaScript数据类型
数据类型 一.基础类型值包括:undefined.null.boolean.string.number 基础类型分别在内存中占有大小空间,它们的值保存在栈空间,我们通过按值来访问. undefined ...
- [jbdj]SpringMVC框架(1)快速入门
1)springmvc快速入门(传统版) 步一:创建springmvc_demo一个web应用 步二:导入springioc,springweb , springmvc相关的jar包 步三:在/WEB ...
- Udp实现消息的发送和接收、以及图片的上传
//Udp实现消息的发送和接收 import java.io.IOException; import java.net.DatagramPacket; import java.net.Datagram ...
- 基于requirejs和angular搭建spa应用
接上篇,angular 实战部分,angular比较适合spa项目,这里不借助任何seed和构建工具,直接从零搭建,基本的angular项目结构大致包含如下几个部分: 1)app.js 入口 2)in ...
- C# 实现语音听写
本文系原创,禁止转载. 分享如何使用c#对接科大讯飞语音听写服务,简单高效地实现语音听写. 实现语音听写主要分为录音和语音识别两部分:录音是指获取设备声卡端口的音频数据并将之保存为音频文件,语音识别就 ...