# Capacitor, Cordova and web views on iPhone Duo > Hybrid iOS apps adapt best to the foldable iPhone, because CSS was built for variable viewports. An analysis of the few things that still break. Source: https://iphoneduosupport.com/blog/capacitor-web-iphone-duo/ Published: 2026-09-09 Framework: capacitor Status: ENGINEERING ANALYSIS — this framework vendor has published no iPhone Duo guidance. Apple-side facts are sourced; framework-side conclusions are inference. Sources: https://developer.apple.com/videos/play/tech-talks/111461/ https://developer.apple.com/videos/play/tech-talks/111466/ Last verified: 2026-09-09 --- Ionic has published no iPhone Duo guidance. This is our analysis of how a `WKWebView`-based iOS app behaves against the APIs and behaviours Apple documented on 9 September 2026. Hybrid apps have the easiest migration of any cross-platform stack, for a reason that has nothing to do with iPhone Duo: the web has assumed a variable viewport since the beginning. A well-built responsive layout adapts to a 626-point display without changes, because it has always had to adapt to everything else. The failures are concentrated in a handful of places where web code borrowed a native assumption. ## Opt into the display Environment variables report nothing useful until the web view claims the full display: ```html ``` Without `viewport-fit=cover`, `env(safe-area-inset-*)` resolves to zero and your layout is inset by the system with no way to draw underneath. This one line is a prerequisite for everything below. ## The one real break: symmetric insets If you fix nothing else, fix this. ```css /* Wrong on iPhone Duo — one value applied to both edges */ .container { padding: 0 env(safe-area-inset-left); } ``` Apple states safe areas are **asymmetric** on this device. Applying the left inset to both sides over-pads one edge, and content drifts visibly off-centre on a display wide enough that people notice. ```css .container { padding-left: env(safe-area-inset-left); padding-right: env(safe-area-inset-right); } ``` The shorthand form was harmless for a decade because the two values were always equal. Search your stylesheets for it specifically — it is the single highest-yield grep in a hybrid codebase: ```bash grep -rn "safe-area-inset" src/ ``` ## User-agent sniffing serves the wrong layout Any code branching on a phone user agent to pick a mobile layout will serve that layout on a regular-width, 626-point display with room for a sidebar. ```js // Wrong — iPhone Duo is an iPhone with a tablet-sized inner display const isMobile = /iPhone/.test(navigator.userAgent); ``` Media and container queries describe the space you actually have: ```css @media (min-width: 600px) { .layout { display: grid; grid-template-columns: 260px 1fr; } } ``` Container queries are better still where a component's own width matters more than the window's — which is often the case in Split View, where the window is smaller than the display: ```css @container (min-width: 480px) { .card { flex-direction: row; } } ``` ## Viewport units `100vh` has always been awkward on mobile. On iPhone Duo it gets worse, because the viewport changes while the app runs — folding, unfolding, and Split View resizing all change it without a navigation. ```css /* Fragile */ .screen { height: 100vh; } /* Tracks the dynamic viewport */ .screen { height: 100dvh; } ``` `dvh`, `svh`, and `lvh` all behave sensibly here. `vh` does not. ## JavaScript that measured once CSS reflows on its own. JavaScript that captured a dimension does not. ```js // Wrong — captured once const width = window.innerWidth; // Right const observer = new ResizeObserver(([entry]) => { layout(entry.contentRect.width); }); observer.observe(document.body); ``` `window.visualViewport` and its `resize` event are the other reliable signal, particularly when the keyboard is involved. A `window.resize` listener works too, but `ResizeObserver` is cheaper and fires for container changes that `window.resize` misses. This matters more than usual on iPhone Duo because resizes are frequent and user-initiated rather than rare and orientation-driven. ## What Capacitor gives you, and what it does not Capacitor's status bar and keyboard plugins behave normally. Nothing in the standard plugin set needs changing for this device. What has no web API at all: - Reserved regions — where the hinge divides the display - Hinge angle - Scene accessories — content on the outer display - The vertical toolbar region A Capacitor plugin wrapping the Swift APIs is entirely possible, and reserved regions would be the one worth building: a plugin that reports division-region frames as CSS custom properties would let a web layout avoid the fold with a `grid-template-columns` rule. Nobody has shipped this that we are aware of. For a typical content app, none of that is needed. The CSS-level adaptation above is the whole job. ## Aspect ratio The inner display is roughly 1.42 — close to √2, the A-series paper proportion. This is unusually good for the kind of layout hybrid apps tend to have: documents, feeds, lists, forms, article views. Two-column reading layouts fit it naturally. Embedded 16:9 video letterboxes, as it does everywhere else on this device. The web idiom of a fixed-aspect embed with content beneath it is already the pattern Apple recommends for native, so most hybrid apps need no change here. ## A pragmatic checklist 1. Confirm `viewport-fit=cover` is present 2. `grep -rn "safe-area-inset"` and split every shorthand into left and right 3. Replace user-agent layout branching with media and container queries 4. Swap `100vh` for `100dvh` 5. Replace cached `window.innerWidth` with `ResizeObserver` 6. Test the Split View divider through its full range 7. Consider a native plugin only if your app draws a full-bleed surface where the fold matters Steps 1 and 2 take an afternoon and account for nearly all of the visible difference. --- Published by iPhone Duo Support (https://iphoneduosupport.com). Not affiliated with Apple Inc.