iPhone Duo 前端踩坑記:折疊螢幕多了前端新 API,實作時卻依然在比寬高
Apple 也出摺疊螢幕的手機了!
我一開始心想應該沒什麼特別的,
Chrome 那邊肯定都把前端功能做好了,Safari(Webkit)肯定不會再亂搞?
摺疊螢幕就是螢幕大一點而已,誰會在螢幕打開一半的情況下滑手機?
網頁瀏覽器還能怎樣,分頁列、網址欄、工具列幾個橫排,還有什麼好討論的?
隔壁 Android 陣營早就做完了,Apple 還能有什麼新花樣?
UI 設計? 現在都叫 AI 刻介面,要查資料都問 AI Agent,誰還在討論 UI 設計?
一些在平板寬度範圍亂做的套板平台/SaaS,一樣沒人治得了他們。
等到 2026年 9~10 月,
測試了 Xcode 的 iPhone Duo 模擬器,
Webkit 發布摺疊螢幕的前端技術文章,
10 月底出貨後大家拿到真機開始使用,
一開始的那些想法......全錯😂😂😂
以下來探討這幾年摺疊手機硬體的變化、市面上各類摺疊比例的差異、Safari 27.1 與 Android Chrome 的支援度,以及如何用 CSS 和 JS 偵測螢幕狀態。
歷史沿革:十幾年前的蘋果專利、Android 拓荒史與 Chrome 演進
從我消費者的角度來看,摺疊螢幕手機就是一種很貴又容易壞的手機,誰愛買就買。
(戶晨風)
但從科技的角度來看,又是一大段有趣的發展史,這中間肯定養活了很多人。
蘋果十幾年前的專利佈局
有人以為 Apple 是看三星和一堆中國品牌的摺疊機把坑踩完了,技術成熟了,才跟風開始做?
但其實早在 2011 年 9 月,Apple 就向美國專利局提交了名為 US Patent 8,929,085 (Flexible electronic devices) 的專利,並於 2015 年獲准公開。
這項專利的發明人名單中包含了 John Ternus,也就是現任 Apple CEO。當年的專利就繪製了柔性外殼、內部鉸鏈與可彎曲 OLED 面板,甚至把透過機身彎折觸發接聽電話或調整音量等互動概念寫進了說明書。
Android 陣營的實戰演進
相較於 Apple 累積十多年的長線專利佈局,Android 陣營過去幾年走的是密集試錯與快速更新的工業化路線。
2018 年柔宇 FlexPai:率先發表全球首款商用摺疊機,但缺點罄竹難書,機身厚重、系統功能不足,比較接近原型展示機,有興趣的可以看看 Mobile01 的媒體文首台可預購摺疊螢幕手機 Royole FlexPai動眼看。
2019 年三星初代 Galaxy Fold 撕膜事件:第一代 Galaxy Fold 寄給科技媒體評測時,多位評測者誤將螢幕最外層的保護層當成出廠保護貼撕下,導致螢幕直接損壞;加上鉸鏈容易進塵,三星隨後推遲半年發售,加固轉軸與邊角防護後才重新推出。
Google Pixel 系列也有出摺疊手機,如果想要查價錢,搜尋「Google Pixel Fold」,會找到一台超便宜的手機...那台是 2023 年推出的初代老款,之後才有帶數字的 Pixel 9 Pro Fold、Pixel 10 Pro Fold,與今年(2026)的 Pixel 11 Pro Fold,最新一代達到 IP68 防塵防水,我們可以從官方影片看出摺疊螢幕可以做很多事。
你說 Google Pixel Fold 的官方宣傳影片裡面的操作,新增行事曆什麼的,一般的手機也能做,完全看不出什麼特點? 沒錯,您的理解完全正確。(Gemini 口吻)
2026 年 9 月小米 18 Fold:在蘋果秋季發表會前夕,小米發表新一代摺疊旗艦 Xiaomi 18 Fold,捨棄以往狹長比例,改採接近 A4 紙張的根號 2 比 1 寬摺疊,正面對標 iPhone Duo。
還有其他中國品牌手機的不同形態嘗試:華為從早期的外折方案 Mate X,後來轉向主流內折,後續推出雙轉軸三摺疊機 Mate XT 非凡大師;OPPO Find N 則主打手感較合手的小巧矮胖比例;vivo 與小米則持續在機身輕薄度與折痕平整度上競爭。
瀏覽器規格與 Chrome DevTools
瀏覽器標準也沒閒著,先把規矩立住,路才能越走越寬。2020~2023 年 Google 與微軟(為雙螢幕 Surface Duo)在 W3C 共同起草了相關規範,並於 Chrome 透過 Origin Trial 進行實測。2023年 Chrome for Developers 那篇 Origin trial for Foldable APIs,大量介紹了 Chrome 針對摺疊螢幕的前端規格與實作細節。

不過內容嘛,現在看看就有,因為很多都更新了...

2026 年 10 月的 Chrome DevTools 更新,把 Chrome 開發者工具好好整理了一番,專門分一類摺疊機出來,這個類別的裝置可以從 Device Mode 切換 Continuous 與Folded 兩種狀態。

2026 年 10 月 23 日,iPhone Duo 開始供貨,官方也發布了 WebKit Features for Safari 27.1,介紹 WebKit 中實作了摺疊相關的前端開發細節。

那個可怕的 6 狀態摺疊圖在幾個月前 WWDC2026 相關資料就見過了,不只是 APP 開發,在網頁前端這邊也無處不在。
摺疊手機形態大觀:從粉餅盒、冷氣遙控器、護照本到三摺疊
在討論實際的 UI 改變,和新增的前端 CSS、JS 之前,先大致分類一下市面上摺疊手機型態,不同機型的比例和摺疊方向,直接決定了 UI 設計和前端 RWD 開發時會遇到哪些邊界狀況。
翻蓋直立小摺疊/貝殼機/小折
- 代表機型:三星 Galaxy Z Flip 系列、OPPO Find N Flip、華為 Pocket 系列、小米 MIX Flip。
- 硬體特點:上下對折,主打便攜,折合後約掌心大小。
- 前端考量:展開時是一塊狹長螢幕(約 21:9 或 22:9);外螢幕從早期 1.1 吋輔助螢幕,逐步加大,使用者還可能用某些方式,在那個小小的外螢幕瀏覽網頁。

長摺疊/大折
- 代表機型:三星 Galaxy Z Fold 3~7、三星 Galaxy Z Fold 8 Ultra、小米 MIX Fold、vivo X Fold 系列、Google Pixel 9~11 Pro Fold。
- 硬體特點:閉合時外螢幕較為狹長(約 21:9 ~ 23:9),握持感偏細;展開後接近 4:3,或是有些廠商會做成方形比例。
- 前端考量:外螢幕又窄又長;展開後用電腦桌面版畫面又略小,而且使用者的手是在螢幕兩邊。

矮闊型摺疊/中摺疊/寬摺疊/護照型(Wide / Passport Fold)
- 代表機型:第一代 Google Pixel Fold、OPPO Find N、OnePlus Open 以及 iPhone Duo、三星 Galaxy Z Fold8。
- 硬體特點:機身偏寬矮,展開時比例接近 4:3 或根號2比1。
- 前端考量:外螢幕或是水平展開時,垂直高度通常比一般瀏海手機還要矮,以前適合手機直立的 banner 都被裁切。

三摺疊螢幕
- 代表機型:華為 Mate XT 非凡大師、三星 Galaxy Z TriFold。
- 硬體特點:Z 字型雙轉軸設計,擁有三個摺疊段落。
- 前端考量:響應式適配範圍較廣,涵蓋單螢幕手機、大折到三螢幕展開的平板比例,在單一裝置上有機會碰到多種不同的版面切換。
外折螢幕
- 代表機型:華為 Mate Xs 系列、榮耀 V Purse。
- 硬體特點:整片柔性螢幕朝外包覆,摺疊後背面也是螢幕,展開時直接拉直。無需在內外兩組螢幕間切換銜接,但面板直接外露,需留意耐用度。
Safari 將控制列移至右側的設計考量
iPhone Duo 的外螢幕比例較為矮寬。在傳統直向手機上,網址列在頂部、工具列在底部是常見做法;但若是照搬到外螢幕上,頂部狀態列加上底部網址列,會吃掉很多垂直高度。
於是蘋果做了全新的設計,一支工具列被移到螢幕側邊的手機,下圖是將外螢幕打橫後旋轉,會發現瀏覽器工具列還跑到左邊去了。

在一些系統介面操作中,「左上角返回」的按鈕也被移到螢幕側邊,需要稍微習慣一下。不過還是一樣可以直接拖曳滑動操作返回上一頁。

根據 WebKit Features for Safari 27.1 的說明,Safari 27.1 預設不會讓網頁主體內容延伸至右側控制列下方。右側保留區域僅會以頁面背景色延伸填補。這樣做的原因是考慮到許多既有網站雖宣告了 viewport-fit=cover,卻未妥善處理 safe-area-inset-right 邊距,若強行通鋪容易造成互動元件被遮蔽。
上面的擷圖讓人覺得角落還有一些空白的空間? 但別忘了那個位置是鏡頭。
iPhone Duo 的手機形狀還有一對?二對?超級大圓角,正常情況下應該是不太會碰到問題,除非碰到太有創意的 UI 設計,例如在角落做一個三角形的返回按鈕之類的。

Brim Browser:把網頁延伸到右邊去
真的覺得瀏覽網頁時右邊的空間很浪費,那可以試試 Brim Browser。

Brim Browser 把網頁內容延伸到右邊去,然後利用手機裝置端的 AI 檢查鏡頭下的 HTML 元素,自動修正,避免網頁裡面的按鈕被鏡頭遮擋。
Brim uses Apple’s on-device AI models to scan and fix the HTML elements that may be under the camera cutout https://t.co/S9ulVk0P3l
— joao (@joogps) October 26, 2026
摺疊螢幕不是寬螢幕,脆弱的手機中間轉軸
平常看紙本漫畫書時怎麼拿? 拿下面中間?
平常拿 iPad Mini 怎麼拿? 拿下面中間?
如果 iPhone Duo 水平展開後,手指用力捏在中間轉軸位置,那下場就是手機損壞。
常見的 UI 設計: 按鈕的文字置中、重要內容放在螢幕正中間給人點,手指按住拖曳螢幕中間的 range slider,現在都可能變成螢幕殺手。
不過,摺疊螢幕中間的摺痕,和書籍設計還是有很大的差別,我們其實不太需要「避開」它。書籍如果把重要圖文放在裝訂線附近,可能因為裝訂深度等因素,讓讀者難以看清楚內容,因此製作時需要特殊處理,以免發生類似《大濛》電影紀念特刊跨頁「卡臉」的事件。
在 Threads 查看
摺疊螢幕的摺痕至少仍然可以正常顯示內容,UI 設計人員不需要像排版書籍一樣,在中央刻意留出一大段空白。
與 iPad 的對比
在這直立展開 951px 的小小螢幕,碰到網頁上需要輸入內容的地方,也出現了這種左右分開的鍵盤。

這種鍵盤一般是在 iPad 上會看到,那 iPhone Duo 有其他跟 iPad 相同的功能嗎? 例如幕前調度(Stage Manager)、多工處理?
不好意思,在 iPhone Duo 上沒有那些東西,只有勉強給一個左右雙開,比例還不能自由調整的簡易版多工處理。

也不一定兩邊都是 Safari 啦,只要有支援的 APP 都可以放。
寫這篇文章時,iPad Mini 第8代剛發表,有趣的是 iPad Mini WiFi 版 255 克,iPhone Duo 254 克,剛好只差了一克,兩者重量幾乎一樣。

若同樣以機身展開狀態「長邊對長邊、短邊對短邊、機身最薄處厚度」來比較,iPhone Duo 比 iPad Mini 小了一點,長邊短了約 3.07 公分,短邊窄了約 1.48 公分。厚度少了 0.2mm。
雖然 iPad 的邊框(螢幕顯示區域到機身邊緣的距離)絕對比手機還粗很多,但螢幕的絕對實體顯示面積,還是 iPad Mini 更大。至於實際上看影片會不會有大黑邊,看漫畫會不會被裁切,還是要看內容而定,這邊僅提供數值參考。
iPad Mini 打橫時(1158px) vs. iPhone Duo 展開打橫時(951px),這個差距在 TailwindCSS v4 預設的 lg: 門檻(1024px)下,iPad mini 會進入桌面排版,iPhone Duo 則會落在 md:(768px~1023px)區間。
例如測試時發現一個電商開店平台的定價方案頁,大約在 viewport 寬度大於 1080px 時,以四欄一橫排的形式整齊平鋪,各方案的功能與價格對比一目了然。
遇上 iPhone Duo 展開螢幕(寬度 951px):頁面內容直接跌落成單欄垂直堆疊(如下圖)。

使用者手持 7.9 吋展開的 iPhone Duo 廣闊螢幕,畫面卻被一張被拉扯至近 900px 寬的肥大卡片佔滿,一眼望去根本顯示不了幾行字,而且無法橫向比對方案差異,使用者被迫像操作狹長小手機一樣不斷向下滑動。
我也舉個自己的例子,有個網頁的 logo 比較大顆一點,高度太小的話看不清細節,然後選單項目又很少,所以本來是到了寬度小於 600px 才把 logo 縮小,選單收起來變成漢堡選單。在一般 iPad 直立跟橫放顯示也都還好,因為垂直高度有很多空間嘛。
結果在 iPhone Duo 水平展開螢幕時,上橫幅 logo 連帶著讓整個上選單區域變得很佔空間,結果又需要在一定寬度範圍的 breakpoint 中進行細修。
我們再另外試試 iPad Mini 打直 vs. iPhone Duo 展開打直(上下分屏)時,大致都落在 TailwindCSS v4 預設的 md: 門檻內。

摺疊螢幕專用的 CSS Media Query:Device Posture 摺疊狀態
為讓 CSS 能夠感知硬體的開合狀態,W3C 與主要瀏覽器制定了一些核心規範,而且在開頭的歷史沿革中提到 Chrome 老早就開始實作,基本上 Chrome 132 以上都能支援(撰文時穩定版號 155)。那 Safari 這邊呢? 又是一個雷,等一下再說。
姿勢查詢:@media (device-posture: ...)
這項屬性不計算螢幕分割數量,而是直接反映設備目前的物理開合姿態:
folded:設備正摺疊成某個角度(類似漫畫書的左右摺疊狀態/類似筆電或NDS的上下狀態狀態/摺疊懸停)。continuous:設備是平整展開或一般單一螢幕。
@media (device-posture: folded) {
/* 當使用者要把手機摺疊時,顯示一些動畫 */
}
•
(device-posture: continuous):檢測中...•
(device-posture: folded):檢測中...
DevTools 切換 Continuous 與 Folded 的尺寸反差謎團
你什麼時候產生你已經看懂 folded 和 continuous 規格的幻覺了? 在 Chrome DevTools 模擬或實機實作時,看到的畫面可能跟想像的完全不一樣。
在 Chrome DevTools 開啟 Pixel 9 Pro Fold 或 Galaxy Z Fold 進行模擬時,明明點選了 Folded(摺疊),畫面卻突然展開成 800 多像素的雙屏大螢幕

點選 Continuous(連續),畫面反而縮小回 400 像素左右的單一外螢幕。
這個反直覺現象的本質,在於日常直覺、規範定義、模擬器實作的不同:
- 在物理規範定義中,「闔上外螢幕」與「完全展開攤平的內螢幕」都是平整無折角的表面,兩者在 Device Posture API 裡通通算同一個狀態(
continuous)。 - 只有當機身處於「摺疊狀態中(如 90° 至 120° 的書本或筆電角度)」時,才被算作
folded狀態。
若需在 DevTools 測試「完全展開攤平且無折痕的大螢幕(951 × 618 且 continuous)」,還是需要將裝置選單切換至 Responsive(自適應)直接輸入寬高,或在 DevTools 設定的 Devices 列表中新增自訂裝置。
高度不一定是618,瀏覽器是否有多分頁、網址列有沒有摺疊起來,都會影響到實際的 viewport 高度,這個數值僅供參考,dvh 的概念就不再多提了。不要再問工程師說到底圖片尺寸要做多大,才能剛剛好不會切到、上下左右都不會留空隙。
如果真要回答的話,就丟 Webkit 的官方說法吧,有緣人自然會看懂。

摺疊螢幕專用的 CSS Media Query:區段查詢:viewport-segments
如果要知道螢幕被摺疊時,viewport 被分割成幾個區段,則可使用 CSS Viewport Segments API 的 media query,範例如下:
當裝置處於微折或懸停、像書本一樣左右分屏時,會吃到這段 @media (horizontal-viewport-segments: 2) {...}
當裝置處於微折或懸停、像筆電或NDS一樣上下分屏時,會吃到這段 @media (vertical-viewport-segments: 2) {...}
•
(horizontal-viewport-segments: 2):檢測中...•
(vertical-viewport-segments: 2):檢測中...•
(horizontal-viewport-segments: 1):檢測中...檢測中...
這裡有一個常見的直覺盲點:很多人以為把摺疊機「完全展開攤平」成大螢幕後,就會自動吃到 horizontal-viewport-segments: 2(左右兩邊?)。實際上並不會!依 W3C 規範,完全展開攤平(continuous 狀態)時整塊柔性螢幕是一體連續的,此時區段數為 1(horizontal-viewport-segments: 1 為 true,而 2 為 false)。只有在機身有實體角度微折(folded 姿態)、或是像早期的雙螢幕實體邊框跨屏時,區段數才會是 2。若要在完全攤平的寬螢幕上排版成左右兩欄,就不能單純只看 segments,更不能只設常規的寬度 breakpoint(否則會害橫持的普通手機跑版,稍後會示範精準的雙態寫法)。
只靠 viewport-segments 只知道「被切成了兩半」,現在的主流摺疊手機都是兩邊一樣大,直接寫寬50%或高50%或1fr 1fr,聽起來好像沒什麼問題。
但要是以後出了某種一邊螢幕較大,一邊螢幕小的裝置,網頁馬上就爆了。若要讓版面精準貼齊轉軸邊界,則需搭配瀏覽器提供的 6 個 CSS 環境變數(Environment Variables):
viewport-segment-width x yviewport-segment-height x yviewport-segment-top x yviewport-segment-right x yviewport-segment-bottom x yviewport-segment-left x y
括號內的兩個索引值分別代表區段所在的欄(Column x)與列(Row y),從左上角的 0 0 開始起算:
- 左右並排時:左邊區段為
0 0,右邊區段為1 0。 - 上下堆疊時:上方區段為
0 0,下方區段為0 1。
/* 左右並排時,精準對齊兩側區段與中間轉軸折痕 */
@media (horizontal-viewport-segments: 2) {
/* 左區段 (x=0, y=0) */
.pane-left {
top: env(viewport-segment-top 0 0);
left: env(viewport-segment-left 0 0);
width: env(viewport-segment-width 0 0);
height: env(viewport-segment-height 0 0);
}
/* 右區段 (x=1, y=0) */
.pane-right {
top: env(viewport-segment-top 1 0);
left: env(viewport-segment-left 1 0);
width: env(viewport-segment-width 1 0);
height: env(viewport-segment-height 1 0);
}
/* 中央轉軸折痕縫隙:右區段的 left 減去左區段的 right */
.hinge-separator {
width: calc(env(viewport-segment-left 1 0) - env(viewport-segment-right 0 0));
}
}
env(viewport-segment-* x y) 解析數值:[ 區段 0 0(左或上區段)]:
• width: 讀取中... | height: 讀取中...
• top: 讀取中... | left: 讀取中... | right: 讀取中... | bottom: 讀取中... [ 區段 1 0(右區段)或 0 1(下區段)]:
• width: 讀取中... | height: 讀取中...
• top: 讀取中... | left: 讀取中... | right: 讀取中... | bottom: 讀取中...
• 轉軸間距 (Hinge Gap): 讀取中...
在隔壁 Chrome 的規範起草背景下,則是假設有某種「具備實體多螢幕+螢幕中間還有轉軸縫隙」的設備,如早期的 Surface Duo,因此官方範例特別在兩個內容區塊(#col1、#col2)中間夾了一個 #fold 元素,利用 calc(env(viewport-segment-left 1 0) - env(viewport-segment-right 0 0)) 算出轉軸盲區的寬度再避開。
以下摘錄 Chrome 的文章部分程式碼:
<style>
/* 區段水平並排(書本式左右分屏) */
@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;
}
}
</style>
<div id="segment-css-container">
<div id="col1"></div>
<div id="fold"></div>
<div id="col2"></div>
</div>
這種寫法是向硬體索取「轉軸兩側各自真實的可用空間」,正向來看是專治內容跨越折痕時的各種不舒服,往壞處說沒人知道數值會不會亂給,讓可憐的工作人員當義工修網頁。
用 JavaScript 偵測摺疊狀態
剛剛是純 CSS 的寫法,若需在 JavaScript 中即時監聽與處理摺疊狀態,可依賴以下 API:
偵測物理姿勢:navigator.devicePosture
if ('devicePosture' in navigator) {
console.log('目前狀態:', navigator.devicePosture.type); // 'folded' 或 'continuous'
// 監聽姿勢變化
navigator.devicePosture.addEventListener('change', () => {
// 注意:
// 事件物件 e.type 為字串 "change",而非姿勢名稱
// 正確作法是讀取 navigator.devicePosture.type
const currentPosture = navigator.devicePosture.type;
console.log('狀態變更為:', currentPosture);
updateLayout(currentPosture);
});
}
navigator.devicePosture 取值:•
'devicePosture' in navigator:檢測中...•
navigator.devicePosture?.type:檢測中...
偵測區段數量 window.viewport.segments,window.viewport.segments 不會回傳單一數值,而是回傳一個 DOMRect 陣列。陣列中的每個 DOMRect 物件代表一個 viewport segment,包含該區段的 x、y、width、height 等資訊。

當拿到兩個 DOMRect 物件 [seg0, seg1] 時,透過比對這兩個區段的 y 坐標與 x 坐標,就能推導出目前螢幕區段的排列方式與轉軸方位:
- 上下堆疊(水平轉軸):若
seg0.y !== seg1.y,代表區段沿垂直 Y 軸上下排列(對應 CSS@media (vertical-viewport-segments: 2)),此時兩區段中間的折痕轉軸為水平走向(hingeAxis: 'horizontal')。這對應到直拿翻蓋小摺(Galaxy Z Flip)立在桌上,或是大摺疊機(Galaxy Z Fold)橫向旋轉 90° 後的筆電懸停打字姿態。 - 左右並排(垂直轉軸):若
seg0.x !== seg1.x,代表區段沿水平 X 軸左右排列(對應 CSS@media (horizontal-viewport-segments: 2)),此時兩區段中間的折痕轉軸為垂直走向(hingeAxis: 'vertical')。這對應到大摺疊機直立握持時微折的書本對開閱讀姿態。
這裡容易讓人卡一下的是「區段排列方向(Segment Orientation)」與「轉軸走向(Hinge Axis)」的幾何差異:CSS 規範是以區段分佈方向命名,上下堆疊稱為 vertical-viewport-segments,左右並排稱為 horizontal-viewport-segments。
但兩區段中央的折痕轉軸剛好與排列方向垂直(呈 90 度交角)。在封裝 JS 工具函式時,建議同時回傳 segmentOrientation(對齊 CSS Viewport Segments 語義)與 hingeAxis(物理轉軸走向),避免在寫程式時產生混淆,看到 horizontal 或 vertical 就開槍。
早期 Chromium 提案是用 window.visualViewport.segments,如果想要進行雙重相容,可以這樣寫:
function getFoldSegments() {
// 只讀取一次 segments,優先支援 W3C 標準(window.viewport.segments),次之相容早期 Chromium(window.visualViewport.segments)
const segments = window.viewport?.segments ?? window.visualViewport?.segments ?? null;
if (!segments || segments.length < 2) {
return {
isDivided: false,
segmentsCount: segments ? segments.length : 1,
segmentOrientation: 'none',
hingeAxis: 'none'
};
}
const s0 = segments[0];
const s1 = segments[1];
// 比對 Y 軸坐標:若 Y 軸有落差,代表區段為上下垂直堆疊(對應 CSS vertical-viewport-segments: 2)
// 此時中間的實體轉軸走向為水平橫向(horizontal hinge)
if (Math.abs(s0.y - s1.y) > 5) {
const isS0Upper = s0.y < s1.y;
return {
isDivided: true,
segmentsCount: 2,
segmentOrientation: 'vertical',
hingeAxis: 'horizontal',
upperRect: isS0Upper ? s0 : s1,
lowerRect: isS0Upper ? s1 : s0
};
}
// 比對 X 軸坐標:若 X 軸有落差,代表區段為左右水平並排(對應 CSS horizontal-viewport-segments: 2)
// 此時中間的實體轉軸走向為垂直直向(vertical hinge)
if (Math.abs(s0.x - s1.x) > 5) {
const isS0Left = s0.x < s1.x;
return {
isDivided: true,
segmentsCount: 2,
segmentOrientation: 'horizontal',
hingeAxis: 'vertical',
leftRect: isS0Left ? s0 : s1,
rightRect: isS0Left ? s1 : s0
};
}
return {
isDivided: false,
segmentsCount: 2,
segmentOrientation: 'unknown',
hingeAxis: 'unknown'
};
}
window.viewport.segments 取值:•
segments 回傳值:讀取中...•
getFoldSegments() 判斷結果:計算中...
viewport.segments 的運作機制與常見誤解
你什麼時候產生你已經看懂 segments 規格的幻覺了?
如果把摺疊手機完全展開後,在 Console 印出 window.viewport.segments),卻發現回傳長度依然是 1,進而懷疑瀏覽器根本沒有正常回報展開狀態,或是 AI 寫的程式碼有問題?

這並非瀏覽器故障或 API 異常,而是 W3C 在制定時 Viewport Segments 規範的明確考量。核心目的是在螢幕出現物理遮擋(如雙螢幕中央的金屬邊框)或空間視角差(如機身正在摺疊狀態、半折懸停)時,讓網頁開發人員避開中間盲區。
當使用者將手機攤平成大平板閱讀長文、瀏覽相簿或觀看影片時,整塊螢幕是一體成型的連續視野。若此時瀏覽器就不會強行回傳區段數為 2,而是 1。
Safari 要另外手動啟用 feature flag
上面講了老半天,實際上 JavaScript 程式碼可能根本無法在 iPhone Duo 的 Safari 上正常執行,只會看到 navigator.devicePosture 得到 unsupported,然後 window.visualViewport.segments 會得到 0,根本無法用 JS 監聽判斷摺疊狀態。
原因是目前這兩個瀏覽器 API 預設是關閉的,要另外手動到 Safari 的 feature flags 中啟用。

如果使用者沒啟用,JS 程式碼就壞光光。
為什麼不像 Chrome 預設直接打開? 官方對這個的說法說可能還有改善空間,朕想聽聽天下百姓的意見。
With the Device Posture API and the Viewport Segments API behind flags, there may still be time to evolve how they work. Let us know if you have thoughts or requests.
取得螢幕開合角度
好了,現在我們能知道螢幕是展開/收合,還是開到一半/懸停;
也能知道現在螢幕被分成幾半,是上下分還是左右分了。
接下來我們可以再取得螢幕的開闔角度
做出一些有趣的應用
......做不到......
天王老子來了也不行。

其實在 2020 年最早是有 Screen Fold API 的提案的,有 screen-fold-angle 跟 @media (min-screen-fold-angle: 270deg) {...} 之類的規格。
在相關討論Device Posture API(formerly Screen Fold API)#575,可以看到大家有其他的想法,但最後變成了前幾段介紹過的 Device Posture API,只有 folded 和 continuous 兩種狀態的破玩意。
在 Screen Fold API 資料的底下有一大段 Security and Privacy considerations 的章節,認為 sensor 對角度讀數的變化、設備姿態的計算,以及事件觸發的回報頻率,都可以拿來 fingerprinting,被廣告追蹤之類的有心人士應用。
有什麼大膽的創意跟想法? 乖乖繳 Apple 開發者年費,去做 APP 去吧!
實例測試:把網頁文章變成像書本一樣?
如果碰到有人要求:
「我要在 iPhone Duo 上看文章時,像實體書一樣左右分頁」
「照片跟影片不要剛好卡在中間摺痕」
那麼該怎麼做?
難道要用程式先把文章內的一堆 html tag 手動拆成「左頁」和「右頁」嗎?可是使用者從各種編輯器上稿,產生出來的就是一堆連續的 <p>、<img>、標題標籤,怎麼可能要求上稿人員人工切分?
現代瀏覽器都支援一個 CSS 多欄排版屬性,完全不需要動到後台資料結構,也不需要手動分段。
只要在 p 標籤的 parent 容器上宣告 columns: 2; column-gap: 64px;,瀏覽器排版引擎就會自動計算,將子元素 <p>、<h3>、<blockquote> 等等自動分流到容器左右兩側,搭配 break-inside: avoid,更可防止標題、引言或程式碼區塊被截斷在欄底。同一篇文章、完全不需人工改稿,即可實現宛如實體書的優雅閱讀體驗。
但其實這樣做非常白爛,大概只適合拿來拍短影片,根本無法實際運用。
瀏覽器技術上的限制,column-count: 2; column-gap: 64px;這種只能處理自動左右分欄,沒辦法分成上下堆疊,其他前端做法都需要先對內容進行預處理(手動分段,或是用 JS 去抓內容,然後再去做分欄),複雜度直線上升。
如果內容超級多,也只是變成左右兩欄超級多的內容,而不會像電子書一樣自動分頁。
頁面捲動時,會兩邊一起動,但另一半邊我根本還沒看,所以左邊看完之後,必須一路往回滑回最上面,重新從右邊第一行開始看,這在 UX 上被稱為 「N 字形視線地獄」。
不想人工去幫內容分頁,還可以繼續使用剛講的 column-count 搭配 scroll-snap-type: x mandatory; 相關的 CSS,做出水平換頁滑動的版面。
總之如果要真的做成一般人習慣的那種電子書的樣子,那些新工具都沒什麼用,該重排的重排,該做特效的做特效,該不會又要復辟網頁翻頁特效了吧? 看來 2026 就是網頁翻頁特效元年了。
如果正在用 iPhone Duo 或其他摺疊手機,螢幕展開看這篇文章,我也沒有調什麼特殊的版面設計,跟用平板看差不多。
實例測試:把網頁系統程式針對左右摺疊模式作特殊UI設計
例如有個網頁的資料管理介面,我要做一個摺疊螢幕的專屬介面,展開時一邊放清單介面,一邊放詳細內容介面,只有給 iPhone Duo 享用,一般的平板/電腦/普通手機打橫都不給。
最陽春的直覺寫法如下:
@media (horizontal-viewport-segments: 2) {
.notebook {
display: grid;
grid-template-columns:
env(viewport-segment-width 0 0)
env(viewport-segment-width 1 0);
column-gap: calc(env(viewport-segment-left 1 0) - env(viewport-segment-right 0 0));
}
}
但這個寫法在真實世界會立刻遇到一個尷尬情境:當使用者將 iPhone Duo 180 度完全攤平時,雙欄直接破功消失!
上面的文章跟實際測試範例一再強調,在 W3C 規範中,完全展開攤平屬於 continuous 姿態,整塊螢幕是連續無折角的平面,此時 horizontal-viewport-segments 會回歸為 1,手機完全展開時,上面的 CSS 規則就不會被匹配。
如果在外層再加一個 @media (min-width: 768px),這會引發嚴重的橫向排版災難:
- 現代一般直板手機(例如 iPhone 18 Pro Max、三星 Galaxy S26 Ultra),只要使用者轉為橫向拿著,Viewport 寬度便高達 900px 以上。
- 但一般手機橫拿時,垂直高度大約只有 380~430px,長寬比超過 2.1:1(甚至 21:9 超扁平帶狀)。若被誤觸雙欄,扣除瀏覽器網址列後,可視高度只剩 300px 左右,兩欄會被擠成狹長的細管,完全無法閱讀。
- 相較之下,iPhone Duo 完全展開時寬度約 951px,高度有 618px(長寬比約 1.54:1,接近 3:2),具備充足的垂直閱讀空間。
兼顧微折與完全展開的雙態響應式寫法
要讓網頁在「微折(folded)」與「完全展開(continuous)」時都能呈現左右雙欄,同時精準排除「扁長橫拿的普通手機」,關鍵在於結合多種 media query 條件(寬度 + 最小高度):
:root {
/* 預設雙欄尺寸(完全展開時使用) */
--pane-list-width: 320px;
--pane-detail-width: 1fr;
--pane-gap: 24px;
}
/* 狀態一:微折書本姿態(folded,有實體轉軸折角) */
/* 動態替換為硬體回傳的兩側區段精準寬度與轉軸間隙 */
@media (horizontal-viewport-segments: 2) {
:root {
--pane-list-width: env(viewport-segment-width 0 0);
--pane-detail-width: env(viewport-segment-width 1 0);
--pane-gap: calc(env(viewport-segment-left 1 0) - env(viewport-segment-right 0 0));
}
}
/* 雙欄觸發條件:微折雙區段,或完全展開的大螢幕折疊機/平板 */
/* min-width: 700px 完整涵蓋 Galaxy Z Fold(768px)、Pixel Fold(842px)、iPhone Duo(951px) */
/* min-height: 480px 關鍵防線!市面所有橫拿直板手機高度僅 380~430px,100% 精準攔截 */
@media (horizontal-viewport-segments: 2),
screen and (min-width: 700px) and (min-height: 480px) {
.notebook {
display: grid;
grid-template-columns: var(--pane-list-width) var(--pane-detail-width);
column-gap: var(--pane-gap);
}
}
這樣的架構能帶來三層防護:
- 處於微折時:自動讀取
env()精準避開中央轉軸折痕。 - 180 度完全平攤時:雖然 segments 變回 1,但展開寬高皆跨過 700×480 門檻,乾淨切成 320px 清單與彈性內容區。
- 普通手機橫放時:因高度不足 480px(通常僅約 380~430px),條件不符,自動維持單欄排版,絕不破版。
這就是標題的由來,看似 CSS 跟 JS 多了一堆新玩意可以用,結果做到後來,想要做一些特殊設計,還是在依照 viewport 寬高範圍去調整。
摺疊螢幕的網頁測試工具
若手邊尚無實體摺疊機,或需在 Safari 與 Chrome 驗證網頁在摺疊手機上會不會爆炸,可參考以下資源:
AWS 的 Device Farm
Device Farm 上面其實半台摺疊機都沒有,不管是 Android 系統跟 iPhone 都一樣,我還寫信去問,AWS 是說用量太低,所以沒有提供給一般開發者使用(the demand for them is low so we don’t have them in our public devices list)。
如果真要用的話,要走 Private Device 方案,邏輯就是 AWS 會幫人去採購手機,代管在他們那,然後我們可以遠端連線到那台手機上測試。手機在租用期結束之後就會銷毀,不會給別人重複使用。
然後依照手機零售價,分成幾個 AWS 月租費價位帶,每台最低 $200 美金起,新註冊帳號的 AWS Credits 不能拿去抵 Private Device 方案的費用,必須要另外付費。
那個方案最短至少要簽半年+5台裝置以上,算下來最便宜就是每個月 $1000 美金起跳。
三星自家的 Remote Test Lab
若需測試三星特定機型,可搭配三星自家的 Remote Test Lab,每個帳號有一定的免費點數。

每次最短30分鐘,如果用沒幾分鐘就退出,還可以選擇退還部份點數。
其他雲端 APP 測試平台
在手邊沒有實體摺疊機時,很多人的直覺是去尋找線上的雲端真機測試平台(例如 BrowserStack、Sauce Labs 等)。
但實際用過一圈,就會發現現實非常骨感:
- 很多是專門為了 APP 開發測試用途,一定要上傳 apk 之類的,不一定有提供 web test 服務。
- 很多線上平台根本沒有提供最新的摺疊機型,有提供的也幾乎全被鎖在昂貴的付費方案中,完全不開放給一般每日免費額度/新會員試用區。
- 配額排隊搶不到:iPhone Duo 這種機型連線時往往大排長龍。想要不花錢在這種平台做正經的測試,幾乎是不可能的任務。
本地測試
與其把時間浪費在線上排隊碰運氣,最踏實且零成本的測試途徑,依然是回歸自己的電腦本機環境。
Android 陣營:在電腦安裝 Android CLI 跑 AVD(Android Virtual Device),讓 AI coding agent 去下載摺疊機型的映像檔跟配啟動參數。可以穩定觸發各類摺疊手機的事件,比 Chrome DevTools 更完整。
Apple 陣營:在 macOS 上安裝 Xcode,使用 Device Hub 來集中調度虛擬裝置與實體機,開啟 Safari 進階設定啟用 Feature Flags。
若純粹為了粗略驗證網頁 CSS 響應式佈局與斷點,直接使用本機 Chrome DevTools 也是最快速、最不求人的起手方式。
結語
摺疊手機的出現,打破了有些人認為「手機即窄屏單欄、電腦即寬屏多欄、設計稿只要畫一份」的既定界線。說起來其實也是有摺疊螢幕的電腦啦,但是沒人關心而已,反正本文主要討論手機。

面對 iPhone Duo 與各類 Android 摺疊機,前端開發的核心不只是盲目窮舉各機型的解析度寬高範圍,還有:
- 透過
device-posture與viewport-segments等新功能感知硬體姿態,取代單純的寬度猜測。 - 兼顧雙手握持的人體工學,避免將主要操作元件置於中央折痕區。
- 為外螢幕矮扁比例與虛擬鍵盤彈起,預留垂直高度的操作彈性。
- 知道 Safari 瀏覽器能做到哪些事,哪些東西做不到,AI 或客人拿一些過時舊資料出來高談闊論時,才能明辨是非。
為了讓網頁都能維持良好的可用性與閱讀體驗,軟硬體持續演進,前端開發中就有越來越多的 CSS 與 JS 標準。
官方技術文件
- Apple 2011 年可摺疊裝置專利 (US Patent 8,929,085)
- WebKit Blog: WebKit Features for Safari 27.1(Jen Simmons 介紹 Safari 27.1 與 iPhone Duo 的設計考量)
- Chrome Developers: Foldable APIs Origin Trial(Chrome 官方對摺疊 API 與鉸鏈計算的教學)
- W3C Device Posture API Specification
- W3C CSS Viewport Segments Specification
- A set of demos to showcase support of foldable devices on the web. Chrome 文章中附的範例,整個帳號的 repo 最後更新差不多是2年前(2024年)...