phenomLi / Blog

Comments, Thoughts, Conclusions, Ideas, and the progress.
219 stars 17 forks source link

微信h5手机适配探索 #5

Open phenomLi opened 6 years ago

phenomLi commented 6 years ago

前些日子在做滴滴的七夕h5的时候,在调试手机适配上花了不少时间,一直没有一个完美的通用的适配算法,都是头疼医头,脚痛医脚,导致状况百出。
由于设计图是以iphone6作为基准的,于是一开始打算用设计图的宽度(750px)作为基准值,将根元素的font-size设为当前屏幕宽度与基准值的比:

html {
    font-size: calc(100vw/7.5)
}

设定了根元素的font-size,我就可以根据设计图的尺寸直接转换为rem来布局:

.box {
    width: 20rem;
}

但是最后发现效果并不如我想的那样,因为我选的基准值是基于设计图宽度的,所以只有在x轴方向的尺寸可以适配,在y轴方向上的尺寸适配不了。估计这种方法只适用于要横轴适应的SPA,而不是横纵都要适配的h5游戏。最后只能用屏幕高度与设计图高度的比作为基准值,也就是calc(100vh/6.67),x轴方向尺寸用百分百,也算是一直暴力解决方法吧。 后来我就想这个rem布局方式是否可以改进,其实方法无非就两个,一个是xy轴同时拉伸适配,一种是页面等比例缩放适配。但是头疼的是根元素的font-size属性只有一个,不能设置两个基准值。如果用页面缩放的思路,只能用js控制transform,或者动态改变meta的值。 transform方法太简单粗暴,而且估计效果也不会很好,我就放弃了,尝试用js控制meta的content:

const meta = document.getElementsByTagName('meta')[1],
          //缩放比例为:当前手机面积/设计图基准面积
          scale = document.documentElement.clientHeight*document.documentElement.clientWidth/(375*667);
meta.setAttribute('content', 'width=device-width,initial-scale=' + scale);

然鹅发现,当scale大于1的时候可以完美适配,但是当scale小于1的时候页面却没变化,怎么调都不行(直到现在我也不知道为什么会这样),最后这个方法也放弃了。


最近在写css的时候,又想起了less,然后就想到了能不能用less来做适配。尺寸不用rem,直接用calc计算尺寸。根据上面的rem计算公式,做了些改进:

x轴:calc(100vw/375*设计图尺寸);
y轴:calc(100vh/667*设计图尺寸);

如果在原生css中,对每个尺寸都要这样写一遍,未免太累了,我们可以在less中,用mixin功能实现上述表达式:

/*
rx代表横轴尺寸,ry代表纵轴尺寸,@attr代表属性,@size代表设计图尺寸
*/
.rx(@attr, @size) {
    @{attr}: calc(~"100vw/375*@{size}");
}
.ry(@attr, @size) {
    @{attr}: calc(~"100vh/667*@{size}");
}

试用一下:

#con {
    .rw(width; 200);
    .rh(height; 200);
    background-color: #333;
}

编译后的结果:

#con {
  width: calc(100vw/375*200);
  height: calc(100vh/667*200);
  background-color: #333;
}

赶紧上浏览器测试测试。 可以看到这个适配方法还是挺不错的,横轴纵轴都能根据屏幕动态变化,但是要真正检验这个方法的可行性,还是要放到实际项目中去测试。