移动端之在不同尺寸大小的手机上展示同一效果解决方案 by FungLeo
前言,反思
在之前的项目当中,我在CSS中设置html{font-size: 62.5%;}
,也就是设置为10px
,然后全站根据这个根植,来设置rem
单位的样式.这样虽然解决了很多的问题.但是在面对不同宽度的手机的时候,还是需要去自适应设置很多的内容.当然,因为手机分辨率的不同,我们可以*的将页面设置在320(iphone5s)-414(iphone6plus)
这样的范围内还是很合适的.但是,奇葩手机年年有,华为meta8这款奇葩手机的缩放居然是2.5倍,也就是说,它的宽度居然是432
,这样一来,我自适应的页面上的内容就显得有些小了.
而且,设计师对我实现的页面还是颇多微词,因为,只有在普通安卓手机上显示是最正常的,5S有点拥挤,6p又有点过宽.
那么,到底TMD有没有一种方式,可以完美的实现设计稿的设计呢?也就是说,不管你的手机屏幕是多大,屏幕分辨率是多少,都能在页面上完整的还原设计稿.
也就是说,要求就是,大手机上,看着每个元素,包括文字都要大一些.而在小手机上,看着要小一些.全部都整体缩放呢?
另外,我为什么要给html{font-size: 62.5%;}
,为什么不是直接写10px
呢?我的思考是将选项交给用户.问题是,用户真知道吗?或许,一万个用户,也难得有几个会去调整浏览器的默认字体大小.白瞎了我的一番苦心.
那么,为什么我不去百分百还原设计稿呢?
我要解决这个问题.
实现的思路
首先,全部单位都是rem,全部基于rem来实现,这一点是肯定的.那么问题的关键还是,给html
设置font-size
.思路是大一点的手机,就设置大一点,小一点的手机就小一点.
思路没错.怎么实现呢?首先,我想到的是媒体查询.
但是我很快放弃了.
看过一些使用媒体查询的案例,首先,它不能无缝切换,而只能根据不同的手机尺寸来进行适配调整.而且,难保不会出现问题.虽然大部分的浏览器都是会进行缩放的.但是不排除某些页面嵌套到APP里面,没有进行缩放处理,导致特别小,或者特别大.这两天我已经被这个特别小或者特别大的问题给折腾疯了.
放弃了媒体查询.我将目光转向了JS
,虽然我一直不喜欢在这种展现层去使用JS,因为我不希望因为JS进行DOM操作大幅的降低网页的性能.但是,我用JS来设置一些html
的font-size
好像不会损失太多的性能.
决定用JS来实现.就需要来考量一下.
计算逻辑
一个项目,要分为两种情况,一种是还没开发的,一种是已经开发了的.目前我遇到的情况就是,这个项目的前端部分我已经开发完成了.只是我希望我去解决一个问题.因此,我下面的算法是基于我已经写好的代码的基础上的.
而如果一个项目还没有开发,正在规划阶段,那么可以选用更加合适的数值.但是基本原理是一致的.我这边说一下我的情况.
我先前是按照html{font-size: 62.5%;}
,也就是设置为10px
的基本设置,全站以REM为单位完成的开发.也就是说,我是按照360
为设计稿宽度来制作的整个前端界面.
我们的html的font-size的计算公示应该如下:
设备宽度/设计稿宽度*比率
而我的这个项目的计算公示就应该如下:
设备宽度/360*10
其中,设备宽度是需要通过JS从浏览器自动获取的.以iphone5s为例,数值如下:
320/360*10 = 8.88888
当然,我这是基于我原有的代码来进行的调整.我们在启用一个新项目的时候,则可以更加随心所欲一些,例如,我们完全可以按照我们的标准设计稿的宽度,如720或者640或者1080来进行实际的计算.
当然,比率是一个问题.如,我们以10为比率,并且以720的设计稿宽度来计算,我们会得到如下
320/720*10 = 4.44444
这样的数值.在移动端这没有什么问题,但我们在PC端进行调试的时候就有问题了,因为chorme
浏览器的最小像素为6px
这就会给我们造成麻烦.因此,如果是这样,我建议比率可以设置为100,也就是如下:
320/720*100 = 44.44444
REM值的确定
因为我的项目之前是确定好了的.如,我需要写一个12px的文字,我就会写1.2rem,计算是很清晰的.基本上不需要费脑子计算.但如果,我们是基于上面的720的设计稿宽度,比率为100,那么显然,全站的rem值必须要进行一个调整.
这个计算公示如下:
数值/比率=需要的rem值
思路收回来一下,这个rem值是什么?
这个rem值是设计稿上的一个宽度,如设计稿宽度是720.对应在代码中,应该转化为多少rem值.
这个算法很简单,就是拿需要的数值/比率就可以得到对应的rem值了.如,设计稿宽度为720,比率为100.那么,我们设计稿上的零件的宽度为240px,我们需要写的就是240/100=2.4rem,我们需要写一个14px的文字,那么就是0.14rem.
代码
JS代码
JS代码的部分特别简单.代码如下:
document.getElementsByTagName("html")[0].style.fontSize=Math.floor(document.documentElement.clientWidth*100000/36)/100000+"px";
这句代码,我不推荐使用jquery来写,而是用原生js,并且是第一句执行的代码.在引入框架前就把他跑完.
scss代码
为什么要有scss代码呢?
回应上面的计算rem值的问题,如果设计稿的宽度为720,比率为100,那倒是真心不用费脑子去计算.但是各家公司的标准都是不一样的.因此,可能你公司的标准,使得这个数值非常难以计算,例如比率为50,或者75之类的.
因此,我们构建一个sass函数来解决这个问题.
@function rem($px){
@return $px / 100 + rem;
}
而在需要调用的地方,就直接这样写:
width: rem(240);
上面的这个240
就是设计师给你的设计稿上的px
数值.
less中应该也有类似的功能.但是不用,所以就不是很清楚了.如果是使用less的同学请自行研究一下.
总结
每一天,都在推翻前一天的经验.每一天,都在惊喜和悔过中度过.
本文由FungLeo原创,允许转载.但转载必须署名作者,并保留文章首发链接.否则将追究法律责任.
首发地址:http://blog.csdn.net/FungLeo/article/details/51177863
修正一
- 一开始,我使用的是获取屏幕宽度的方法,为
screen.width
这在大部分的手机上都没问题.但是遇到了一些变态的国产浏览器就产生了问题.因此,将screen.width
修正为document.body.scrollWidth
- 以我这个项目为例,我们最好好使在
css
中去设定html
的font-size
为10px
以防止在JS没有成功运行之前,页面布局超乎想象.
修正二
- NND,今天发现在部分手机部分页面,居然会莫名其妙出现获取宽度不正确.没办法,将
document.body.scrollWidth
更换为document.documentElement.clientWidth
问题好像解决了.
有其他问题,欢迎留言,我们一同进步,一同学习.