The original address: blogs.windows.com/msedgedev/2…

The original author: blogs.windows.com/msedgedev/a…

Release date: September 4, 2020

The browser is one of the most used applications on any device, and today it runs on a whole new category of hardware: dual-screen and foldable devices.

With a variety of new dual-screen and foldable devices entering the market, including the new Surface Duo, which launched last week, now’s a good time to start thinking about how your website embraces these form factors.

Today, we’re excited to announce two new experimental features that will help web developers effectively lay out content in browser Windows across multiple display areas and create responsive websites that naturally fit this new category of devices.

  • CSS cross-screen media features and a set of environment variables to describe the geometry of the fold.
  • The JavaScript window segment enumeration API, a companion API for CSS primitives, is useful when working with non-DOM targets such as Canvas2d and WebGL.

Read this next.

Collapsible device class

Broadly speaking, foldable devices come in two variants: dual-screen devices and single-screen devices that utilize flexible display technology. Both have a lot in common: They’re portable, multi-pose devices that allow users to rotate, flip, and fold.

In this shape, applications can reside on one side or across two display areas. Responding to this cross-state web site is combined with the semantics and intent of the logically segmented presentation of the content.

The vast screen real estate and unique gestures that come with this category of devices enable web developers to unleash unprecedented web experiences in a device that can be carried in a pocket or wallet.

Transition from traditional continuous screens to dual screens and foldable devices

While existing websites will continue to work out of the box, making websites aware of the device’s foldability can greatly enhance the user experience.

To better illustrate this opportunity, and to show how the newly created browser features work, we’ll take you through an example of enhancing an email client layout.

Displaying a list view of your inbox and the contents of your email side by side is a common pattern that works well for a wide viewing area. When the browser window spans two display areas on a dual-screen device, the overall viewport width is likely to be comparable to that on a traditional landscape tablet device.

Without modification, the email client will continue to work as before. However, if we could align the inbox and mail bar with the fold so that it stayed within the boundaries of a single display area, the experience would be vastly improved. This way, no area of content is cut or obscured by the device hinge or displayed in the folds of the flexible display.

To achieve the desired layout, we are introducing a new cross-screen media feature and a set of predefined environment variables that allow web developers to treat foldable devices as another responsive web design goal. Developers can now create layouts that fit each device category without rigid dependencies on specific hardware parameters. This flexibility improves scalability because it does not need to work repeatedly for each new device type.

Detection display area

CSS cross-screen media features will help Web developers test whether the root viewport is crossed across multiple adjacent display areas and provide configuration details for those adjacent display areas (such as stacked or side-by-side).

grammar

The cross-screen media feature is specified as a value that describes the number of folds (or hinges) of devices, as well as their posture. If the device is not a foldable device, the value is none. If it’s a foldable, it can have one of these two values.

  • Single-fold-vertical: Matches devices that have a Single fold (two display areas) and are folded vertically.
  • Single-fold-horizontal: Matches a device with a Single fold (two display areas) and a horizontal folding posture.

Calculates the geometry of the display area

It is not safe to assume that in the cross-screen state, folding always splits the viewport exactly in half. In addition, some window administrators may choose to block collapsed web content. To help web developers calculate the size of each display area and make sure they know how much, if any, their content needs to be filled to avoid blocking, we’re adding four predefined CSS environment variables.

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

The values of these variables are represented in CSS pixels relative to the layout viewport (that is, in client coordinates, as defined by the CSSOM view). When evaluated in content that is not in one of the span states, these values are treated as nonexistent and the browser uses the fallback values passed to env().

Enhance our email sample application for a dual screen and foldable experience

A side-by-side example shows a mail application where the content is obscured by a hinge gap, and a layout that takes into account the hinge gap lets us put CSS’s cross-screen media capabilities and folding geometry environment variables into practice, enhancing the reader view of our mail client.

@media screen and (min-width: 799px) {
    /* rules specific to screens that are wider than tablet */
}

@media screen and (min-width: 799px) and (screen-spanning: single-fold-vertical) {
    /* main is an element wrapping the 3 flex items highlighted in the figure above */
    main {
        display: flex;
        flex-direction: row;
    }
    .navigation {
        /* ** flex direction is row, so flex-basis acts like this flex item width ** according to the design, the desired width on foldables / dual-screens is 60px */
        flex-basis: 60px;

        flex-grow: 0;
        flex-shrink: 0;
    }

    .inbox {
        /* ** inbox width consumes the entire width of the first display region, ex ** inbox width = display-region-1-width - 60px (navigation column width) */
        flex-basis: calc( env(fold-left) - 60px );
        
        /* ** some devices have a mask, so we need to add a margin or a gap after this column ** env(fold-width) = 28 CSS-pixels on surface Duo. ** env(fold-width) = 0 CSS-pixels on devices that does not mask content. */
        margin-inline-end: env(fold-width);
        
        flex-grow: 0;
        flex-shrink: 0;
    }

    .email-content {
        /* ** the email content column should "grow" to fill the rest of the space ** but to demonstrate how to calculate the width of the 2nd display region ** we will manually set the width */
        flex-basis: calc( 100vw - (env(fold-left) + env(fold-width)) );

        flex-grow: 0;
        flex-shrink: 0; }}Copy the code

Enumerates window segments in JavaScript

When using non-DOM targets such as Canvas2d or WebGL, you can use the new Window Segments Enumeration API to get the geometry of each display region.

GetWindowSegments () is a method of the Window object that returns an array of one or more DOMRects representing the geometry and location of each display region.

The array returned is an immutable snapshot that shows the state of the region when the method is called. If the user transitions from a span state to a non-span state, or rotates the device, the previously retrieved window segment is invalidated.

const segments = window.getWindowSegments();

// case 1: desktops, traditional touch screen devices, foldable device not spanned
console.log(segments.length) / / 1

// case 2: dual-screen and foldable 
console.log(segments.length) / / 2
Copy the code

The page should listen for window resizing events or reorientation events to detect whether the browser has been resized or the device has been rotated, and to retrieve updated display areas.

let segments = window.getWindowSegments();

// state 1: browser is spanned across 2 displays and fold is vertical.
console.log(segments.length); / / 2

// state 2: user decided to rotate the device, browser is still spanned but fold is now *horizontal*
// on window resize, both resize and orientationchange events fire
// resize events will also fire when user go in or out of spanned state.
window.addEventListener('resize'.() = > {
    // segments we initially retrieved are no longer
    // update with latest information representing segments the 2 when the fold is horizontal
    segments = window.getWindowSegments();
});
Copy the code

There is no clear way to know whether the folding position is vertical or horizontal, as this information can be easily calculated from the returned DOMRects.

function isSingleFoldHorizontal() {
    const segments = window.getWindowSegments();

    // single fold means the device has 1 fold and 2 display regions
    if( segments.length ! = =2 ) {
        return false;
    }

    // horizontal fold means 1st segment top is smaller than 2nd segment top
    if( segments[0].top < segments[1].top ) {
        return true;
    }

    // if we reach this point, the fold is vertical
    return false;
}
Copy the code

The same is true of fold widths. Web developers can use information provided by getWindowSegments() to find out whether the window manager is masking the folded content and whether the fold width is larger than zero pixels.

function foldWidth() {
    const segments = window.getWindowSegments();

    // if there's 1 segment, fold mask is not applicable, return 0
    // if there's more than 2 segments, we don't deal with this kind of device, yet, return 0
    if( segments.length ! = =2 ) {
        return 0;
    }

    // fold is vertical
    // device looks like this: [][]
    if( segments[0].top === segments[1].top ) {
        return segments[1].left - segments[0].right;
    }

    // if we reach this point, the fold is horizontal
    return segments[1].top - segments[0].bottom;
}
Copy the code

For the future

As developers, we tend to plan for the future when we build for today, so minimal refactoring is required to unlock scenarios that might be possible in the future.

An imaginary device with 2 folds and 3 screens

Unlike CSS, JavaScript has the concepts of arrays, loops, and conditions, which makes the mapping between the Window Segments Enumeration API and a device with N display regions more straightforward. For the hypothetical device above, calling the getWindowSegments() method returns an array of three DOMRects when the browser spans all three display segments. Using simple language primitives such as looping or built-in array methods, you can learn more about how display segments are configured (for example, Are all screens the same width, etc.

In CSS, the current plan is simply to add new values to the cross-screen media functionality that represents the new screen topology.

Start enhancing your site’s foldable experience today

CSS cross-screen media features and window segment enumerations APIS are available behind an experimental flag, and you can enable them at edge://flags/#enable-experimental-web-platform-features.

Starting with the Microsoft Edge 86, Web developers can use Microsoft Edge DevTools to simulate dual-screen and foldable devices on Windows and Mac desktop platforms. Alternatively, you can download and install the new Surface Duo simulator preview (2020.806.1 or later) and test and debug with the built-in Edge browser after enabling the experimental platform feature mark.

Both the JavaScript window enumeration API and CSS cross-screen media capabilities are available as Origin trials, and you can get tokens to safely experiment with these new primitives in production in exchange for providing us feedback on the API. If you’re interested in testing these apis, sign up for the Origin trial.

The road to the future

Thanks to the Chromium Project, Google, Intel, W3C’s CSSWG, Second-screen WG and many others, these apis are available for you to experiment with today after many iterations and improvements.

We’ve already contributed CSS and JavaScript primitives for the desktop platform to the Chromium open source project, and now DevTools’s foldable and dual-screen device emulation is available not only in Edge, but also in Chrome, and soon in other Chromium-based browsers. We’re currently working to push the Android implementation upstream so that all chromium-based browsers on Android can support web developers to provide exciting new experiences for this flexible device category.

If you have feedback on any of these apis, please let us know by Posting a question on GitHub, or you can contact us on Twitter (@_Zouhir or @msedgedev).

  • Zouhir Chahoud, Project Manager
  • Daniel Libby, Principal Software Engineering Manager

www.deepl.com translation