Chrome 浏览器正在试验两个全新的 API:Device Posture API(设备姿态API)和 Viewport Segments Enumeration API(视口段枚举API),这两个 API 统称为 Foldable APIs(可折叠API),它们从 Chrome 125 版本开始作为起源试验功能提供。这些 API 旨在帮助开发者更好地针对可折叠设备进行开发和优化,本文就来看看这些 API 如何解锁折叠屏应用开发新姿势。
这些 API 是在过去几年中,微软、英特尔、三星和谷歌合作开发的。
可折叠设备
可折叠设备主要分为两种物理形态:一种是只有单个柔性屏幕(无缝)的设备,另一种是拥有两个屏幕(有缝,也称为双屏设备)的设备。
这些设备为内容的展示提供了多样化的方式。例如,用户可以像翻阅书籍一样使用无缝设备,也可以像使用平板电脑一样将其展开为平面屏幕。而双屏设备因其两块屏幕之间存在物理接缝,需要开发者特别关注这一点。
这些新的 API 为开发者提供了改善这类设备用户体验的方法。每个 API 都通过CSS和JavaScript两种途径,向开发者开放了所需的 Web 平台基础功能。
Device Posture API
可折叠设备具备改变其姿态(即设备的物理状态)的能力,从而允许开发者提供不同的用户体验。这些新的API确保网页内容能够灵活响应设备的各种折叠状态。
设备可以呈现以下两种姿态:
- 折叠态:类似于笔记本电脑或书籍的姿态。
- 连续态:平板模式,类似于无缝的平板及曲面显示屏。
CSS
Device Posture API 规范引入了一个新的 CSS 媒体特性 device-posture,该特性能够解析出设备的一组固定姿态。这些姿态由预定义的值组成,每个值都代表设备的物理状态。
device-posture 特性支持的值与前面描述的设备姿态相匹配:
- folded(折叠态)
- continuous(连续态)
注意:如果未来有新的设备上市,可能会添加新的姿态。
示例:
/* 当设备处于“书籍”姿态时 */
@media (device-posture: folded) { ... }
/* 当设备处于“平板”姿态时,或者像笔记本电脑或台式电脑这样的典型设备 */
@media (device-posture: continuous) { ... }
JavaScript
为了查询设备的姿态,现在可以使用一个新的 DevicePosture 对象。
const currentPosture = navigator.devicePosture.type;
console.log(`当前设备的姿态是:${currentPosture}`);
要监听设备姿态的变化,并作出响应,可以注册一个事件监听器:
navigator.devicePosture.addEventListener('change', (event) => {
console.log(`设备的姿态已更改为:${event.type}`);
// 在这里可以根据新的姿态更新页面的布局或内容
});
Viewport Segments API
Viewport Segments 是CSS环境变量,用于定义视口中逻辑上独立区域的位置和尺寸。当视口被硬件特性(如折叠处或独立显示器之间的铰链)分割时,会形成视口段。这些段是开发者可以视为逻辑上不同的视口区域。
CSS
视口被分割成的段数通过两个新的媒体特性来呈现,这些特性在CSS媒体查询第5级规范中定义:vertical-viewport-segments(垂直视口段数)和horizontal-viewport-segments(水平视口段数)。这些特性会解析出视口被分割成的段数。
此外,还新增了环境变量来查询每个逻辑分割的尺寸和位置。这些变量包括:
- env(viewport-segment-width: x y):查询指定(x, y)位置视口段的宽度。
- env(viewport-segment-height: x y):查询指定(x, y)位置视口段的高度。
- env(viewport-segment-top: x y):查询指定(x, y)位置视口段的上边界位置。
- env(viewport-segment-left: x y):查询指定(x, y)位置视口段的左边界位置。
- env(viewport-segment-bottom: x y):查询指定(x, y)位置视口段的下边界位置。
- env(viewport-segment-right: x y):查询指定(x, y)位置视口段的右边界位置。
每个变量中的(x, y)坐标代表了由硬件特性在视口中创建的二维网格中的位置。
在上图中,第一个水平段的坐标是 x 0 和 y 0,第二个水平段的坐标是 x 1 和 y 0。第一个垂直段的坐标是 x 0 和 y 0,第二个垂直段的坐标是 x 0 和 y 1。
以下代码片段是一个简化的例子,展示了如何创建一个在折叠处两侧都有两个内容区域(col1 和 col2)的分割 UX。
/* 当视口水平分割为两段时 */
@media (horizontal-viewport-segments: 2) {
#segment-css-container {
flex-direction: row;
}
#col1 {
display: flex;
flex: 0 0 env(viewport-segment-right 0 0);
background-color: steelblue;
}
#fold {
width: calc(env(viewport-segment-left 1 0) - env(viewport-segment-right 0 0));
background-color: black;
height: 100%;
}
#col2 {
display: flex;
background-color: green;
}
}
/* 当视口垂直分割为两段时 */
@media (vertical-viewport-segments: 2) {
#segment-css-container {
flex-direction: column;
}
#col1 {
display: flex;
flex: 0 0 env(viewport-segment-bottom 0 0);
background-color: pink;
}
#fold {
width: 100%;
height: calc(env(viewport-segment-top 0 1) - env(viewport-segment-bottom 0 0));
background-color: black;
}
#col2 {
display: flex;
background-color: seagreen;
}
}
下图展示了物理设备上的体验:
JavaScript
要获取视口段的数量,可以检查 visualViewport 对象中的 segments 属性,它返回一个数组:
const segments = window.visualViewport.segments;
console.log('视口具有以下段:', segments);
segments 数组中的每一项代表视口的一个逻辑段,这些逻辑段使用 DOMArray 来描述坐标和大小。segments 字段是查询时给定状态的快照,为了接收更新的值,需要监听姿态变化(如屏幕旋转)或调整大小事件,并重新查询 segments 属性。
简单来说,这段代码可以查看当前视口被逻辑分割成的段的信息。如果想要追踪这些段如何随着窗口大小变化或设备姿态变化而变化,需要设置事件监听器来捕获这些变化并重新获取 segments 属性的值。
尝试 Foldable APIs
可折叠 API 已在 Chrome 125 到 Chrome 128 的版本中进行了原始试验。
为了进行本地测试,可以通过访问 chrome://flags/#enable-experimental-web-platform-features 来启用可折叠 API。另外,还可以通过在命令行中运行 Chrome 并添加 --enable-experimental-web-platform-featues 参数来启用这些功能。