{"id":431,"date":"2020-06-11T14:11:34","date_gmt":"2020-06-11T21:11:34","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/surface-duo\/?p=431"},"modified":"2021-06-07T08:22:29","modified_gmt":"2021-06-07T15:22:29","slug":"dual-screen-web-experiences-preview","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/surface-duo\/dual-screen-web-experiences-preview\/","title":{"rendered":"Dual-screen web experiences preview"},"content":{"rendered":"<p>\nIn previous posts, we\u2019ve talked about building Android apps for Microsoft Surface Duo using <a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/introducing-dual-screen-layouts-android\/\">Kotlin &amp; Java<\/a>, <a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/bring-your-xamarin-apps-to-surface-duo\/\">C# with Xamarin<\/a>, <a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/build-react-native-apps-for-microsoft-surface-duo\/\">React Native<\/a>, <a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/dual-screen-games-with-unity-for-android\/\">Unity<\/a>, and <a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/get-started-with-flutter-on-surface-duo\/\">Flutter<\/a>. Microsoft is also working hard to bring new capabilities to the web so that websites and embedded web experiences can also adapt to the Surface Duo and other dual-screen devices.\n<\/p>\n<h2>Proposals: CSS primitives and window segments<\/h2>\n<p>\n  There are currently two proposals being considered:\n<\/p>\n<ul>\n<li><a href=\"https:\/\/github.com\/MicrosoftEdge\/MSEdgeExplainers\/blob\/master\/Foldables\/explainer.md\">CSS primitives explainer<\/a>\n  <\/li>\n<li><a href=\"https:\/\/github.com\/webscreens\/window-segments\/blob\/master\/EXPLAINER.md\">Window segments explainer<\/a>\n  <\/li>\n<\/ul>\n<p>\n  Today\u2019s post shows how these features might work and explains how you can test them today to provide feedback and plan for future dual-screen web experiences.\n<\/p>\n<p><strong>Please note that the proposed APIs are a work-in-progress and subject to change at any time.<\/strong>\n<\/p>\n<blockquote><p><b>UPDATE:<\/b> The CSS examples below were updated on 7th June, 2021 from <code>spanning<\/code> to <code>screen-spanning<\/code> to reflect changes in the standards proposal. References to <code>fold-right<\/code>,\u00a0<code>fold-bottom<\/code> environment variables were removed. The <a href=\"https:\/\/docs.microsoft.com\/dual-screen\/web\/css-media-spanning\/\">dual-screen CSS documentation<\/a> is up-to-date.<\/p><\/blockquote>\n<h3>CSS primitives<\/h3>\n<p>\n  The proposed media additions would look like this in a CSS file:\n<\/p>\n<pre>@media (screen-spanning: none) {\t\r\n   \/\/ styles when browser is not spanned\r\n}\r\n@media (screen-spanning: single-fold-vertical) {\t\r\n   \/\/ styles applied in double-portrait (wide) mode\r\n}\r\n@media (screen-spanning: single-fold-horizontal) {\t\r\n   \/\/ styles applied in double-landscape (tall) mode\r\n}<\/pre>\n<p>\n  The styles contained in each spanning clause would be applied, depending on the web browser\u2019s screen position, and would automatically be updated as the device is rotated or the web browser is spanned or unspanned.\n<\/p>\n<p>\n  The proposal also includes predefined CSS environment variables such as fold-top,\u00a0fold-left,\u00a0fold-width, and\u00a0fold-height, which can be used to reason about the size of each screen segment.\n<\/p>\n<h3>Window segments<\/h3>\n<p>\n  The window segments proposal adds a <strong>getWindowSegments<\/strong> method that returns the number of \u201cpanes\u201d available for rendering. By default, it will return one element, but if there are multiple elements in the array, the web browser is spanned across two screens and you query the dimensions of each. An example JavaScript usage is shown here:\n<\/p>\n<pre>const screenSegments = window.getWindowSegments();\r\nif (screenSegments.length > 1 ) {\r\n   \/\/ now we know the device is a foldable\r\n   \/\/ it's recommended to test whether screenSegments[0].width === screenSegments[1].width\r\n   \/\/ and we can update CSS classes in our layout as appropriate \r\n   document.body.classList.add('is-foldable');\r\n   \/\/ other changes as required for layout\r\n}<\/pre>\n<p>\n  Note that these proposals are still being discussed and can be explored further in <a href=\"https:\/\/github.com\/MicrosoftEdge\/MSEdgeExplainers\/issues\/235\">this issue for the spanning media feature<\/a>. The links and samples provided below are available to experiment with and provide feedback on.<strong> <\/strong>\n<\/p>\n<h2>Testing in a browser<\/h2>\n<p>\n  While the proposals work their way through the standards process, it is possible to test an implementation of these ideas using the <a href=\"https:\/\/github.com\/foldable-devices\/spanning-css-polyfill\">spanning-css-polyfill<\/a> and <a href=\"https:\/\/github.com\/foldable-devices\/windowsegments-polyfill\">windowsegments-polyfill<\/a>. There is a <a href=\"https:\/\/foldable-devices.github.io\/demos\/photo-gallery\/\">photo-gallery example<\/a> with a panel that simulates dual-screen devices in any modern browser. Click the left-most icon to enable a dual-screen experience in the browser:\n<\/p>\n<p>\n  <img decoding=\"async\" width=\"305\" height=\"107\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/word-image-4.png\" class=\"wp-image-436\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/word-image-4.png 305w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/word-image-4-300x105.png 300w\" sizes=\"(max-width: 305px) 100vw, 305px\" \/>\n<\/p>\n<p>\n  Figure 1: foldable configurator for testing\n<\/p>\n<p>\n  Click the third icon to expand the configurator and preview a Surface Duo-specific experience:\n<\/p>\n<p>\n  <img decoding=\"async\" width=\"704\" height=\"673\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/word-image-6.png\" class=\"wp-image-438\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/word-image-6.png 704w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/word-image-6-300x287.png 300w\" sizes=\"(max-width: 704px) 100vw, 704px\" \/>\n<\/p>\n<p>\n  Figure 2: simulating the Surface Duo web experience\n<\/p>\n<p>\n  You can also use the polyfills with your own website. Follow these <a href=\"https:\/\/github.com\/foldable-devices\/device-configurator\">instructions to add the configurator for testing<\/a>, and keep in mind these proposal may change in the future.\n<\/p>\n<h2>Testing with the WebView <\/h2>\n<p>\n  Android app developers can use the polyfill implementations in HTML that is hosted in an Android application WebView. Instead of the configurator shown above, you can use Java or Kotlin to detect the application state and directly set the spanning behavior for the WebView, thereby simulating browser support.\n<\/p>\n<p>\n  Two samples using this technical implementation can be found on <a href=\"https:\/\/github.com\/conceptdev\/java-samples\">GitHub<\/a>. The code shown below interacts with the WebView to control the CSS behavior (it relies on our Surface Duo SDK ScreenHelper class to respond to spanning and rotation):\n<\/p>\n<pre>private void UpdateSpanning()\r\n{\r\n    int rotation = ScreenHelper.getRotation(this);\r\n    String spanning = \"none\";\r\n    int foldSize = 0;\r\n    if (isDuo && screenHelper.isDualMode()) {\r\n        Rect hinge = screenHelper.getHinge(rotation);\r\n        switch (rotation) {\r\n            case Surface.ROTATION_90:\r\n            case Surface.ROTATION_270:\r\n                foldSize = (int) (hinge.height() \/ 2.5); \/\/ height is returned in pixels, CSS wants in dp\r\n                spanning = \"single-fold-horizontal\";\r\n                break;\r\n            default:\r\n                foldSize = (int) (hinge.width() \/ 2.5); \/\/ height is returned in pixels, CSS wants in dp\r\n                spanning = \"single-fold-vertical\";\r\n                break;\r\n        }\r\n    }\r\n    webView.evaluateJavascript(String.format(\"(window[\\\"__foldables_env_vars__\\\"]).update({spanning: '%1$s', foldSize: %2$s})\", spanning, foldSize), null);\r\n}<\/pre>\n<h3>Example: floating boxes<\/h3>\n<p>\n  The <a href=\"https:\/\/github.com\/conceptdev\/java-samples\/tree\/master\/DualScreenWebViewDemo\">first example<\/a> consists of four boxes shown in this HTML snippet:\n<\/p>\n<pre>&lt;div class=\"content\">\r\n    &lt;div class=\"blue\">1&lt;\/div>\r\n    &lt;div class=\"yellow\">2&lt;\/div>\r\n    &lt;div class=\"pink\">3&lt;\/div>\r\n    &lt;div class=\"green\">4&lt;\/div>\r\n    &lt;div class=\"fold angled stripes\">&lt;\/div>\r\n&lt;\/div><\/pre>\n<p>\n  An excerpt of the CSS shows that by default each div style is given a height, width, and color, but no other layout information. The <strong>@media spanning<\/strong> styles are only applied when the app is spanned:\n<\/p>\n<pre>.green {\r\n    height: 100px;\r\n    width: 100px;\r\n    background-color: green;\r\n    text-align: center;\r\n}\r\n@media (spanning: single-fold-vertical) {\r\n   .green {\r\n       position: absolute;\r\n       left: calc(env(fold-left) + env(fold-width));\r\n       bottom: 0;\r\n       background-color: green;\r\n   }\r\n}<\/pre>\n<p>\n  This behavior is demonstrated in the following screenshots \u2013 on a single screen the boxes are rendered in the order they are declared, but when the app is spanned (and the Java code sets the correct spanning value), the boxes are absolute positioned according to the <strong>@media<\/strong> styles:\n<\/p>\n<p>\n  <img decoding=\"async\" width=\"1026\" height=\"708\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/word-image-7.png\" class=\"wp-image-439\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/word-image-7.png 1026w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/word-image-7-300x207.png 300w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/word-image-7-1024x707.png 1024w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/word-image-7-768x530.png 768w\" sizes=\"(max-width: 1026px) 100vw, 1026px\" \/>\n<\/p>\n<p>\n  Figure 3: Single-screen HTML with no position style applied\n<\/p>\n<p>\n  <img decoding=\"async\" width=\"600\" height=\"414\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/word-image-8.png\" class=\"wp-image-440\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/word-image-8.png 600w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/word-image-8-300x207.png 300w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/>\n<\/p>\n<p>\n  Figure 4: Spanned app with single-fold-vertical media spanning styles applied\n<\/p>\n<h3>Example: reading experience<\/h3>\n<p>\n  The <a href=\"https:\/\/github.com\/conceptdev\/java-samples\/tree\/master\/DualScreenWebViewSample\">second example<\/a> provides a reading experience implemented for dual-screens. In double-portrait mode, a book-like reading experience is available, but in double-landscape mode, the article scrolls vertically (the same experience as a single-screen device):\n<\/p>\n<p>\n  <img decoding=\"async\" width=\"1299\" height=\"629\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/word-image-9.png\" class=\"wp-image-441\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/word-image-9.png 1299w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/word-image-9-300x145.png 300w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/word-image-9-1024x496.png 1024w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/word-image-9-768x372.png 768w\" sizes=\"(max-width: 1299px) 100vw, 1299px\" \/>\n<\/p>\n<p>\n  Figure 5: double-portrait and double-landscape reading experience\n<\/p>\n<h2>Feedback<\/h2>\n<p>\n  I hope these examples inspire you to test out the dual-screen proposals and start to imagine how web-based dual-screen experiences could be applied to your online apps. Keep an eye on the proposals and the <a href=\"https:\/\/docs.microsoft.com\/dual-screen\/web\/\">dual-screen web experiences documentation<\/a> for the latest updates. \n<\/p>\n<p>\n  Remember these APIs are still a work-in-progress.\n<\/p>\n<p>\n  We\u2019d love to hear from you! Please leave us feedback using our <a href=\"http:\/\/aka.ms\/SurfaceDuoSDK-Feedback\">feedback forum<\/a>, or message me on <a href=\"https:\/\/twitter.com\/conceptdev\">Twitter<\/a> or <a href=\"https:\/\/github.com\/conceptdev\">GitHub<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In previous posts, we\u2019ve talked about building Android apps for Microsoft Surface Duo using Kotlin &amp; Java, C# with Xamarin, React Native, Unity, and Flutter. Microsoft is also working hard to bring new capabilities to the web so that websites and embedded web experiences can also adapt to the Surface Duo and other dual-screen devices. [&hellip;]<\/p>\n","protected":false},"author":570,"featured_media":447,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[531,412,46,45,530],"class_list":["post-431","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-surface-duo-sdk","tag-css","tag-javascript","tag-surface-duo","tag-surface-duo-sdk","tag-web"],"acf":[],"blog_post_summary":"<p>In previous posts, we\u2019ve talked about building Android apps for Microsoft Surface Duo using Kotlin &amp; Java, C# with Xamarin, React Native, Unity, and Flutter. Microsoft is also working hard to bring new capabilities to the web so that websites and embedded web experiences can also adapt to the Surface Duo and other dual-screen devices. [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/posts\/431","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/users\/570"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/comments?post=431"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/posts\/431\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/media\/447"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/media?parent=431"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/categories?post=431"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/tags?post=431"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}