Sitemap

Let’s meet Viewport Segments API

10 min readJul 9, 2025
Press enter or click to view image in full size
Let’s meet Viewport Segments API

Introduction

Chrome VER.138 釋出了一個非常有趣的支援 — Viewport Segments API。透過這個 Web API,web developers 可以針對 fold 類型的 device 做出一些客製化的樣式與操作。

Press enter or click to view image in full size
CSS Viewport Segments, https://github.com/foldable-devices/viewportsegments-css-polyfill?tab=readme-ov-file

如上圖所示,這是一個地圖 Web APP,便巧妙的利用了 fold dual-screen 的特性,讓左邊區塊顯示地圖資訊,而右邊區塊則顯示地標資訊。藉此讓使用者依照當前 device 以及操作方式可以有更多元的呈現與互動。

雖然說對象僅僅針對 fold 這類型的 mobile device,但是對 front-end 來說便是多了一種與使用者互動、交心的機緣,儘早掌握這類排版設計技巧總是需要的。

Viewport Segments API

Web developers 可以從 window.viewport 下取得 segments 相關資訊。若取得的個數大於 1,則表示目前使用者處與 multi-screen 的狀態。需要特別注意的是 device 僅有在似書本打開立起來放或是似 laptop 打開的樣子下,segments 的個數才會大於 1,倘若是 180 度完全展開模式,則是 segments 個數永遠都會為 1。

const { segments = [] } = window.viewport || {};
const orientation =
window.matchMedia('(orientation: landscape)').matches
? 'landscape'
: 'portrait';

console.log(`Segments count: ${segments.length}`);
console.log(`Orientation: ${orientation}`);

如上所示,我們不僅可以知道當前 segments 的個數,更可以搭配 orientation 的資訊來知曉當前是橫式還是直式展開。

CSS viewport segments media query

CSS 亦有釋出對應的 media query 供 web developers 進行樣式上的調整,其基本定義為:

@media (horizontal-viewport-segments: <count>) { }
@media (vertical-viewport-segments: <count>) { }

換成人話就是偵測當前水平 / 垂直 viewport segments 個數,目前除了華為出了一隻三折機外,大部分的狀況就是 dual-screen 狀態,所以接下來的範例均會以 2 進行設置。

*-viewport-segments

@media (horizontal-viewport-segments: 2) {
/* styles applied in double-portrait (wide) mode */
/* matches Figure 1. below */
}

@media (vertical-viewport-segments: 2) {
/* styles applied in double-landscape (tall) mode */
/* matches Figure 2. below */
}
Press enter or click to view image in full size
CSS viewport segments media query for dual-screen detection, https://learn.microsoft.com/en-us/previous-versions/dual-screen/web/css-viewport-segments

筆者自身的記憶法是水平切割成兩塊就是用 horizontal-viewport-segments,若是垂直切割成兩塊則為 vertical-viewport-segments。

另外還可以透過 env() 來取得 viewport segments 的各項資訊。

env(viewport-segment-width <x> <y>);
env(viewport-segment-height <x> <y>);
env(viewport-segment-top <x> <y>);
env(viewport-segment-left <x> <y>);
env(viewport-segment-bottom <x> <y>);
env(viewport-segment-right <x> <y>);

裡面 x / y 的設定就是左上角為原點,從 0 開始計數(類 grid 區塊劃分)。所以 dual-screen 類型大致上可以有兩種變化來取得各個 viewport segments 的 width / height / top / right / bottom / right 的資訊。

Press enter or click to view image in full size
CSS viewport segments media query for dual-screen detection, https://learn.microsoft.com/en-us/previous-versions/dual-screen/web/css-viewport-segments

以上圖左邊那個水平切割為例,由左上為原點,所以第一塊的 X Y 座標便是「0 0」,第二塊因為是向右邊長出去,垂直方位沒變化,所以 X Y 座標則為「1 0

右邊那塊垂直切割則因為水平方位都沒有變化,所以兩塊的 X 座標均為 0,下面區塊則因為向下長出去,所以 Y 座標為 1。

有了這些基礎知識後,如果我們想要取得水平切割右邊區塊的寬度,則可以這麼下:

.demo {
--inline-size: 100px;

inline-size: var(--inline-size);

@media (horizontal-viewport-segments: 2) {
--inline-size: env(viewport-segment-width 1 0);
}
}

此外,media query 還有支援另一個和 fold 相關的條件陳述式 — device-posture。可以透過 continuous 以及 folded 來偵測當前 device 是否是 fold 類型且半開闔模式。搭配 *-viewport-segments 就可以玩出更多元的變化。

@media (device-posture: folded) and (orientation: portrait) {
.list-view {
margin-block-end: 60px;
}
}

Example

知曉上述的玩具之後,筆者也做了些嘗試。透過實作來驗證其正確性以及深烙到自己技術櫃中。歡迎有興趣的朋友試試看。

Press enter or click to view image in full size
Example for Viewport Segments API. https://blog.lalacube.com/mei/example-viewport-segments.html
<style>
main {
...
...
display: flex;

@media (horizontal-viewport-segments: 2) {
flex-direction: row;

.dimension--A {
flex: 0 0 env(viewport-segment-width 0 0);
}

.dimension--B {
flex: 0 0 env(viewport-segment-width 1 0);
}
}

@media (vertical-viewport-segments: 2) {
flex-direction: column;

.dimension--A {
flex: 0 0 env(viewport-segment-width 0 0);
block-size: env(viewport-segment-height 0 0);
}

.dimension--B {
flex: 0 0 env(viewport-segment-width 0 1);
block-size: env(viewport-segment-height 0 1);
}
}
}
</style>

<main>
<div class="dimension dimension--A" data-dimension="A"></div>
<div class="dimension dimension--B" data-dimension="B"></div>
</main>

筆者透過 media query 以及 env() 來設置 dimension — A、dimension — B 的寬高以及排列模式。如此便可以隨著使用者當前手持方位以及開合模式進行調整。

How to test it ?

有越來越多的手機開發商推出了各式各樣 fold 類型裝置,不過基本價位依舊不好入手,尤其像筆者這樣只是單純想玩玩看 Viewport Segments API 的人來說未免太不切實際了。有這方面需求的朋友其實可以弄個模擬器來進行測試。

1.前往 Android Studio 進行下載。

Press enter or click to view image in full size
Android Studio, https://developer.android.com/studio

2.由於我們僅僅是要使用模擬器,所以直接打開 Virtual Device Manager

Press enter or click to view image in full size

3.如果陳列的裝置沒有你需要的機型,則點擊 + 來新增裝置

Press enter or click to view image in full size

4.下載且安裝完後,我們便有一台 Pixel 9 Pro Fold 了

Press enter or click to view image in full size

5.如果不是 Chrome VER.138 的話,記得前往 Play Store 進行 update

Press enter or click to view image in full size

以上便是簡易的模擬器設定流程。

Conclusion

以上便是 Viewport Segments API 的初體驗,可以透過 Web API 來知曉當前 viewport 資訊外,CSS 亦提供了 media query 以及 env() 來讓 web developers 版型設計上有充足的發揮空間。有興趣的朋友,不妨參照上面範例玩玩看吧!

Reference

--

--

Paul Li
Paul Li

Written by Paul Li

Paul is the lead programmer of the AMP project at Yahoo Taiwan and is always eager for modern web technologies. He is also focusing on UX for vivid user flow.

No responses yet