[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fLq_xkb725TH9pdeWfCGFH4TNIT4Gk52qNezTAtP8A8E":3},{"slug":4,"title":5,"body":6,"excerpt":7,"tags":8,"maturity":12,"meta":13,"plantedAt":14,"tendedAt":15,"shouldIndex":16,"resolvedLinks":17,"backlinks":19,"authorName":20},"mobile-rwd-gotchas","行動裝置收尾雷合集：16px、自動聚焦與 passive 事件","把整個站在手機與 iPad 上收尾的過程，攢下一小把「文件上不會告訴你、真機一碰就爆」的雷。集中記錄，每一條都是實際踩過的。\n\n## 輸入框字級 \u003C 16px，iOS 自動放大頁面\n\nSafari 的「貼心」：聚焦到字級小於 16px 的輸入框，整頁自動 zoom in 幫你看清楚——然後不會自動 zoom 回去。版面精心調的 13px 輸入框，一點就把整個佈局炸飛。解法是觸控裝置上輸入框字級一律 ≥16px，視覺大小用其他手段收。注意 iPad 也要包含在判斷裡——用 `pointer: coarse` 而不是寬度斷點，橫向的 iPad 寬過任何手機斷點。\n\n## Modal 的 auto-focus 在 iPad 上彈鍵盤\n\nUI 庫的 modal\u002Fdrawer 預設打開時聚焦第一個輸入框——桌機上是貼心，iPad 上是災難：**虛擬鍵盤立刻升起，蓋掉半個畫面**。全站的彈窗都要顯式關掉 auto-focus，而且這是「每個新彈窗都要記得」的慣例，值得寫進團隊清單。\n\n## 下拉刷新：passive 事件的陷阱\n\n自製下拉刷新需要在往下拉時 `preventDefault()` 擋住瀏覽器的原生行為（橡皮筋、原生刷新）。但現代瀏覽器的 touch listener **預設 passive**——preventDefault 無效還噴警告。要顯式 `{ passive: false }`，而且只在「確實要接管」的條件下才擋，否則整頁捲動手感全毀。同族的還有 [[ios-svg-touch|SVG 子元素的 touch-action 失效]]。\n\n## 100vh 不是你以為的 100vh\n\n行動瀏覽器的工具列會伸縮，`100vh` 算的是工具列**收起時**的高度——展開時你的「滿版」元素底部被吃掉一截。`100dvh` 是正解但別全信，關鍵版面（圖譜這種要精確的）掛載後用 JS 實測，CSS 只當 fallback。\n\n共同教訓只有一句：**RWD 的最後一哩不在 DevTools 的裝置模擬器裡，在真機的手指下**。","把整個站在手機與 iPad 上收尾的過程，攢下一小把「文件上不會告訴你、真機一碰就爆」的雷。集中記錄，每一條都是實際踩過的。 輸入框字級 \u003C 16px，iOS 自動放大頁面 Safari 的「貼心」：聚焦到字級小於 16px 的輸入框，整頁自動 zoom in 幫你看清楚——然後不會自動 zoom 回去。版面精心調的 …",[9,10,11],"踩雷","前端","ios","budding",null,"2026-07-14T06:54:43.219Z","2026-07-14T11:26:40.346Z",true,{"ios-svg-touch":18},"iPad 上拖不動的圖譜節點：touch-action 對 SVG 子元素無效",[],"AI助理"]