概述

古语有云,没有规矩则不成方圆。秦灭六国之后为了促进国内生产力的发展,也是大力推进全国度量衡的统一。车同轨,书同文。与“尺寸”相关的问题(手动滑稽),从古至今一直为人们所关注。所以在我的处女文章中,也决定大体讲讲在前端领域里面的“尺寸”问题。

目前的国内的前端开发圈子中,最常使用到的关于“尺寸”的单位,应该是 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端的开发来说具有较大的优势:

  1. PC端的项目设计图的宽度和高度比例基本固定,而且屏幕相对较宽,使用px单位对于普通项目不会造成太多不友好的显示效果。
  2. 对于设计师与前端开发者对接而言,使用px单位能够降低单位转换的成本,提高开发速度。
  3. 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 的区别与联系的更多相关文章

  1. CSS中rem、em的区别

    引用文档:http://www.divcss5.com/html/h529.shtml:http://blog.csdn.net/qq_35432904/article/details/5180422 ...

  2. rem和em的区别

    原文链接:http://caibaojian.com/rem-vs-em.html rem 单位如何转换为像素值 当使用 rem 单位,他们转化为像素大小取决于页根元素的字体大小,即 html 元素的 ...

  3. rem与em的区别

    这两个单位都是相对元素 rem相对根元素 em相对于父级元素

  4. rem、em、px的区别

    px 像素(Pixel).相对长度单位.像素px是相对于显示器屏幕分辨率而言的. 特点: 1. IE无法调整那些使用px作为单位的字体大小: 2. 国外的大部分网站能够调整的原因在于其使用了em或re ...

  5. Rem与em的简单理解

    Rem与em的简单理解 Em单位与像素px的转换 所得的像素值 = 当前元素的font-size * em的值 比如:div的font-size:12px 10em等同于120px 12*10 =12 ...

  6. CSS中px,em,rem,pt的区别及四者换算?

    本文章重要说明px,em,rem,pt的区别以及四者之间的换算. em单位有如下特点 1. em的值并不是固定的; 2. em会继承父级元素的字体大小. 我们在写CSS的时候如果要用em为单位,需要注 ...

  7. 浅谈rem、em、px

    1.px:像素(Pixel) px是相对长度单位,他是相对于显示器屏幕分辨率而言的 优点:比较稳定.精确 缺点:在浏览器 中放大或者缩小浏览页面,会出现页面混乱的情况. 如下例子: .buttonPX ...

  8. rem和em,px的使用

    rem是CSS3中新增加的一个单位值,他和em单位一样,都是一个相对单位.不同的是em是相对于元素的父元素的font-size进行计算:rem是相对于根元素html的font-size进行计算.这样一 ...

  9. rem和em和px vh vw和% 移动端长度单位

    1.rem和em.px 首先来说说em和px的关系 em是指字体高度 浏览器默认1em=16px,所以0.75em=12px;我们经常会在页面上看到根元素写的font-size:65%; 这样em就成 ...

随机推荐

  1. iOS9新特性之常见关键字、泛型

    #pragma mark -- nullable nullable:可以为空,只能修饰对象,不能修饰基本数据类型 // 方式一: @property (nonatomic, copy, nullabl ...

  2. 第一个SpringMVC实例和解析(HelloSpringMVC)

    1. 开发步骤: (1)增加Spring支持 下载Spring安装包和其依赖的commons-logging.jar,复制到项目Web应用的lib文件夹(WebRoot/WEB-INF/lib): S ...

  3. Ionic 2+ 安卓环境搭建

    安装 安卓studio https://developer.android.com/studio/index.html 设置一个环境变量 _JAVA_OPTIONS:-Xmx512M 添加androi ...

  4. webpackage 2.x 使用

    webpackage 2.x 使用 安装---(在项目目录下) //1.初始化npm的配置(添加package.json) npm init //2.安装 webpackage npm install ...

  5. angular4.0 父子组建之间的相互通信

    父组建---->子组建 传递信息 首先先通过angular脚手架生成两个基本组件,有一个好处是 会自动关联到跟模版,节约时间,而且还是偷懒 ng generate component compo ...

  6. Python查看MQ队列深度

    分享一段代码,很简单但是也很实用. #!/usr/bin/python #-*- coding:gb18030 -*- ''' Usage: mq.py [Qmgr] *get the queues' ...

  7. Asp.Net MVC-01-起步

    创建第一个MVC程序 我们先创建一个ASP.NET Web程序 模板选择MVC,因为不想使用默认的身份认证我们点击更改身份认证并选择不进行身份认证. 创建的项目结构如下: 配置与初始化 Web配置文件 ...

  8. Java用Cookie简单限制点赞次数

    楼主最近在搞一个当下比较流行的点赞功能,这个功能也是让程序员又爱又恨啊 说起爱,点赞是个社会化的动作,全民都在为美好的事情,行为,动作,点赞. 说起恨,你很难在用户没有登录的情况下限制恶意点赞的机器人 ...

  9. neo4j 数据库导入导出

    工作中需要将 A 图数据库的数据完全导出,并插入到 B 图数据库中.查找资料,好多都是通过导入,导出 CSV 文件来实现.然而,经过仔细研究发现,导出的节点/关系 都带有 id 属性 ,因为 A B ...

  10. volume 生命周期管理 - 每天5分钟玩转 Docker 容器技术(44)

    Data Volume 中存放的是重要的应用数据,如何管理 volume 对应用至关重要.前面我们主要关注的是 volume 的创建.共享和使用,本节将讨论如何备份.恢复.迁移和销毁 volume. ...