View on GitHub

Yinjie - GitHub.io

Welcome to the Yinjie's notes

充满一屏的自适应 UI 解决方法

估计大家都有遇到过这样的需求:

做一个宣传展示类的页面,有好几页,需要一页一页的翻动。

这个需求看听起来很简单,就一个纯展示类的页面,没有什么复杂功能,翻页效果也是信手拈来,然后就立即上手去做。 但是拿到 UI 图看了看,隐约感觉有什么不对啊~~~(PS:也有可能是做了一大半才发现,或者是最后真机测试总会发现)。

UI 图的尺寸是固定的,虽然用通常的自适应缩放方法,如rem,可以解决多尺寸屏幕下UI缩放的还原度,但是比例问题不好解决啊: 比如公司UI统一出图都是 750*1334 的,长度比例大致是 1.778,但直机就不一样了,有 16:9(1.778)、4:3(1.33)、3:2(1.5)等等。 再加上各浏览器有自己的状态栏等,视窗的大小比例真是杂乱无章了。 而且像这类展示性的 UI,设计的随意性很大,压根没有什么规律性排版可言, 不可能在每个比例下都看起来正常,这个时候就需要我们和 UI 一块协同解决了。

这个问题目前没有什么100%的完美解决方案,UI 元素是只能是等比放缩的,但是屏幕比例可不是等比的,这必然会造成元素在不同屏幕比例下位置与UI的设计有差异。

对比,笔者通过两个实际项目,总结出一些经验方法,分享一下。

UI 设计的小幅调整

对于这种页面,我们需要在UI设计之前就与相关同学进行协商,在这里我分享给大家一个经验得出的“较”合适UI出图大小:

750 * 1150(比例:1.5333~)

这个比例是综合了市面上所涉及到的多数屏幕尺寸比例,与各浏览器去掉菜单、状态栏等元素后,实际显示的视窗大小,折中的一个比例大小。 这样可以顾及到绝大多数的直机充满全屏的显示效果。当然,这个效果也需要前端制作时的一些方式方法。

定比例制做

在以上的基础上,我们就可以按以上比例进行等比例缩放制做了。但是这个缩放比例怎么定,比例固定的“制做区域”怎么在比例不固定的真机屏幕里放置呢? 这个也是前端的关键了,下面介绍两种在此情况下的“等比”缩放方式。

基础的页面结构如下:

<div class="body">
    <div class="wrap">
    </div>
</div>

其中.body需要和屏幕大小一致。.wrap里放置我们做的图。

rem

我们平常所用的 rem 方法都是通过屏幕宽度来动态确定基准 rem 大小的。 但是这里,我们需要通过屏幕的宽/高一块确定rem大小了。

因为屏幕有可能比 UI 图“长”,也有可能比其“方”,仅靠屏幕宽来定 rem,有可能在比较“方”的屏幕里出溢出的问题。

以下代码来确定高或宽的较小放缩比来作实际的 rem 比例。

    /**
     * 计算整体缩放比例
     */
    var DEFAULT_WIDTH = 375,
        DEFAULT_HEIGHT = 575;
    var win_width = document.documentElement.clientWidth,
        wid_height = document.documentElement.clientHeight;
    var real_per = Math.min(win_width / DEFAULT_WIDTH, wid_height / DEFAULT_HEIGHT);

我们默认以 20rem 作为 750px ui图的基准,那么实际的 rem 变化就是

document.documentElement.style.fontSize = (20 * real_per) + 'px';

这样确定的rem就可以保证所做的“定比图”很好的充满屏幕了。别忘了还需要将.wrap上下左右的居中哦。

scale 缩放

上一个 rem 的方法比较传统,算是比较规矩的一个方法,笔者还总结出一个方法,对于这种“定幅”的一屏式ui制作更简单一点点,其还原度也更稳定。

还是以 750px 的UI图为例,我们可以以 px 为单位做一个适用于 375px 宽的图,再根据实际屏幕大小对其直接缩放即可,理论上性能也会更好。

上面计算real_per的代码还是需要的。再加上以下代码即可,.wrap上下左右的居中还是需要的。

var wrapEle = document.querySelector('.wrap');
wrapEle.style.webkitTransform = 'scale(' + real_per + ')';
wrapEle.style.transform = 'scale(' + real_per + ')';