乐趣区

移动端适配手机端rem布局详解

1. 问题的引出
如果 html5 要适应各种分辨率的移动设备,应该使用 rem 这样的尺寸单位,同时给出了一段针对各个分辨率范围在 html 上设置 font-size 的代码:

html{font-size:10px}

@media screen and (min-width:321px) and (max-width:375px){html{font-size:11px}}

@media screen and (min-width:376px) and (max-width:414px){html{font-size:12px}}

@media screen and (min-width:415px) and (max-width:639px){html{font-size:15px}}

@media screen and (min-width:640px) and (max-width:719px){html{font-size:20px}}

@media screen and (min-width:720px) and (max-width:749px){html{font-size:22.5px}}

@media screen and (min-width:750px) and (max-width:799px){html{font-size:23.5px}}

@media screen and (min-width:800px){html{font-size:25px}}

在实际项目中,把与元素尺寸有关的 css,如 width,height,line-height,margin,padding 等都以 rem 作为单位,这样页面在不同设备下就能保持一致的网页布局。举例来说,网页有一个.item 类,设置了 width 为 3.4rem,该类在不同分辨率下对应的实际宽度如下:

321px <= device-width <= 375px,font-size:11px        --->  .item 的 width:34px

376px <= device-width <= 414px,font-size:12px        --->  .item 的 width:37.4px

415px <= device-width <= 639px,font-size:15px        --->  .item 的 width:40.8px

640px <= device-width <= 719px,font-size:20px        --->  .item 的 width:51px

720px <= device-width <= 749px,font-size:22.5px      --->  .item 的 width:76.5px

750px <= device-width <= 799px,font-size:23.5px      --->  .item 的 width:79.8999999px

800px <= device-width,font-size:25px        --->  .item 的 width:85px

以上代码乍看没啥问题,响应式设计不就应该是这么干的吗?但是从工作量和复杂度方面来考虑,它有以下几个不足:

(1).item 类在所有设备下的 width 都是 3.4rem,但在不同分辨率下的实际像素是不一样的,所以在有些分辨率下,width 的界面效果不一定合适,有可能太宽,有可能太窄,这时候就要对 width 进行调整,那么就需要针对.item 写媒介查询的代码,为该分辨率重新设计一个 rem 值。然而,这里有 7 种媒介查询的情况,css 又有很多跟尺寸相关的属性,哪个属性在哪个分辨率范围不合适都是不定的,最后会导致要写很多的媒介查询才能适配所有设备,而且在写的时候 rem 都得根据某个分辨率 html 的 font-size 去算,这个计算可不见得每次都那么容易,比如 40px
/ 23.5px,这个 rem 值口算不出来吧!由此可见这其中的麻烦有多少。

(2)以上代码中给出的 7 个范围下的 font-size 不一定是合适的,这 7 个范围也不一定合适,实际有可能不需要这么多,所以找出这些个范围,以及每个范围最合适的 font-size 也很麻烦

(3)设计稿都是以分辨率来标明尺寸的,前端在根据设计稿里各个元素的像素尺寸转换为 rem 时,该以哪个 font-size 为准呢?这需要去写才能知道。

正是因为以上提到的一些不足,我觉得这种适配方式不是特别好,写起来太麻烦。为了完成工作,我们需要找寻更简单更有效率的方法。那么 html5 该如何去做众多移动设备的适配呢?我目前已知的有 3 种解决方法,将会在下文的第 2,3,4 部分阐述,如果你阅读之后,有什么想法,尽可在评论中与我交流。

  1. 简单问题简单解决

我觉得有些 web app 并一定很复杂,比如拉勾网,你看看它的页面在 iphone4,iphone6,ipad 下的样子就知道了:
图片描述
图片描述
图片描述
它的页面有一个特点,就是:

顶部与底部的 bar 不管分辨率怎么变,它的高度和位置都不变

中间每条招聘信息不管分辨率怎么变,招聘公司的图标等信息都位于条目的左边,薪资都位于右边

这种 app 是一种典型的弹性布局:关键元素高宽和位置都不变,只有容器元素在做伸缩变换。对于这类 app,记住一个开发原则就好:文字流式,控件弹性,图片等比缩放。以图描述:

图片描述

这个规则是一套基本的适配规则,对于这种简单 app 来说已经足够,同时它也是后面要说的 rem 布局的基础。另外对于拉勾这种 app 可能需要额外媒介查询对布局进行调整的就是小屏幕设备。举例来说,因为现在很多设计稿是根据 iphone6 的尺寸来的,而 iphon6 设备宽的逻辑的像素是 375px,而 iphone4 的逻辑像素是 320 个像素,所以如果你根据设计稿做出来的东西,在 iphone4 里面可能显示不下,比如说拉钩网底部那个下载框,你对比看下就知道了,这是 4:
图片描述
这是 6:
图片描述
6 下面两边的间距比 4 多很多,说明拉勾对 4 肯定是做过适配的,从代码也可以证实这一点:
图片描述
不过如果你拿到的是根据 4 的设计稿,那就没有问题,比 4 分辨率大的设备肯定能显示根据 4 的尺寸做出来的东西。

还有一点,这种情况 css 尺寸单位用 px 就好,不要用 rem,避免增加复杂度。

  1. 淘宝的做法

动态计算 html 的 font-size

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

关于这种做法的具体实现,淘宝已经给我们提供了一个开源的解决方案,具体请查看:

https://github.com/amfe/lib-f…

  1. 总结

总算是罗里吧嗦地把文章写完了,希望你还觉得满意,这篇文章对我来说价值也很大,今后做 html5 的项目就有思路了。最后,欢迎大家在评论里与我交流你对本文的看法,我们可以一起交流,一起进步。

退出移动版