CSS零碎之em、rem

栏目: CSS · 发布时间: 5年前

内容简介:移动端的开发基本很少直接使用px作为单位了,目前最常用的是rem。不过在这之前其实还有个em单位,和rem长得非常的像,那么它们有什么区别呢?又有什么不一样的适用场景呢?注意:无论使用em,还是rem,客户端最终解析的值依旧是px!从title的解释就可以看出,em的基准是其父级元素,不过这个父级元素要求是设置有font-size值的,如下面的例子:

移动端的开发基本很少直接使用px作为单位了,目前最常用的是rem。不过在这之前其实还有个em单位,和rem长得非常的像,那么它们有什么区别呢?又有什么不一样的适用场景呢?

注意:无论使用em,还是rem,客户端最终解析的值依旧是px!

em:相对父级元素字体大小的倍数

从title的解释就可以看出,em的基准是其父级元素,不过这个父级元素要求是设置有font-size值的,如下面的例子:

<div class="father" style="font-size:20px;">
    <div class="son"  style="font-size:2em;"></div>
</div>

那么son的字体大小就是2 * 20px = 40px,此时,如果father的字体大小变化了,那么son的也会跟着变化。假如没有父元素,则基准就是body(由于默认浏览器默认字体为16px,所以默认情况1em=16px)。

rem:相对 html 根元素字体大小的倍数

跟上面解释body基准时的差不多,默认情况下1rem=16px。此时,只要根元素字体大小不变,那么相对于它的rem就不会变。

对于移动端的各种机型来讲,由于不同的机型屏幕尺寸、分辨率都不一样,不太可能使用相同的根元素字体大小作为基准,所以所谓rem布局,就是通过js动态计算出不同机型的根元素字体大小值,来对页面进行等比例的缩放,达到适配大部分机型的效果。

那么具体如何去设定这个基准呢?

假设把手机屏幕宽度均分成10等份(因为rem布局就是针对宽度去做设定的),规定其中的一份作为根元素的font-size值,那么根元素font-size值就可由下述公式获得:

document.documentElement.style.fontSize = document.documentElement.clientWidth / 10 + 'px';

在这个基准下,那么1rem的值也随之得到了:

1rem = document.documentElementstyle..fontSize = document.documentElement.clientWidth / 10 + 'px';

那么,不同屏幕的机型由于屏幕宽度不同,也就得到了在"屏幕宽度均分成10等份"这个标准下的rem相对值。比较完整的计算方式如下:

// set 1rem = viewWidth / 10
function setRemUnit () {
  var rem = docEl.clientWidth / 10
  docEl.style.fontSize = rem + 'px'
}

setRemUnit()

// reset rem unit on page resize
window.addEventListener('resize', setRemUnit)
window.addEventListener('pageshow', function (e) {
  if (e.persisted) {
    setRemUnit()
  }
})

注意:这里的标准 "10"可以是任一值,只要跟下面转换公式中用到的标准值保持一致即可,这里只是为了计算方便才这么设定。

这样,rem的基础生态就搭建好了。那么如何基于这套标准应用到开发中去呢?

在继续之前,先来了解下"像素"这个知识点,因为接下来都会用到它的概念。

像素分为两种:设备像素和CSS像素

1、设备像素(device independent pixels): 设备屏幕的物理像素,任何设备的物理像素的数量都是固定的

2、CSS像素(CSS pixels): 又称为逻辑像素,是为web开发者创造的,在CSS和javascript中使用的一个抽象的层

在pc端,css像素和物理像素是1:1的关系;而在移动端,由于类似retina的各种高清屏的出现,css像素和物理像素的关系一般是2:1或者3:1,即1个物理像素容纳2到3个css像素,实现高清的效果。

一般移动端页面的开发流程是:设计人员以某个机型作为标准,设计好UI。前端开发针对这个机型的UI做开发,然后其它机型相对的去等比例缩放。

这里以iphone6作为标准(因为实际开发中基本也是用它做设计),它的物理像素为750x1334,css像素为375*667,假设UI上图片a的宽度为140,那么如何把它转换成以rem为单位的值呢?

现在屏幕宽度是已知的10rem,要求UI上宽140的rem值,假设为X,由下图可以很容易的得到比例关系:

屏幕宽度/UI宽度 = x/140 = 10rem / 750
=》
x = 140 / 750 * 10 rem

CSS零碎之em、rem

一般可以在sass中通过封装预处理函数进行这个转换过程:

$UI_WIDTH: 750;

@function px2rem($px) {
  @return ${ $px / $UI_WIDTH * 10 }rem;
//=>or @return ${ $px / 75 }rem;
}

img{
  width: px2rem(140);
}

这就是"rem布局"原理的整个实现过程!

而随着社区各种 工具 的完善,现在也无需手动去使用如px2rem的这种预处理函数去转换,比较流行的做法是使用postcss的postcss-px2rem插件去自动处理,开发时仍然按照px的方式去编程,postcss配置例:

postcss: function() {
  return [px2rem({remUnit: 75})]; //设置基准值,75是以iphone6的标准
}

这里的remUnit设置是有一定规则的,比如屏幕宽度等分成10份,当UI以iphone6(即物理像素宽度750)设计时,remUnit=75;当UI以iphone5(即物理像素宽度640)设计时,remUnit=64。可以看出它中遵循如下公式:

remUnit = 物理像素宽度 / 设定的屏幕宽度等分值;

至于具体的js等分逻辑封装可以参看手淘的 flexible

em 还是 rem ?

那么在实际开发中,究竟适用em还是rem呢?记住如下原则即可:

  1. 如果属性值根据元素的font-size获得,则使用em,如padding、margin、line-height等
  2. 其他情况都使用rem

本文收录在个人的Github上 https://github.com/kekobin/bl... ,觉得有帮助的,欢迎start哈!


以上所述就是小编给大家介绍的《CSS零碎之em、rem》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

代码的未来

代码的未来

[日] 松本行弘 / 周自恒 / 人民邮电出版社 / 2013-6 / 79.00元

《代码的未来》是Ruby之父松本行弘的又一力作。作者对云计算、大数据时代下的各种编程语言以及相关技术进行了剖析,并对编程语言的未来发展趋势做出预测,内容涉及Go、VoltDB、node.js、CoffeeScript、Dart、MongoDB、摩尔定律、编程语言、多核、NoSQL等当今备受关注的话题。   《代码的未来》面向各层次程序设计人员和编程爱好者,也可供相关技术人员参考。一起来看看 《代码的未来》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

MD5 加密
MD5 加密

MD5 加密工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换