CSS media screen-spanning feature for dual-screen detection

Important

This article describes functionality and guidance that is in public preview and may be substantially modified before it's generally available. Microsoft makes no warranties, express or implied, with respect to the information provided here.

The spanning CSS media feature can be used to test whether the output device is a dual-screen (or foldable) and the browser viewport is spanned across the two display regions.

Screen-spanning values

CSS syntax to declare styles for when the browser is spanned is:

@media (screen-spanning: <value>) { }

The allowed values are:

single-fold-vertical

Describes the state of when the browser viewport is spanning across a single fold (two display regions) and the fold posture is vertical. This value matches Surface Duo in double-portrait (wide) mode.

single-fold-horizontal

Describes the state of when the browser viewport is spanning across a single fold (two display regions) and the fold posture is horizontal. This value matches Surface Duo in double-portrait (tall) mode.

This example CSS snippet shows how to use the screen-spanning media feature:

@media (screen-spanning: single-fold-vertical) {
   /* styles applied in double-portrait (wide) mode */
   /* matches Figure 1. below */
}
@media (screen-spanning: single-fold-horizontal) {
   /* styles applied in double-landscape (tall) mode */
   /* matches Figure 2. below */
}

Surface Duo's two orientations, double portrait and double landscape

CSS environment variables

Web developers can utilize browser-defined environment variables to get the geometry of the device fold (hinge, mask area), therefore calculate the geometry of the 2 display regions.

CSS env variables on a dual-screen device in double portrait mode

env(fold-top);
env(fold-left);
env(fold-width);
env(fold-height);

Two additional variables - fold-bottom and fold-right - will be available in a future release. You can calculate these using the available values (depending on the orientation of the device):

/*single-fold-vertical*/
calc(env(fold-left) + env(fold-width)) /* fold-right */
env(fold-height) /* equivalent to fold-bottom */

/*single-fold-horizontal*/
env(fold-width) /* equivalent to fold-right */
calc(env(fold-top) + env(fold-width)) /* fold-bottom */

Examples

Basic

Create a responsive page where the <body> background-color is set to yellow on phones and green on dual-screen devices in any posture.

Illustration of the basic example output

/* maximum width of our customers phones is 420px */
/* spanning: none is optional in this case */
@media (max-width: 420px) {
   body {
      background-color: yellow;
   }
}

/* Separating media features with comma `,` is equivalent to the logical operation OR  */
@media (screen-spanning: single-fold-vertical), (screen-spanning: single-fold-horizontal) {
   body {
      background-color: green;
   }
}

Flexbox

Use flexbox to create a gap-aware two column layout where the first column contains a scrollable description and the second column contains the image.

Dual-screen CSS demo

The HTML and CSS to create this layout is shown below:

   <body>
      <article class="article">
         ...
      </article>
      <figure class="figure">
         <img src="/sydney-opera-house.jpg"
               alt="Sydney Opera House">
      </figure>
   </body>
body {
   height: 100vh;
   display: flex;
}

.article {
   /* grow: no, shrink: no, basis: fold-left */
   flex: 0 0 env(fold-left);

   /* equals to margin-right when writing mode is left-to-right (english)  */
   /* equals to margin-left when writing mode is right-to-left (arabic, hebrew)  */
   /* this will prevent content from being rendered behind the device mask */
   margin-inline-end: env(fold-width);

   overflow-y: scroll;
}

.figure {
   /* fill the rest of the space */
   flex: 1;

   margin: 0;
   overflow: hidden;
}

.figure img {
   height: 100%;
}