在详细介绍rem之前,我们先简单阐述下px、em、rem之间的关系!
px为单位
em为单位
px为单位
像素是相对于显示器屏幕分辨率而言的相对长度单位。pc端使用px倒也无所谓,可是在移动端,
因为手机分辨率种类颇多,不可能一个个去适配,这时px就显得非常无力,所以就要考虑em和rem。
em为单位
使用“em”作单位时,一定需要知道其父元素的设置,因为“em”就是一个相对值,而且是一个相对于父元素的值。
继承父级的,假设html的font-size默认为16px,body字体大小定义为50%,那么在body里字体大小就是1em=8px了。
可当你又定义了一个div,然后把字体设置成了50%,请问,现在div下的1em等于多少?因为继承了父级的值,
现在这个div里的1em=4px,这么嵌套下去的话,抱歉,我数学不好!所有rem就出现了。
rem为单位
「rem」是指根元素(root element,html)的字体大小,rem只会相对html的值,不会受到父级的影响,
这样的好处在于:从em里的例子来讲,1rem始终会等于8px。
使用的时候不需要重新计算rem此时的大小。rem因为是css3增加的,所以ie8或以下请无视。
[浏览器兼容性] :IE9+,Firefox、Chrome、Safari、Opera 的主流版本都支持了。
从遥远的 IE6 到版本帝 Chrome 他们都约好了,根元素默认的 font-size 都是 16px。
比如默认的 html font-size=16px,那么我想设置12px 的文字就是:12÷16=0.75(rem)
为什么要用rem?
Px是相对固定单位,字号大小直接被定死,所以用户无法根据自己设置的浏览器字号而缩放,
em和rem虽然都是相对单位,但em是相对于它的父元素的font-size,页面层级越深,em的换算就越复杂,
而rem是直接相对于根元素,这就避开了很多层级关系。移动端新型浏览器对rem的兼容很好,可以放心使用。
那rem怎么换算呢?
通用方案
rem是依赖根元素来计算的方式,就是先给予html元素一个font-size,然后我们所有的rem就根据这个font-size来计算
例如:html{ font-size:16px;}
那么我们这里的1rem就应该这么来计算:1x16=16px=1rem;浏览器默认为16px可能造成rem计算上的麻烦和多位小数,所以,我们也可以进行这种方式的初始化根元素:
html{ font-size=62.5% //这里就是10/16x100%=62.5% 也就是默认10px的字号}
这样初始化之后,我们来进行rem计算的时候,就会减少许多的麻烦。
设置viewport配合进行缩放
通常在写移动端页面的时候,我们都会设置viewport,保证页面缩放没有问题,最常见的viewport的meta标签如下:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
至于为什么要加入viewport,我觉得就是因为现在市面上虽然有那么多不同种类不同品牌不同分辨率的手机,
但它们的理想viewport宽度归纳起来无非也就 320、360、414、等几种,都是非常接近的,理想宽度的相近也就意味着我们针对某个设备的理想viewport而做出的网站,
在其他设备上的表现也不会相差非常多甚至是表现一样的。
怎么样在不同分辨率的情况下计算根元素需要的font-size的值
关于这个点,其实有两种解决方案,一种是基于CSS的情况,另外一种就要通过js计算获得。
a.基于CSS
一般我们做页面,肯定都会有设计图,移动端页面,一般情况下,UI出图都会定宽为640px,这也是移动端的标准尺寸;但是,我们也不能排除可能有其他特殊的情况
可能需要做其他大小的设计图。所以,我们可以先定一个基准,然后来看看isux团队的整理出来的一个表格:
通过表格,我们能很清楚的看出各种分辨率下该如何计算,例如:320下的html的font-size就应该为320/640=0.5 所以,当以640为基准的font-size是20px时,
我们就应该给320的定义为10px;
怎么做到基于不同的分辨率来定义呢?不用说,首先想到的肯定就是媒体查询。当我们基于媒体查询来做屏幕自适应时,首先要考虑下需要做那些屏幕,
毕竟时下各种类型的手机让人眼花缭乱,分辨率也是多种多样,这里我做一下简单的例举,是我在过往项目中涉及到常见的屏幕分辨率的媒体查询:
上述为现阶段常见的iPhone系列的媒体查询,对于安卓方面,我发现好像只要做好了6p+和6的,基本在安卓主流机型上的表现都会很好。
但是考虑到有些其他的项目可能会出现向下兼容较低版本的情况,我这边提供几个媒体查询的例子,但是具体的数值,我觉得可能需要大家自行计算一下。
b.基于JS进行屏幕分辨率计算
我们来看这么一段js
(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);
其实这段代码,主要起到的作用是监听,代码的核心就是这么一句:
docEl.style.fontSize = 20 * (clientWidth / 320) + 'px';
这句话决定了几个关键:1.基于根元素计算rem所需要的font-size;2.规定了设计图的基准尺寸以及基准的font-size。所以,在需要用到这段JS的时候,
我们只需要根据UI设计图,规定好基准的font-size和统一的UI设计图尺寸就好了。
举个例子:
【js部分】
<script type="text/javascript"> !(function(doc, win) { var docEle = doc.documentElement, //获取html元素 event = "onorientationchange" in window ? "orientationchange" : "resize", //判断是屏幕旋转还是resize; fn = function() { var width = docEle.clientWidth; width && (docEle.style.fontSize = 10 * (width / 375) + "px"); //设置html的fontSize,随着event的改变而改变。 }; win.addEventListener(event, fn, false); doc.addEventListener("DOMContentLoaded", fn, false); }(document, window)); </script>
【css部分】
<style type="text/css"> html { font-size: 10px; } *{ margin: 0; } </style>
设计稿中标注此div的width:750px;height:200px;
换算为rem,即为width:37.5rem,height:10rem;
此时 1rem = 20px;将设计稿标注的宽高除以20即可得到rem的值。
【html部分】
<div style="width:37.5rem;height:10rem;background:#f00;color:#fff;text-align:center;"> test </div>
基础知识请参考以下网站:
http://isux.tencent.com/web-app-rem.html
原创文章请注明转载自杭州WEB前端外包网站本文地址:http://hz.35ui.cn/post/69.html,标题:前端rem单位详解