概述

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

目前的国内的前端开发圈子中,最常使用到的关于“尺寸”的单位,应该是 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. Spring MVC 项目搭建 -5- spring security 使用数据库进行验证

    Spring MVC 项目搭建 -5- spring security 使用数据库进行验证 1.创建数据表格(这里使用的是mysql) CREATE TABLE security_role ( id ...

  2. Java基础(6)- 面向对象解析

    java面向对象 对象 知识点 java 的方法参数是按值调用,是参数的一份拷贝 封装 使用private将 属性值/方法 隐藏,外部只能调用 get,set方法/非private 的接口 获取 重载 ...

  3. Egret的项目结构

    这是我新建的一个Egret EUI项目 .wing文件夹是项目的配置文件 bin-debug 文件夹,项目编译和运行的debug目录 libs 文件夹,存放库文件,包括 Egret 核心库,其他扩展库 ...

  4. Java异常体系简析

    最近在阅读<Java编程思想>的时候看到了书中对异常的描述,结合自己阅读源码经历,谈谈自己对异常的理解.首先记住下面两句话: 除非你能解决这个异常,否则不要捕获它,如果打算记录错误消息,那 ...

  5. God 1.1.1 多线程之内存可见性

    共享变量在线程间的可见性 synchronize实现可见性 volatile实现可见性 指令重排序 as-if-serial语义 volatile使用注意事项 synchronized和volatil ...

  6. Jenkins设置svn授权

    1.问题引入 在job的scm部分,subversion modules/credentials出现错误 "Unable to access https://xxx/code : svn: ...

  7. Struts2框架05 result标签的类型

    1 result标签是干什么的 就是结果,服务器处理完返回给浏览器的结果:是一个输出结果数据的组件 2 什么时候需要指定result标签的类型 把要输出的结果数据按照我们指定的数据类型进行处理 3 常 ...

  8. sqlserver 处理百万级以上的数据处理与优化

    一处理百万级以上的数据提高查询速度的方法: 1.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描. 2.对查询进行优化,应尽量避免全表扫描,首先应 ...

  9. iOS App签名的原理

    前言 相信很多同学对于iOS的真机调试,App的打包发布等过程中的各种证书.Provisioning Profile. CertificateSigningRequest.p12的概念是模糊的,导致在 ...

  10. 使用Dubbo、JSF等RPC框架时,对于异常的处理

    无论是Dubbo还是JSF等RPC框架,一般都会把接口分为2部分: 1,服务端(provider) 2,客户端(consumer) 由于,客户端与服务端可能不在同一个应用中,所以客户端一般在调用服务端 ...