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:
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
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.
/* 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.
.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:
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.
// 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:
@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:
@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.
/* 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.
// 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
- Confirm
viewport-fit=coveris present grep -rn "safe-area-inset"and split every shorthand into left and right- Replace user-agent layout branching with media and container queries
- Swap
100vhfor100dvh - Replace cached
window.innerWidthwithResizeObserver - Test the Split View divider through its full range
- 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.