「響應式」這個詞混淆了兩種互斥的策略。重排保持元素的實際尺寸不變,改變它們的排列方式;縮放保持元素的相對位置不變,等比改變全體尺寸。文件型網頁用前者:字永遠是 16px,欄位從三欄變一欄。遊戲畫面用後者:角色與地圖的相對位置是遊戲規則的一部分,不能因為螢幕變窄就把敵人換到下一行。
選錯的代價很具體。用重排思維做遊戲,你會寫出一堆 @media 斷點去調每個 HUD 元素的座標,斷點之間永遠有沒對齊的螢幕尺寸,而且新機型出來就要再補一個斷點。用縮放思維做文件,你會得到在手機上小到看不清的 12px 字。
三個彼此獨立的問題
把「響應式」拆成三個問題,每個問題的解法不同,混在一起想就會打結。
一、視口幾何(Geometry):可視區有多寬多高、比例多少、哪些邊緣不安全。 這是純數字問題,答案是像素與長寬比。手機從 16:9(1.78)到 21:9(2.33),平板 4:3(1.33),桌機可以拉成 3:1 以上。你的設計解析度只會命中其中一個比例,其他全部要處理。
二、輸入能力(Input):手指、滑鼠、觸控筆、還是遊戲手把。 這與螢幕尺寸沒有必然關係——觸控筆電是大螢幕+觸控,平板接鍵盤是中螢幕+鍵鼠。用寬度猜輸入方式是最常見的錯誤,正確做法是 pointer / hover media query(見 方向與裝置)。
三、資源預算(Budget):這台裝置每幀能畫多少像素。 一支 DPR 3 的手機在 1290×2796 上跑滿版,等於每幀 360 萬像素;一台 DPR 1 的舊筆電在 1366×768 只有 105 萬。像素量差 3.4 倍,而 GPU 效能可能是反過來的。這問題的解法是 render scale,不是版面(見 效能)。
遊戲的標準解法:設計解析度 + 取景
遊戲引擎(Unity 的 Canvas Scaler、Godot 的 stretch mode、Cocos 的 Resolution Policy)不約而同收斂到同一個模型,網頁上照抄即可:
1. 固定一個設計解析度 DESIGN_W × DESIGN_H (例如 1280×720)
2. 所有遊戲內座標都用這個座標系寫死,永不改動
3. 執行期量測容器的 CSS 尺寸 cssW × cssH
4. 算出縮放係數 scale,把設計座標系映射到螢幕
5. 比例不合的那個軸,用一種「取景策略」補償
第 2 步是關鍵:遊戲邏輯完全不知道螢幕尺寸的存在。碰撞、AI、存檔全都在設計座標系裡跑,只有最外層的呈現層知道 scale。這條界線一旦破了——例如有段程式碼寫 if (window.innerWidth < 768) 去改子彈速度——你就再也無法保證不同裝置上的遊戲行為一致。
第 5 步的取景策略有三種,各有明確的適用場景,完整推導在 畫布縮放策略:
| 策略 | 做法 | 代價 | 適用 |
|---|---|---|---|
| letterbox(fit) | scale = min(cssW/W, cssH/H),剩餘補黑邊 | 有黑邊,滿版感消失 | 畫面構圖固定的橫向遊戲、街機移植 |
| cover(crop) | scale = max(cssW/W, cssH/H),超出裁掉 | 邊緣內容看不到 | 有背景可犧牲、UI 貼齊安全框 |
| expand(彈性視野) | 固定短邊,長邊視野變多 | 不同裝置看到的世界範圍不同 | 現代手遊主流;需確認不影響公平性 |
兩者其實要並存
滿版遊戲不是「只用縮放」,而是畫面用縮放、外框 UI 用重排:
- 遊戲畫布:等比縮放,維持設計解析度的座標系。
- HUD/選單/設定頁:這些是文件,該重排就重排。手機直向堆成單欄、平板兩欄、桌機側欄常駐。
- 命中區(hit area):不能跟著縮放。畫布縮到 0.4 倍時,一個設計上 48px 的按鈕實際只有 19px,手指按不到。命中區要用裝置像素設下限(Apple HIG 44pt、Material Design 48dp),做法是把互動 UI 放在 DOM 層而非畫布內,或在畫布內另外維持一個不隨 scale 縮小的觸控 padding。
這個分層在實作上就是「一個 canvas + 一層絕對定位的 DOM UI」。DOM UI 用 env(safe-area-inset-*) 貼邊、用 media query 重排;canvas 只負責被縮放。兩層各用各的響應式策略,互不干擾。
「設計解析度該選多少」
沒有標準答案,但有幾個可推導的原則。
選一個比例接近目標裝置中位數的值。 若主要跑手機直向,20:9(例如 1080×2400)比 16:9 更接近現況;若主要跑桌機,16:9 仍是安全選擇。你選的比例決定了「多數裝置需要補多少」——選得越偏,取景策略要吃掉的差距越大。
解析度數字本身不影響清晰度,只影響美術資產。 因為最終渲染會乘上 scale × devicePixelRatio,設計解析度只是座標單位。真正決定清晰度的是點陣圖資產的原始像素與 backing store 大小(見 DPR 與清晰度)。所以 1280×720 這種好算的數字完全夠用,不需要為了清晰而選 4K。
定義一個「安全框」比定義解析度更重要。 安全框是「無論在什麼裝置上都保證看得到」的中央矩形,通常取設計解析度的 80–90%。所有關鍵資訊(血條、分數、必按按鈕)都放在安全框內,這樣三種取景策略都不會切到它。
下一篇處理最容易寫錯的一步:視口設定 → meta viewport 與 svh/lvh/dvh