投身烈火
Keep Walking

使用rem实现响应式布局的方法

起因

前两天小徒弟问我,老看到有人说用rem实现响应式布局,具体要怎么做呢?这可问住我了,之前我只知道rem的概念却不知道要怎么用rem来实现响应式布局……赶紧忽悠她一顿,让她先去各大网站上学习下别人是怎么做的,看不懂了再来问我。自己则私底下恶补了rem实现响应式布局的知识来应付她的问题,这才算糊弄过去……

话说,临阵磨不能白磨了不是,总结下当时搜索到的资料供大家参考,以后真被问起来嘡嘡嘡一说,就准备接受萌新崇拜的目光吧,哈哈( ̄▽ ̄)

概念

在说rem之前不得不先介绍下em,em这种单位最早源自印刷界,一个em表示一种特殊字体的大写字母M的高度。后来到了网页上,em作为一种相对长度单位,相对于当前对象内文本的字体大小。没有被css设置过的网页,一般页面字体的默认大小是16px,所以1em就等于16px。当然em除了可以作为font-size属性值得单位,还能作为width和height属性值的单位。于是前端工程师们就脑洞大开了,如果所有的宽高单位都用em,那么在做响应式布局的时候,只要改变页面上的字体大小不就能直接调整页面各个部分的大小了吗?

但是事与愿违,em是针对当前对象内文本的,就是说针对的是被设置过字体大小的元素的字体大小。有点绕是不是?举个例子好了,比如现在又这样一个结构,body>div.A>div.B,body的font-size是20px,div.B的width和height都是1em,所以当前页面上div.B的宽高就是20px,这时候如果div.A被设置了font-size为10px,div.B的宽高就是10px了,这个特性让em非常不好被应用,要用em就整个页面所有的font-size都要用em,这在没有node做自动化工具的年代简直是异常噩梦……你想写个页面,还得不停的换算px和em,想想就头疼……

后来rem出现了,其实rem就是root em,故名思意,rem单位就是相对于根节点(html元素)字体大小的单位。这个单位跟em不一样的区别也在这里,他是不受继承影响的,这样就可以各种单位混用,回避了不停换算的问题。当然要想使用换算的过程还是不能少,不过只是根据根节点的字体大小换算,列个换算表需要的时候查表就好了,当然这个问题在有了前端打包工具之后就彻底解决了,咱们后面再具体说。

方案

理解了rem的概念,揭下来说说利用rem实现响应式布局的方案。一般响应式布局分两种:

方案一

使用rem定义想要响应式的部分的宽高,使用媒体查询来修改html元素的font-size属性

简单举个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
html {
font-size:16px;
}
@media screen and (max-width: 480px) {
html {
font-size:14px;
}
}
@media screen and (max-width: 960px) {
html {
font-size:15px;
}
}
.some-class {
width: 10rem;
height: 10rem;
}

方案二

使用rem定义想要响应式的部分的宽高,在页面resize时动态的改变html的font-size属性。

这个方案也是我觉得比较有趣的一个方案,他可以保证窗口大小在变化时,真个页面也等比例缩放。目前淘宝和饿了么使用的就是这个方案。

本来还想抄一段淘宝计算html元素font-size大小的代码,后来一搜发下阿里无线团队已经把脚本开源了,附上地址好了:lib-flexible

问题

除了以上两种方案,其他把root的font-size设死,又使用rem做单位的方案我就真不能理解了……貌似没什么意义吧?希望能白话的同学给我套靠谱的解释,这样以后别人喷我的时候我也好一嘟噜一串儿的喷回去……( ̄▽ ̄)”

自动化

刚才提到了,在使用rem的时候不得不对rem和px做转换。我个人是信奉“一切重复工作都应该交给电脑去做”这一理念的,所以我觉得转换的工作也应该交给电脑去做才对。其实前人早的轮子也已经很多了,这件事less、sass、postcss、stylus等预处理器都支持,也可以用px2rem这个npm模块,使用webpack的也有对应的loader可用px2rem-loader 。所以根本不用操心重复劳动的事,某种意义上来说,只要你够勤快,就根本累不着~

总结

在查资料的过程中,也发现有人在说,字体大小自适应是一种错误的想法,因为就算是响应式布局,其实也没必要做到这一步……使用媒体查询、calc、vw单位、flex一样能够完成一个体验优秀的页面。在这件事上,我觉得还是仁者见仁吧,虽然rem实现响应式布局的感觉都有些hack,但是肯定还是有他存在的意义的,屠龙之技学会了,砍谁不是砍不是?何况有的时候,咱们程序员说了真不算,到底要不要做到完全等比例缩放这一步,还是得听产品经理的……毕竟产品小白分分钟就能让技术大牛加班啊~哈哈哈b( ̄▽ ̄)d