px、em、rem

px、em、rem简介

px像素(Pixel),相对长度单位,相对于显示屏幕分辨率

em,相对长度单位,相对于父元素设置的font-size,页面层级越深,em的换算就越复杂。

rem,相对长度单位,相对于HTML根元素设置的font-size,避免了多级嵌套。是CSS3新增的一个相对单位(root em 根em)

em和rem若没有设置上级字体尺寸,则相对于浏览器的默认字体尺寸16px(所有未经调整的浏览器默认字体都是16px)。

rem基础应用

在使用rem的页面,会给根元素设置一个样式:

html{
  font-size: 62.5%;
}

为什么是62.5%呢?

所有未经调整的浏览器默认字体都是16px,1rem等于HTML根节点(或浏览器默认)的字体大小,因此1rem = 16px。

这样不方便px和rem的单位换算,(若设计稿中25px换算成rem,就需要这样计算 25px * 1rem / 16px = 1.5625rem)

假设 1rem = 10px ,那么 100px = 10rem ,20px = 0.25rem 这样换算就简单很多,于是就有了10 / 16 = 62.5%

font-size: 62.5% 就可以理解为,浏览器默认字体为16px,16px * 62.5% = 10px,1rem等于HTML根节点(或浏览器默认)的字体大小,那么1rem = 10px

若设计稿宽度为720px(以iPhone6尺寸设计的设计稿)(设计师给的设计稿是物理分辨率,会是我们写样式的逻辑分辨率的两倍,如果给的设计稿是640,那么是基于iPhone5,320),需要除以2转化为和iPhone6屏幕等宽的375px,那么设计稿中的px宽度转化为CSS代码中的rem就应该这么计算:设计稿中px / 2  / 10 = css中rem。之后再用媒体查询,设置不同屏幕大小上HTML根节点font-size的百分比(详见下文示例)。

62.5%有什么问题?

问题一:上文说“所有未经调整的浏览器默认字体都是16px”,其实并不准确。rem是CSS3的新属性,部分早前浏览器和国内浏览器的默认字体并不是16px,那么10 / 16 的换算规则就不成立了。

问题二:chrome浏览器强制最小字体为12px,若低于12px按照12px处理,那么上文定义的1rem = 10px 就变成了 1rem = 12px,会出现偏差。

建议:为特殊的浏览器设置特殊的HTML根元素字体大小,不建议在pc端使用rem。对于chrome最小字体的限制,建议将换算比例调整为 1rem = 100px(或其它自定的值,但换算规则1rem不能小于12px)。

直接上示例:(前提条件,设计稿是以iPhone5尺寸设计,设计稿宽度为320px * 2 = 640px,规定1rem = 100px

html{ font-size: 625% }

即以320px宽度的屏幕为标准, 在320px宽度的屏幕下,根字体设置为 625% (即 1rem = 100px),

那么,应用媒体查询修改不同屏幕大小下根元素字体大小:

@media screen and (min-width:360px) and (max-width:374px) and (orientation:portrait) {
  html { font-size: 703%; } /*  625% * 360px / 320px = 703.12%  */
}
@media screen and (min-width:375px) and (max-width:383px) and (orientation:portrait) {
  html { font-size: 732.4%; } /*  625% * 375px / 320px = 732.42%  */
}

rem高级应用

625%的方案存在一定的兼容性问题,无法根据不同的设计稿精确适配。网易和淘宝有其自己的适配方案,适配性也很完美,我们可以借鉴。

网易动态font-size

屏幕宽度/设计稿rem宽度=页面动态font-size值

获取页面动态font-size值,再赋值给html元素设置style:

document.documentElement.style.fontSize = document.documentElement.clientWidth / (设计稿px宽度  /  基准值100 = 设计稿rem宽度) + 'px'

淘宝Flexible

github地址:https://github.com/amfe/lib-flexible

Flexible会根据不同屏幕宽度自动设定根font-size、动态viewport、针对Retina屏做的dpr。

直接引用阿里的CDN文件(或下载到本地引入)

<script src="http://g.tbcdn.cn/mtb/lib-flexible/0.3.4/??flexible_css.js,flexible.js"></script>

 假设设计稿为750px,Flexible会把设计稿分为10份(Flexible会把设计稿宽度设为10rem),即1rem = 75px,所以根元素的font-size(基准值)为75px

将css换算成rem时:100px = 100px / 75 = 1.33rem

换算工具

不管何种换算方案,px和rem的换算会因为基准值的不同而有些复杂,甚至需要借助计算器的辅助。在这里推荐一个换算神器:cssrem

总结

通用方案

设置根font-size:625%(或其它自定的值,但换算规则1rem不能小于12px);通过媒体查询分别设置每个屏幕的根font-size。

有一定适用性,换算也较为简单。

但,有兼容性的坑,对不同手机适配不是非常精准;需要设置多个媒体查询来适应不同手机,当某款手机尺寸不在设置范围之内,会导致无法适配。

网易方案

拿到设计稿除以100,得到宽度rem值;通过给html的style设置font-size,把得到的宽度rem值代入x  ;

document.documentElement.style.fontSize = document.documentElement.clientWidth / x + 'px'

设计稿px/100即可换算为rem。

通过动态根font-size来做适配,基本无兼容性问题,适配较为精准,换算简便。

但,无viewport缩放,且针对iPhone的Retina屏没有做适配,导致对一些手机的适配不是很到位。

淘宝方案

只需要引入Flexible,通过动态根font-size、viewpor、dpr来做适配,无兼容性问题,适配精准。

假设拿到的设计稿是750px,Flexible会把设计稿分为10份,可以理解为页面width=10rem,即1rem=75px,所以根font-size(基准值)=75px。

之后css换算rem公式就是 px / 75 = rem。在没有换算插件的时候计算起来会比较麻烦。

参考资料

前端页面适配的rem换算

淘宝弹性布局方案lib-flexible实践

教你如何用 lib-flexible 实现移动端H5页面适配

使用Flexible实现手淘H5页面的终端适配

基于淘宝适配方案flexible + 翻屏h5 适配方案adaptive(移动端全屏滑动h5活动解决方案)

与君共勉:再牛逼的梦想,也抵不住傻逼般的坚持! 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值