回到目录

[前端知识体系] 设计还原

2017-09-24

0x1 何为设计还原?

顾名思义,设计还原即把设计稿内容通过代码还原(实现)出来,其效果不单单是看起来差不多,还需要做到像素级无差别。这不仅要求程序员对宿主开发环境的控件库、布局原理和定位方式要熟练和精通,而且要有很「刁钻」的视觉审查能力。

为什么需要专门写一篇文章说这件事情,是因为看似基础的工作内容,太多人做不到位了。在公司我负责审查外包的静态页面,我发现同样的问题总是三番四次纠正,连页面最基本的交互原则都没有考虑,心里总是愤怒和无奈。作为界面的实现者,不仅仅需要对拿到的设计稿进行审查并还原出来,更多的还要考虑到适配、交互和可阅读性的最优平衡。下面说说我对设计还原的理解和标准。

0x2 静与动

设计稿是静态的,也是动态的。先说静态的,拿到设计稿之后,需要看什么内容?

1. 设计稿的尺寸

对于 PC 页面来说,设计稿的核心内容区域宽度不超过 1280px(目前屏幕宽度在 1280px 以上的用户数占 90%),但最好在 1024px 以内(兼容笔记本电脑)。在核心内容区域之外可以有任意发挥的辅助性元素/背景,但需要平缓过渡到纯色以兼容更大的屏幕(如 iMac)。如果是单屏页面,设计稿核心内容高度最好控制在 500px 以内。

再说 H5,目前主流的方案只要求设计师根据 iPhone6 的尺寸来设计。已经有了成熟的方案让页面适配任何终端。但是在 iPhoneX 出来之后,需要注意页面顶部和底部是否预留了足够的空间,不至于内容被遮挡。

2. 字体、字号、字色

不要用特殊字体,不要用特殊字体,不要用特殊字体。不是每台电脑或每部手机都装了设计稿里用的特殊字体,而一个中文字库要好几十M 基本是不可能下载调用的。除非中文字体是固定的,那么可以用字体提取工具把特殊中文字体集抽出来,转成 base64 加载。

而字号呢,在 H5 中最小 24px,普通的 28px,非常次要的辅助性内容可以用 20px。不能再小了。要知道设计师在电脑上设计的时候往往会把设计稿放大,而在几寸的手机屏幕上,字号的问题会严重起来(看看传说中针对老年人设计的 iOS11 的大字号,也许你能看到趋势)。

一个页面的字体颜色不要超过三种,不要超过三种,不要超过三种。这并非一个非设计专业的程序员的个人偏好,这是我们设计总经理说的,我也极度认同。

3. 空白页

这也是设计师经常会疏漏的地方,如排行榜列表暂无数据,应该如何展示?搜索页找不到内容,应该如何展示?若设计师没有考虑到,请提醒 TA。

4. Retina 兼容

PC 页面的图标是否提供了双倍图以适配高清屏幕的展示?

说完静,再说动,「动」体现在与用户的交互上:

5. 点击态/按压态

所有页面可以点击的元素,都必须要有一个让用户点击后明显感知的状态。拿到设计稿后先看看设计师有没有补齐。当然也有比较方便的做法:我在实际工作中已经和设计师达成一致,通过代码设置透明度来实现点击状态的变化。

当然除了有点击态,也有不可点击态。同时超链接是否有特殊颜色或者下划线来让其看起来是可点击的?

6. 动效还原

静态的设计稿并不能体现出页面交互动效,这里建议设计师通过 Principle、Hype 或 Framer Studio 原型工具输出动画,因为这些工具都有准确的动效参数,方便通过代码参考复用和精准还原。

0x3 优雅实现

私以为更高层次的视觉还原不仅仅是视觉层面的高质量还原,还应该体现在代码层面的优雅实现。简单来说,在移动端兼容性基本没有问题的前提下,能用 flexbox 布局就不用 position 或 float;能用伪类 :before / :after 实现的就不要多加一个 DOM 节点。除此之外,还有一些最基本的前端注意事项:

1. 文本过长截断

简单来说,屏幕空间有限,过长的昵称、过长的文案都会导致换行或者超出范围,这个时候需要提前考虑到并做防范措施:

// 块级元素截断
@mixin block-text-ellipsis($w) {
    width: #{$w}px;
    display: block;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

// 行级元素截断
@mixin inline-block-text-ellipsis($w) {
    max-width: #{$w}px;
    display: inline-block;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

// 多行截断
@mixin multi-line-text-ellipsis($n) {
    display: -webkit-box;
    -webkit-line-clamp: $n;
    -webkit-box-orient: vertical;  
    overflow : hidden;
    text-overflow: ellipsis;
}

2. 点击区域大小

确认移动端设备最小可点区域是否大于 44*44,如果没有(一般是文本链接),需要额外扩大:

button {
    position: relative;
    width: 20px;
    height: 20px;

    // 通过伪类扩大按钮可点区域
    &:after {
        content: "";
        position: absolute;
        left: -10px;
        right: -10px;
        top: -10px;
        bottom: -10px;
        z-index: 5;
    }
}

3. 点击态延时

:active 的触发是即时的,也就是说在滑动页面的时候,你轻触屏幕也会触发 :active 点击态。这样容易给用户造成困扰。所以一般我们会通过 tap 或者 fastclick(首选)来模拟用户的点击,并通过添加类名来增加点击态,并在 300ms 后删除该类名:

// 为页面添加点击态(不用 :active 伪类避免误触)
$('.list-wrapper').on("click", "li", function(event) {
    var item = $(this);
    item.addClass('active');
    setTimeout(function() {
        item.removeClass('active');
    }, 300)
})

4. 屏幕适配

设计师在出设计稿的时候,往往没有考虑到兼容不同的屏幕尺寸,这就需要我们在实现的时候思考不同屏幕下的适配,那么一般来说有三种适配模式:

图示已经很清楚了,不过这种方式一般是针对平台型的页面,很多时候都建议使用 px 而非 rem 来做适配,因为 css 的 px 是设备无关像素,系统会自动计算出它显示的大小,正如原生 App 中的度量单位 pt、dp、sp 等一样,在 Hybric App 中的 H5 页面尤其需要注意这点。

而活动页面可以使用等比缩放这种粗暴的方式来适配,不管是 REM、Viewport、Transform: scale(n) 等方式,只要能一劳永逸都可以。

0x4 如何校验还原度?

设计还原之后,如何验证还原度?一般有两种做法:

1. 对比设计稿

我们通过在页面里嵌入一个 JS 来方便的通过 URL 引入一张设计稿截图(透明度 50%),盖在页面上做对比:

代码也很简单:

(function() {
    // 获取 URL 参数
    function getURLParameter(name) {
      return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search) || [null, ''])[1].replace(/\+/g, '%20')) || null;
    }
    // 将图片节点插入页面
    function appendHtml(el, str) {
        var div = document.createElement('div');
        div.innerHTML = str;
        while (div.children.length > 0) {
            el.appendChild(div.children[0]);
        }
        div.style.position = "absolute";
    }
    // _p 图片路径、_t 距离顶部高度、_c 是否对比
    function compare(page) {
        var _page = getURLParameter("_p");
        var _compare = getURLParameter("_c");
        var _top = parseInt(getURLParameter("_t"));

        if(!_page) {
            _page = page;
        }

        if(!_top) {
            _top = 0;
        }

        if(_compare) {
            var div = "<div style='position:absolute;left:0;top:"+_top+"px;width:100%;z-index:9999;opacity:.5;pointer-events:none;'><img style='width:100%;display:block;' src='/src/compare/"+_page+"'></div>";
            appendHtml(document.body, div);
        }
    }
    compare(window.location.href);
})();

2. 设计师走查

将做好的页面二维码发给设计师,并建立 Google doc 由设计师将还原度不佳的内容列出来,前端逐一解决修改。