Skip to content

Two columns are not displayed on the iPhone Duo unfolded in landscape #247

Open

Description

@mickael-menu

Describe the bug

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?

  1. Open any reflowable EPUB in a paginated reading app that uses Readium CSS v1 (e.g. the Readium Swift toolkit Test App).
  2. Unfold the iPhone Duo and rotate to landscape.
  3. Keep the default column count (auto) and font size.
  4. 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:

@media screen and (min-width: 59.375em) and (orientation: landscape), screen and (horizontal-viewport-segments: 2) {
  • The query no longer uses device-width or device-height.
  • The threshold drops from 960px to 950px (59.375em), so the Duo's 951px viewport matches.
  • Two columns now require landscape. As a side effect, a 13" iPad in portrait (1032px wide) gets one column instead of two.
  • A horizontal-viewport-segments: 2 arm handles the half-folded posture.

Something to decide before merging:

  • Is the iPad portrait change acceptable, or should portrait keep two columns above some larger width?

Activity

  1. added theissue type on Sep 25, 2026
  2. JayPanoz commented on Sep 28, 2026

    @JayPanoz
    Collaborator

    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.

    Will dig a little deeper and report.

  3. HadrienGardeur commented on Sep 28, 2026

    @HadrienGardeur
    Member

    Is the iPad portrait change acceptable, or should portrait keep two columns above some larger width?

    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.

  4. erkamyaman commented on Oct 9, 2026

    @erkamyaman

    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.

    Measurements and useful info from building this on the 27.1 simulator: https://github.com/erkamyaman/capacitor-foldable/blob/main/docs/iphone-duo.md

  5. JayPanoz commented on Oct 9, 2026

    @JayPanoz
    Collaborator

    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 800 should be fine, and the height is there to filter other smartphones in landscape.

  6. mickael-menu commented on Oct 9, 2026

    @mickael-menu
    MemberAuthor

    I created a new PR for the Swift toolkit:

    @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.

  7. erkamyaman commented on Oct 9, 2026

    @erkamyaman

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions