DEV Community

Leo
Leo

Posted on Originally published at news.html.to

Safari 27.1 previews CSS for foldable screens

I don't have a foldable phone on my desk, so this one started with WebKit's code samples pasted into a scratch stylesheet. The news: Safari 27.1 ships alongside the iPhone Duo, running what WebKit calls "the same WebKit engine and the same web technologies as every other iPhone." It also includes a preview of two APIs for foldable layouts, the Device Posture API and the Viewport Segments API. Both sit behind feature flags. WebKit's post doesn't mention other browsers, a spec stage or Baseline status, so treat this as a developer preview and nothing more.

Two new questions your CSS can ask

The iPhone Duo has an outer display for when it's closed and a larger inner display for when it's open. Both rotate between portrait and landscape. Per WebKit, that puts viewport widths anywhere from 382 to 951 CSS pixels and heights from 368 to 902.

Width and height can't tell you there's a fold running through the screen. The two previews can.

The Device Posture API tells you how the device is being held. It reports one of two values. folded means the device is partially folded, in a book or laptop pose. continuous means the screen is flat, which per WebKit covers both fully open and fully closed.

The Viewport Segments API tells you how the viewport is split. It adds the horizontal-viewport-segments and vertical-viewport-segments media queries, plus six environment variables: viewport-segment-width, viewport-segment-height, viewport-segment-top, viewport-segment-right, viewport-segment-bottom and viewport-segment-left.

Wiring up a two-pane layout

The smallest useful rule comes straight from WebKit's post. Go to two columns when the device is folded:

@media (device-posture: folded) {
  .layout {
    display: grid;
    grid-template-columns: 1fr 1fr;
  }
}
Enter fullscreen mode Exit fullscreen mode

That works, but 1fr 1fr is a guess about where the fold sits. The segment variables let the grid match the physical halves. Each env() call takes a column index and a row index, counted from 0 at the top left. With two segments side by side, the left one is 0 0 and the right one is 1 0. Stacked, the top is 0 0 and the bottom is 0 1.

horizontal-viewport-segments: 2 matches the book pose, with two segments side by side. vertical-viewport-segments: 2 matches the laptop pose, with two stacked. Here's WebKit's book-pose grid:

@media (horizontal-viewport-segments: 2) {
  .wrapper {
    display: grid;
    grid-template-columns:
      env(viewport-segment-width 0 0)
      env(viewport-segment-width 1 0);
  }
}
Enter fullscreen mode Exit fullscreen mode

On the script side, navigator.devicePosture.type gives you the current posture and fires a change event. window.viewport.segments is an array of DOMRect objects. WebKit's sample logs each segment's size and runs again on both posture changes and resize:

function reportSegments() {
  window.viewport.segments.forEach((segment, i) => {
    console.log(`Segment ${i}: ${segment.width}px × ${segment.height}px`);
  });
}

reportSegments();
navigator.devicePosture.addEventListener("change", reportSegments);
window.addEventListener("resize", reportSegments);
Enter fullscreen mode Exit fullscreen mode

The rough edges

The flags come first. To try any of this, open Settings > Apps > Safari > Advanced > Feature Flags and turn both APIs on. Your visitors won't have done that. WebKit also says, with both APIs behind flags, "there may still be time to evolve how they work." I wouldn't build a layout that depends on these exact names yet.

Second, don't sniff for the device. WebKit puts it bluntly: "Avoid UA sniffing to detect devices, and use feature detection instead." The post points to the usual responsive toolkit of media queries, Grid and Flexbox. The rules above already behave that way. Where the query doesn't match, the page keeps its normal layout.

Third, continuous covers both the open inner display and the closed outer one. Posture alone won't tell those two apart. Your existing width-based queries still have to handle that.

Support today

Safari 27.1 on the iPhone Duo, behind flags. That's the full list as far as WebKit's post goes. It names no other engine, no standards status and no Baseline status. If you don't have the hardware, WebKit says Xcode 27.1 or later includes Device Hub, where you can create an iPhone Duo simulator. One detail outside CSS: when the device is partially folded like a book, Safari 27.1 shows PDFs as two pages side by side.

What I'm watching next

Whether the names hold. WebKit has said these APIs can still change while they're flagged. In the next Safari release notes, the first thing I'll check is whether device-posture and the viewport-segment-* variables come out from behind the flag unchanged. Until then, your plain responsive layout is the one that ships.

Top comments (0)