You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Two columns are not displayed on the iPhone Duo unfolded in landscape #247
On the iPhone Duo unfolded in landscape, Readium CSS v1 shows a single column across the full width, even if two columns are forced. We expect two columns, as on an iPad in landscape.
Viewport dimensions measured on the device:
viewport: 951×545 (inner display)
screen: 466×678 (cover display)
Since Readium CSS v2 no longer handles automatic columns with media queries, this would be a hotfix on top of the latest v1 version, for clients that can't migrate to v2 before the Duo ships.
How to reproduce?
Open any reflowable EPUB in a paginated reading app that uses Readium CSS v1 (e.g. the Readium Swift toolkit Test App).
Unfold the iPhone Duo and rotate to landscape.
Keep the default column count (auto) and font size.
The text is laid out in a single column across the viewport.
Readium CSS version
1.1.0
Platforms
iOS 27.1
Browsers
WebKit (WKWebView)
Additional context
The Swift toolkit has a proposed fix in readium/swift-toolkit#903. It swaps both media queries for a viewport-based one:
As a side effect, a 13" iPad in portrait (1032px wide) gets one column instead of two
There should be another side effect with iPhone Pro Max (956px) getting two columns in landscape if I’m not mistaken?
We could have something like this:
@media screen and (min-width: 58em),
screen and (min-device-width: 36em) and (max-device-width: 47em) and (orientation: landscape),
screen and (horizontal-viewport-segments: 2)
It protects iPad in theory, but not Pro Max and Plus models.
Or
@media screen and (min-width: 58em) and (min-height: 30em),
screen and (min-device-width: 36em) and (max-device-width: 47em) and (orientation: landscape),
screen and (horizontal-viewport-segments: 2)
That fixes it. But then on desktop, windows under 480px tall lose two columns.
@media screen and (min-width: 58em) and (max-aspect-ratio: 2/1),
screen and (min-device-width: 36em) and (max-device-width: 47em) and (orientation: landscape),
screen and (horizontal-viewport-segments: 2)
Aspect ratio makes the previous one a little less impactful to desktop – although, ultra wide screens will be.
If I remove the query on the column setting, it kinda gets around it, as then you could override and set 2 columns.
Careful with 951: that's your viewport after the app's chrome, not the display. The inner display is 951×669 points, so a client with a different toolbar lands elsewhere, and a future iPhone can collide with whatever window you pick, same trap as the Pro Max at 956.
The real signal is the fold. Viewport Segments and Device Posture answer this directly (two segments means two columns, no width guessing), but WebKit 27.1 keeps both behind a flag only Safari can set, so a WKWebView never gets them.
Since the Swift toolkit owns the web view, it can inject what the CSS can't read: reservedRegions(kind:options:) gives the fold rect in view coordinates on iOS 27.1. Include inactive regions, or an open-flat Duo looks like an ordinary phone. Put it on html as a class or custom property and v1 can key columns off the fold instead of a width.
@JayPanoz I confirmed that the fix works, after testing on a bunch of devices.
@erkamyaman Do you see an issue with your app's chrome with this version of the fix?
We're currently working on integrating Readium CSS v2 which moves the decision on auto columns to the app, so I don't think it's worth messing with reservedRegions(kind:options:) right now.
To be clear I'm not a Readium client, I measured the device while building a Capacitor plugin, so take this as arithmetic rather than field experience.
Against the numbers, your thresholds look safe. Inner display is 951×669pt, your 951×545 viewport implies ~124pt of chrome, and 30em bottoms out at 480, so there's roughly 190pt of vertical headroom before a client falls back to one column. Horizontally you have ~150. A client would need a toolbar plus a page slider plus a tab bar on the inner display to break it, which seems unlikely, and the failure is graceful anyway.
It also excludes the cases you wanted excluded: Pro Max landscape is too short for 30em, a folded Duo is too narrow for 50em, and iPad portrait is out by orientation.
Adding horizontal-viewport-segments: 2 is the right call. WebKit 27.1 keeps it behind a flag only Safari can set, so it does nothing in a WKWebView today, but it costs nothing and becomes the correct answer the moment that ships.
And agreed on reservedRegions, not worth it if v2 hands the decision to the app anyway.
Activity
JayPanoz commentedon Sep 28, 2026
There should be another side effect with iPhone Pro Max (956px) getting two columns in landscape if I’m not mistaken?
We could have something like this:
It protects iPad in theory, but not Pro Max and Plus models.
Or
That fixes it. But then on desktop, windows under 480px tall lose two columns.
Aspect ratio makes the previous one a little less impactful to desktop – although, ultra wide screens will be.
If I remove the query on the column setting, it kinda gets around it, as then you could override and set 2 columns.
Will dig a little deeper and report.
HadrienGardeur commentedon Sep 28, 2026
It's acceptable and might even be preferrable.
IMO, we shouldn't display two columns for any iPad model in portrait mode or for any iPhone (other than an opened Duo) in landscape mode.
Of course things will be different with Readium CSS v2 since this gives a lot more power in the hands of implementers.
erkamyaman commentedon Oct 9, 2026
Careful with 951: that's your viewport after the app's chrome, not the display. The inner display is 951×669 points, so a client with a different toolbar lands elsewhere, and a future iPhone can collide with whatever window you pick, same trap as the Pro Max at 956.
The real signal is the fold. Viewport Segments and Device Posture answer this directly (two segments means two columns, no width guessing), but WebKit 27.1 keeps both behind a flag only Safari can set, so a WKWebView never gets them.
Since the Swift toolkit owns the web view, it can inject what the CSS can't read:
reservedRegions(kind:options:)gives the fold rect in view coordinates on iOS 27.1. Include inactive regions, or an open-flat Duo looks like an ordinary phone. Put it onhtmlas a class or custom property and v1 can key columns off the fold instead of a width.Measurements and useful info from building this on the 27.1 simulator: https://github.com/erkamyaman/capacitor-foldable/blob/main/docs/iphone-duo.md
JayPanoz commentedon Oct 9, 2026
Thanks for the warning and the useful document!
That's what for testing right now in the maintenance branch of v1:
https://github.com/readium/css/blob/v1-maintenance/css%2FReadiumCSS-config.css#L16-L20
So
800should be fine, and the height is there to filter other smartphones in landscape.mickael-menu commentedon Oct 9, 2026
I created a new PR for the Swift toolkit:
develop: Fix two columns on the iPhone Duo unfolded in landscape swift-toolkit#919hotfix/3.11.1branch from the last stable release: https://github.com/readium/swift-toolkit/tree/hotfix/3.11.1@JayPanoz I confirmed that the fix works, after testing on a bunch of devices.
@erkamyaman Do you see an issue with your app's chrome with this version of the fix?
We're currently working on integrating Readium CSS v2 which moves the decision on auto columns to the app, so I don't think it's worth messing with
reservedRegions(kind:options:)right now.erkamyaman commentedon Oct 9, 2026
To be clear I'm not a Readium client, I measured the device while building a Capacitor plugin, so take this as arithmetic rather than field experience.
Against the numbers, your thresholds look safe. Inner display is 951×669pt, your 951×545 viewport implies ~124pt of chrome, and 30em bottoms out at 480, so there's roughly 190pt of vertical headroom before a client falls back to one column. Horizontally you have ~150. A client would need a toolbar plus a page slider plus a tab bar on the inner display to break it, which seems unlikely, and the failure is graceful anyway.
It also excludes the cases you wanted excluded: Pro Max landscape is too short for 30em, a folded Duo is too narrow for 50em, and iPad portrait is out by orientation.
Adding
horizontal-viewport-segments: 2is the right call. WebKit 27.1 keeps it behind a flag only Safari can set, so it does nothing in a WKWebView today, but it costs nothing and becomes the correct answer the moment that ships.And agreed on reservedRegions, not worth it if v2 hands the decision to the app anyway.