简介: 可折叠Web即将到来,我们应该去思考可折叠Web可能会给我们带来什么变化,如果这一天真的到来,我们的技术能否支持该设备?
作者 | 大漠
可折叠Web的说法是可折叠设备带来的。可折叠设备形式多样,从笔记本电脑到手机,再到新奇的双屏幕混合设备。对于这类新发明并没有一个全面的定义,但大多数都可以归为两类。“可折叠”是指屏幕可以折叠的设备(比如华为Mate X,三星Galaxy Z Flip);而“双屏”设备的屏幕是分开的,但也可以以独特的方式一起工作,以灵活的形式提供生产力(比如,微软的Surface Neo和Surface Duo)。当涉及到Web设计时,这两种类型可能会遵循类似的规则。如果这项技术能大获成功,那么Web设计将面临十年来最大的变革。这对于我们Web开发者而言,也将会开启新的旅程。
听起来就很令人兴奋,但这到底意味着什么呢?可折叠Web将带来新的挑战,新的机遇,而且很可能还会带来新的概念。互联网可能也会经历自智能手机以来最大的变革。你可能会认为这是一种炒作,但事实上这样的一天已经离我们不是太远。记得在去年这个时候,有些移动品牌商,比如华为,三星都推出可折叠的硬件设备,而微软,苹果等公司在幕后的努力也不逊色。可以说可折叠Web即将到来。我们真的应该去思考可折叠Web可能会给我带来什么变化?如果这一天真的到来,我们的技术是否能支持该设备。简单地说,我们开发的Web页面能不能在可折叠设备和双屏幕上完美的运行。
可折叠和双屏设备
可折叠设备采用的是一种柔性屏幕技术,该技术的研究始于20世纪70年代,但直到世纪之交才得到真正的发展。特别是在去年,得到了爆发式的发展——在市场上能看到一些可折叠设备终端。比如三星Galaxy Z Flip手机,模仿的是老式的翻盖手机:
.gif")
还有很多像电子书一样,当设备完全打开时,内部的两个显示屏会合二为一。通常在外面有一个独立的小屏幕,这样用户在使用的时候就不用打开它。
双屏幕设备是具有两个对称屏幕的便携式设备,以独特的方式一起工作,以灵活的形式提供生产力。比如像微软的Surface Neo和Surface Duo这样的双屏幕设备,人们可以比以往任何时间都更快地完成工作。如果你使用过Surface Neo这样的双屏幕设备,你可以在一个屏幕上做笔记,在传输过程中在另一个屏幕上查看完整的项目建议书:
尽管现在市场上有不同的折叠屏,双屏幕设备,而且还会有更多的类似设备出现,但我们相信为这些设备设计应用程序会有一个共同的方法。我们希望这将帮助你的应用程序能跑在更多的设备上,而不需要为不同的设备做特殊的设计和处理。
换句话说,在可折叠屏或双屏幕的设备上,用户可以做更多的事情,比如说让屏幕分屏,可以同时打开多个应用程序:
新的 Web 标准、新的体验和新的问题
可折叠和双屏幕设备正在出现。这已经不是概念,也不是炒作。这更不是重点。重点是:
可折叠和双屏幕这项技术将如何影响Web开发人员、用户体验设计师以及其他以提供高质量浏览体验为业务的人。
首先可折叠和双屏幕会给视觉设计师在做设计的时候带来很大的变化。
整个可折叠的概念是基于你可以把你的手机变成平板电脑的想法。市场上大多数平板电脑的屏幕宽高比都是 4:3,所以手机和平板电脑的混合也应该是4:3。这使用折叠设备达到3:2。而这些比率都不能保证16:9或18:9的真实视频体验。其中4:3的宽高比更适合在各种文本和图形编辑器中执行任务和工作,比如iPad,但它需要更大的分辨率,这是可折叠设备无法做到的。这使得大多数可折叠手机处于一个模糊地带,给人用户的体验就会变得很糟糕,这也是因为在传统手机中是无法达到16:9的比例。
为了让可折叠手机成为一种有用的媒体设备,它必须转换成16:9或18:9的设备,然后再折叠成8:9或9:9 —— 基本上就是一个正方形。@Nathan Cunn通过计算得出结论,折叠手机的完美宽高比应该是其宽度的1.4倍。
除此之外,不管是可折叠设备还是双屏幕设备,最大的特征就是屏幕变大了,在展开的状态下和平板一样了。这样一来,可用的空间就变大了。
可折叠和多屏设备打破了移动设备(手机)可用空间小的束缚!
空间大了,能放置的内容就多了,如果设计还是按着以前的思路,直接拉伸平满全屏,就过于浪费了。面对这样的场景,除了响应式Web设计能帮助我们更好的利用可用空间之外,还可以参照淘宝设计提出的一个概念:
让你的内容像水一样的流动(“Content is like water”)
用一张图来描述:
有关于这方面更详细的介绍,可以关注淘宝设计微信公众号。
你可以搜索“可折叠”关键词,能找到一些这方面的文章,比如:
对于双屏幕给设计带来的变化,或者说设计应该要注意的细节,可以阅读微软官方有关于双屏幕的介绍:《Introduction to dual-screen devices》。
另外,折叠屏幕还会带来一些其他的设计和体验变化。
单(双)手移动设计
随着状态的改变(这里的状态是折叠和展开状态,单屏和多屏状态),整个体验本身也随之改变。目前大多数用户都习惯用一只手操作移动设备(手机),而展开状态,就像iPad了,这个时候需要两只手来操作设备(或应用)。
手机操作 vs 平板操作
屏幕连续性和间隔
可折叠设备和多屏幕设备有着明显的区别。
可折叠设备在展开状态时,它的屏幕是连续性的,我们在设计的体验应该无缝地转移到全屏上。
多窗口,多应用
前面提到过,折叠屏和多屏幕最大的特征之一,就让我们有更多的空间可利用。这样对于用户来说,对于处理多任务更友好,能同时做更多的事情。因此,我们应该始终考虑用户可能会同时运行多个App应用。比如说,一边查看日历,一边查看地图,一边看新闻:
除了同时打开多个App应用之外,还可以在同一个App中,分屏做不同的事情,比如,一边看直播,一边逛淘宝:
.gif")
折叠屏和多屏幕除了给设计师带来新的挑战之外,给Web开发者也带来相应的挑战。在去年华为Mate X出来的时候,有幸参与在Mate X做一些Web端的适配处理。主要处理H5的应用完美适配折叠屏设备。
由于相关H5业务采用的都是视窗单位vw(我常称该方案为vw-layout),能较好的让相应的H5业务适配折叠屏展开状态,但也存在一些相应的问题,最为突出的是图像变得模糊:
虽然该方式可以让我们的H5应用最大化的利用折叠屏可用空间,但也存在一定的缺陷。因此在《聊聊安卓折叠屏给交互设计和开发带来的变化》一文中提出相应的概念:
处理折叠屏时,我们应该像一些带有刘海设备(比如iPhone X)一样,具有独特的检测特性来检测折叠设备或多屏幕设备。
值得庆幸的是这一年来,在这方面有了明显的变化,尤其是微软公司的团队对可折叠技术的探究和讨论非常的积极。在今年2月份,三位微软开发人员@Bogdan Brinza、@Daniel Libby和@Zouhir Chahoud发表了一篇文章,解释如何使用JavaScript API和CSS 媒体查询来处理可折叠和多屏幕设备的布局。
该文档提出两个概念:用于双屏幕布局的CSS 和 窗口段枚举的JavaScript API。它的宗旨是作为讨论折叠屏和多屏幕在Web开发中技术标准。即:以可折叠和双屏幕设备为目标的Web开发人员能够在跨多个显示区域的窗口中有效的对Web应用进行布局。
未来处理可折叠或多屏幕的 Web 技术
从@Bogdan Brinza、@Daniel Libby和@Zouhir Chahoud三位开发者在Github上发表的文档《Web Platform Primitives for Enlightened Experiences on Foldable Devices》来看。处理可折叠和多屏幕设备的Web布局主要由两部分特性组成,其一是CSS的媒体查询特性,其二是JavaScript API。
接下来,我们主要围绕着这两个部分来展开。
用于构建双屏幕布局的 CSS 特性
特别声明:用于双屏幕布局的CSS还处于W3C规范的 草案当中,一切皆有可能会变。
@Brinza、@Libby和@Chahoud提出了一个CSS特性,即媒体特性,它可以确定网站是否跨越两个相邻的显示区域,以及这两个相邻显示区域的配置。相应的还提出了另一个特性,即环境变量(指的是用户代理定义的环境变量),它将帮助Web开发人员以CSS像素计算每个屏幕区域的大小。
为什么要提出新的CSS特性
当浏览器窗口跨越设备折叠时,告诉Web开发者折叠方向和显示边界可以帮助他们开发出来具有较好体验的Web应用。这里快速概述可能会出现的模式。
将更大屏幕的UI模式带到更小的便携设备
由于屏幕尺寸的限制,传统的便携式触摸设备在很大程度上依赖于“叠加视图”,比如点击收件箱列表中的一封邮件,就会导致整个收件箱列表视图被选中的邮件内容视图所取代。这种行为通常会创建额外的操作步骤;而在更大屏幕的设备上将会有一个更自然的配置,邮件收件箱列表视图和邮件内容视图是并排的。
轻松改进现有的Web应用和UI组件
Web开发人员可能不想为这类设备引入主要的UI更改,而只想简单地移动一些组件。在下面的示例中,对于模态对话框(Modal)避免设备折叠更有意义(无论可折叠设备是无缝的还是有间隙的),并允许Web开发人员逐步增强他们的站点,提供更好的体验。
也正因为这些原因,提出了相应的CSS特性和设计原则。
CSS媒体特性:spanning
提出一个新的媒体特性:spanning,该特性可用于检测浏览器窗口是否跨越多个显示区域。
spanning特性主要有三个值:
- single-fold-vertical:屏幕是水平的,布局视图跨越单个折叠(两个屏幕)并且折叠姿势是垂直时(分左右两边),这个值是匹配的
- single-fold-horizontal:屏幕是垂直的,布局视图跨越单个折叠(两个屏幕)并且折叠姿势是水平时(分上下),这个值是匹配的
- none:描述浏览器窗口不处于跨越模式时的状态
识别折叠或多屏设备的CSS环境变量
这个有点类似于刘海设备一样,通过env()函数来识别环境变量,即识别安全区域:
- env(safe-area-inset-top):在Viewport顶部的安全区域内设置量(CSS像素)
- env(safe-area-inset-bottom):在Viewport底部的安全区域内设置量(CSS像素)
- env(safe-area-inset-left):在Viewport左边的安全区域内设置量(CSS像素)
- env(safe-area-inset-right):在Viewport右边的安全区域内设置量(CSS像素)
Web开发人员可以利用这些变量来计算横屏和竖屏的每个屏幕片段大小。
注意,这些CSS环境变量的值是CSS像素,并且是相对于布局视图的(即在客户端坐标中,由CSSOM视图定义)。当不处于跨越状态时,这些值将被视为不存在,则会取env()函数的回退值。
来看一个简单的示例:一个地图应用程序,在一个屏幕上显示地图,在另一个屏幕上显示搜索结果。如下图所示:
如果用CSS代码来实现的话,大致如下:
@media (spanning: single-fold-vertical) {
body {
flex-direction: row;
}
.map {
flex: 1 1 env(fold-left)
}
.locations-list {
flex: 1;
}
}
spanning 的 Polyfill
到目前为止,新增的CSS媒体特性spanning和相应的环境变量都还处于草案的讨论阶,但如果你要尝试着在折叠设备或多屏幕设备上使用该特性的话,可以使用@darktears 提供的一个Polyfill。
这个Polyfill的使用很简单,你可以使用NPM将这个Polyfill加载到你的项目中:
npm install --save spanning-css-polyfill
安装完之后,通过将对应的spanning-css-polyfill.js引入到项目中:
也可以使用import的方式引入:
import "/path/to/modules/spanning-css-polyfill/spanning-css-polyfill.js";
这样你就可以在CSS中使用spanning这个新媒体查询特性和CSS环境变量fold-top、fold-left、fold-width和fold-height。
当然,你还可以手动改变显示(display)相关的配置。比如,通过导入FoldablesFeature对象:
import { FoldablesFeature } from '/path/to/modules/spanning-css-polyfill/spanning-css-polyfill.js';
可以通过FoldablesFeature对象来更新像spanning、foldSize和browserShellSize等值。你也可以订阅change事件,以便spanning媒体查询特性或环境变量发生变更时得到相应的通知。
import { FoldablesFeature } from '/path/to/modules/spanning-css-polyfill/spanning-css-polyfill.js';
const foldablesFeat = new FoldablesFeature;
// Add an event listener.
foldablesFeat.onchange = () => console.log("change");
// Add as many event listeners as you want.
foldablesFeat.addEventListener('change', () => console.log("change"));
// Change a single value; results in one update (one 'change' event firing).
foldablesFeat.foldSize = 20;
// Change multiple values by assignment; results in one update.
Object.assign(foldablesFeat, { foldSize: 50, spanning: "none"});
// Change multiple values in one scope; results in one update
(function() { foldablesFeat.foldSize = 100; foldablesFeat = "single-fold-horizontal" })();
有关于spanning更详细的使用,可以查看Github上的相关教程。
枚举窗口片段的 JavaScript API
特别声明,枚举窗口片段的JavaScript API已移到 W3C第二屏幕社区组。相关的解释、问题和评论,可以参阅GitHub的 webscreens/window-segments仓库。
这里提出了一个窗口片段的新概念,它表示位于单独(相邻)显示上的窗口区域(及其尺寸)。窗口片段尺寸以CSS像素表示,并允许Web开发者通过JavaScript API对窗口片段进行枚举,在相应的窗口片段上放置独立内容。
这个建议主要针对响应式场景,在这种情况下,Web应用程序希望利用跨越多个显示的优势,通过用户、窗口管理器将其置于该状态。它不适合将内容预先放置在各种可用显示的单独顶级浏览器上下文的情况(这属于Window Placement API和Presentation API)。请注意,使用枚举窗口片段的API和Web现有的特性,可以使用JavaScript来编写交叉显示和窗口的矩形,同时考虑devicePixelRatio来,计算横跨多个显示的窗口区域。不过,这个并不能正确的处理未来设备形式中存在的极端情况,因此,这个提议试图解决Web开发人员针对或考虑显示内容屏幕作为一个实际的起点。
简单地来说,Web开发者可以使用getWindowSegments()来获取一个DOMRects数组,然后根据每个窗口片段返回的数据,开发人员能够推断出可用链接(Hinge)的数量以及其方向。
用户可以在任何时候将浏览器窗口脱离跨越模式,并将其放在某个屏幕上,反之亦然,在这种情况下,将触发窗口resize事件,从而可以查询并获得可用屏幕段的数量。
比如我们上面提到的示例:
如果使用JavaScript来解决的话,可以像下面这样:
const screenSegments = window.getWindowSegments();
if( screenSegments.length > 1 ) {
// 现在我们知道这个设备是可折叠(可多屏幕)的
// 建议测试 screenSegments[0].width === screenSegments[1].width
// 可以更新CSS类,实现不同的布局效果
document.body.classList.add('is-foldable');
document.querySelector('.map').classList.add('flex-one-half');
document.querySelector('.locations-list').classList.add('flex-one-half');
}
我们再来看另一个示例,当窗口的resize事件和spanning状态发现变化时处理方案。
先看CSS的解决方案:
@media (spanning: none) and (max-width: 728px) {
body {
flex-direction: column;
}
.map {
flex: 0 0 300px;
}
.locations-list {
flex: 1;
}
}
如果使用JavaScript可以这样:
window.onresize = function() {
const segments = window.getWindowSegments();
console.log(segments.length) // 1
if( screenSegments.length > 1 ) {
document.body.classList.add('is-foldable');
document.querySelector('.map').classList.add('flex-one-half');
document.querySelector('.locations-list').classList.add('flex-one-half');
}
}
实战:多屏幕布局
最后我们来看实际案例。
你可能在手上没有折叠屏或多屏幕的设备,有可能无法看到实际效果。但可以使用一款基于Web的模拟器,这款模拟器可以模拟微软 Surface Duo 和 Surface Neo两款分屏设备:
@kenchris 在GitHub上spanning-css-polyfill提供了几个Demo,我们来看最简单的basic中的index.html。
HTMl部分很简单(这个Demo本身就很简单):
在