rem与px换算的计算方式


前言

这段时间的小项目中算是真正意义上使用了rem来进行移动端的页面布局,项目结束了我反思了一下之前的对于rem的使用...原来我以前对rem用法完全是在搞笑啊!!结合这次这个小项目,我觉得我也有必要对rem布局以及用法进行一次总结。

ps.文笔可能不太好...

1.什么是rem

来自于鹅厂ISUX团队的解释如下: rem(font size of the root element)是指相对于根元素的字体大小的单位。简单的说它就是一个相对单位。看到rem大家一定会想起em单位,em(font size of the element)是指相对于父元素的字体大小的单位。它们之间其实很相似,只不过一个计算的规则是依赖根元素一个是依赖父元素计算。

所以这里总结一句,所谓依赖根元素来计算的方式,就是先给予html元素一个font-size,然后我们所有的rem就根据这个font-size来计算

例如:

1
html{ font-size:16px;}

 那么我们这里的1rem就应该这么来计算:1x16=16px=1rem;浏览器默认为16px可能造成rem计算上的麻烦和多位小数,所以,我们也可以进行这种方式的初始化根元素:

1
2
3
html{
   font-size=62.5% //这里就是10/16x100%=62.5% 也就是默认10px的字号
}

 这样初始化之后,我们来进行rem计算的时候,就会减少许多的麻烦。

 2.设置viewport配合进行缩放

通常在写移动端页面的时候,我们都会设置viewport,保证页面缩放没有问题,最常见的viewport的meta标签如下:

1
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />

 这个标签的参数就不再做详细解释,如果有需要了解详细的参数分析与解释,可以参考我的这篇博文:http://www.cnblogs.com/azhai-biubiubiu/p/5305022.html

 至于为什么要加入viewport,我觉得就是因为现在市面上虽然有那么多不同种类不同品牌不同分辨率的手机,但它们的理想viewport宽度归纳起来无非也就 320、360、414、等几种,都是非常接近的,理想宽度的相近也就意味着我们针对某个设备的理想viewport而做出的网站,在其他设备上的表现也不会相差非常多甚至是表现一样的。

3.怎么样在不同分辨率的情况下计算根元素需要的font-size的值

 关于这个点,其实有两种解决方案,一种是基于CSS的情况,另外一种就要通过js计算获得

a.基于CSS

一般我们做页面,肯定都会有设计图,移动端页面,一般情况下,UI出图都会定宽为640px,这也是移动端的标准尺寸;但是,我们也不能排除可能有其他特殊的情况可能需要做其他大小的设计图。所以,我们可以先定一个基准,然后来看看isux团队的整理出来的一个表格:

                          

通过表格,我们能很清楚的看出各种分辨率下该如何计算,例如:320下的html的font-size就应该为320/640=0.5 所以,当以640为基准的font-size是20px时,我们就应该给320的定义为10px;

怎么做到基于不同的分辨率来定义呢?不用说,首先想到的肯定就是媒体查询。当我们基于媒体查询来做屏幕自适应时,首先要考虑下需要做那些屏幕,毕竟时下各种类型的手机让人眼花缭乱,分辨率也是多种多样,这里我做一下简单的例举,是我在过往项目中涉及到常见的屏幕分辨率的媒体查询:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@media only screen and (min-device-width320px)and (-webkit-min-device-pixel-ratio: 2) {
   //针对iPhone 45c,5s, 所有iPhone6的放大模式,个别iPhone6的标准模式<br>  html{<br>    font-size:10px;<br>  }
}
@media only screen and (min-device-width375px)and (-webkit-min-device-pixel-ratio: 2) {
  //针对大多数iPhone6的标准模式<br>  html{<br>    font-size:12px;<br>  }
}
   
@media only screen and (min-device-width375px)and (-webkit-min-device-pixel-ratio: 3) {
  //针对所有iPhone6+的放大模式<br>  html{<br>    font-size:16px;<br>  }
   
}
@media only screen and (min-device-width:412px) and (-webkit-min-device-pixel-ratio: 3) {
  //针对所有iPhone6+的标准模式,414px写为412px是由于三星Nexus 6412px,可一并处理<br>  html{<br>    font-size:20px;<br>  }
}

 上述为现阶段常见的iPhone系列的媒体查询,对于安卓方面,我发现好像只要做好了6p+和6的,基本在安卓主流机型上的表现都会很好。但是考虑到有些其他的项目可能会出现向下兼容较低版本的情况,我这边提供几个媒体查询的例子,但是具体的数值,我觉得可能需要大家自行计算一下。

1
2
3
4
5
6
7
8
9
10
11
@media only screen and (-webkit-device-pixel-ratio:.75){ /*低分辨率小尺寸的图片样式*/
 
}
 
@media only screen and (-webkit-device-pixel-ratio:1){ /*普通分辨率普通尺寸的图片样式*/
 
}
 
@media only screen and (-webkit-device-pixel-ratio:1.5){ /*高分辨率大尺寸的图片样式*/
 
}

 b.基于JS进行屏幕分辨率计算

我们来看这么一段js:

1
2
3
4
5
6
7
8
9
10
11
12
13
(function (doc, win) {
    var docEl = doc.documentElement,
        resizeEvt = 'orientationchange' in window ? 'orientationchange' 'resize',
        recalc = function () {
            var clientWidth = docEl.clientWidth;<br>       window.innerWidth>max ?  window.innerWidth : max;
            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);

 其实有点尴尬的问题在于...这段代码的详细作用我也未能完全理解,但是通过其中的某些关键词,我先做下大致的分析:

 orientationchange:这是一个事件,菜鸟教程中做了这么一个解释:事件是在用户水平或者垂直翻转设备(即方向发生变化)时触发的事件。

 以下理解,可能并不是很准确!!只是让我自己明白了是个啥东西!各位千万别被带坑里去了!也希望大神在底下指正分析下这段代码!

 其实这段代码,主要起到的作用是监听,代码的核心就是这么一句:

1
docEl.style.fontSize = 20 * (clientWidth / 320) + 'px';

 这句话决定了几个关键:1.基于根元素计算rem所需要的font-size;2.规定了设计图的基准尺寸以及基准的font-size。所以,在需要用到这段JS的时候,我们只需要根据UI设计图,规定好基准的font-size和统一的UI设计图尺寸就好了。

基于这段JS,我们的项目处理中也利用了这种方式,但是不同的是并没有使用JS,而是根据这种预定义基准量的方式,在less中进行计算后得到可以自适应的尺寸

1
2
3
4
5
//html font-size20-40
//对应屏幕宽度320-640
//当前设计稿是750,我们用设计稿100%的宽度来测量比较方便,
//所以需要base换算
@base: (640/750)/40rem;//rem是最后算出结果的单位

 然后看看下面这个例子:

1
2
3
4
5
6
7
8
.tag {
  display: inline-block;
  font-size22*@base;
  text-aligncenter;
  border-radius: 20px;
  margin-bottom20*@base;
  padding:10*@base 20*@base;
}

 例子中的@base就是预编译好的,可以进行计算的基准变量,然后例子中的尺寸变化,我是根据UI的PSD中百分百尺寸下的测量得到的数值乘以基准值。这样做可能有些麻烦,但是好处在于对于UI的还原度会特别高,基本可以做到像素级的UI还原,那我们来看看效果:

                                          

可以看出,在chrome的移动端模拟器下,大、中、小三种分辨率下,布局并没有产生变化,发生变化的仅仅只有内容而已。在移动端代码中,我们一般只会定义元素的width,使其height自适应,但是使用这种变量的形式,height也可以进行定义,使我们的CSS更为严谨些。

 

4.流式布局与rem布局的区别

 在流式布局下:

 网页的主要架构部分按照百分比布局,宽度百分比,高度定死;

 如果是图片宽度设置百分比,高度根据图片的比例自适应,如果是封面图片可以高度定死,用background-size:cover显示部分就行;

 在rem布局下,之前已经说了很多,这里就说下和流式布局的区别:

 rem布局需要基于根元素的基准量来做的,不同屏幕分辨率设置不同的基准量,那么对UI的还原度就会很高,但是...发现了一个rem的问题...就是如果页面设计比较看重元素间隔和高度的话...那么用rem布局就会比较难受

 

5.总结下

 其实在实际项目中,感觉使用rem还是比较方便的,而且学习成本也不高。如果有同学遇到移动端项目而不需要考虑PC端的话,rem绝对能让人写CSS比较舒服。


评论 (0)

发表评论

上一篇: 初涉Less 下一篇: rem与px的转换