Building Web Layouts For Dual-Screen And Foldable Devices — Smashing Magazine

Quick abstract ↬

Dual-screen units have been available on the market for almost three years. In that point new web platform applied sciences have been constructed with developer suggestions to allow structure on the web that adapts to those units. These web platform capabilities combine with present ideas, such because the viewport and media queries, in order that builders and designers can spend extra time ideating about tips on how to leverage two shows to create enhanced experiences reasonably than studying a brand new set of code to construct them.

It’s now been greater than two years for the reason that Samsung Galaxy Fold and Surface Duo have been launched to the world. Since then, the Surface Duo 2, Samsung Galaxy Z Fold 3 and Galaxy Z Flip 3 have all hit the market. Foldable units can be found to buy, and are at present being utilized by customers at this time, and with it comes a chance the place we, as builders, can begin to discover this new class of machine and the following evolution in responsive design.

The APIs that have been initially designed to resolve for constructing layouts on dual-screen units have gone via some revisions after suggestions from builders who used the APIs in browser origin trials. The lovely factor about these APIs is that they combine with present ideas, so designers and builders don’t need to spend time studying new ideas, however can take into consideration tips on how to construct enhanced experiences for customers on dual-screen units.

Dual display screen and foldable units are simply the following step in responsive design, in order that they’re seen as one other responsive design goal that we will fashion for with media options. We already use media options and queries to focus on desktops, tablets, and cell phones at this time, and now we now have the CSS Viewport Segments media function to focus on our foldable and dual-screen units.

horizontal-viewport-segments

The viewport segments media question can have two values. The first one is horizontal-viewport-segments, and this represents the state of the machine when the machine hinge is vertical and the viewports are break up by the {hardware} hinge or fold into columns.

The horizonal-viewport-segment targets the machine when the hinge is within the vertical fold posture. (Large preview)

To serve kinds particularly for a foldable machine on this orientation we might write the next:

@media (horizontal-viewport-segments: 2) {
// Styles particular to the machine on this orientation
}

The integer represents the variety of viewports current within the machine orientation. When the machine is within the vertical fold posture like a e book, we now have two distinct viewports within the horizontal course and just one viewport within the vertical course.

We may mix our media queries to focus on twin display screen units and sure viewport widths to serve up particular kinds:

@media (horizontal-viewport-segments: 2) and (min-width: 540px) {
physique {
background: yellow;
}
}

vertical-viewport-segments

Our second worth for the viewport segments media function is vertical-viewport-segments, and that is the state of the machine when the machine hinge is horizontal, and the {hardware} hinge splits our viewports into rows.

A foldable device illustration with displays stacked on top of each other

The vertical-viewport-segments targets the machine within the horizontal fold posture. (Large preview)

To goal units which are rotated on this course we might use the next code:

@media (vertical-viewport-segments: 2) {
// Styles particular to the machine on this orientation
}

More after leap! Continue studying under ↓

Feature Panel

Using JavaScript To Detect Foldable Devices

There are situations the place you is probably not in a position or wish to use CSS media queries to detect whether or not your person is on a foldable machine, and that is the place the JavaScript API is available in. Initially, a brand-new API known as Windows Segments Enumeration was proposed, however after the suggestions from the developer neighborhood via origin trials, it made extra sense to construct off the prevailing Visual Viewport API draft specification.

Viewport Segments Property

Viewport segments signify the areas of the window that reside on separate shows which are adjoining to one another. To detect a dual-screen machine you’d question the segments property with the next code:

const segments = window.visibleViewport.segments;

The worth returned from this question can be an array of DOMRects that point out what number of viewports there are. If there is just one viewport phase, the question will return null, and is applied this strategy to forestall future compatibility points, in order that builders don’t begin utilizing visibleViewport.segments[0] to focus on single-screen units.

On dual-screen units, the question will return 2 DOMRects, representing the two viewports out there when the browser window is spanning throughout the fold.

This worth we now have saved within the segments fixed is an immutable snapshot of the machine state when the attribute was queried, and if the browser window is resized or the machine is rotated, the viewport segments beforehand retrieved are now not legitimate and should be queried once more via a resize or orientation occasion (or each).

If you resize the browser window to span throughout just one show area, we’ll fireplace the resize occasion.

If you rotate the machine, this may fireplace each the resize and orientation occasion, and you should use the occasions to question the attribute once more to get the present state of the browser show areas.

window.addEventListener(“resize”, operate() {
const segments = window.visibleViewport.segments;
console.log(segments.size); *// 1*
});

When To Use The JavaScript API vs The CSS Media Features To Detect Devices

Both the CSS media options and JavaScript phase property will detect a dual-screen machine, however the JavaScript property is greatest used when there’s no CSS getting used, which might occur if you’re working with objects in Canvas2D and WebGL. An instance could be a sport that you simply’re creating that would leverage each screens.

Using CSS env() Variables

In addition to the CSS media options, six new CSS atmosphere variables have been launched to assist builders calculate the geometry of the show areas, calculate the geometry of the hinge space when it’s being obscured by a bodily {hardware} function like on the Surface Duo, and so they can be used to assist place content material with the bounds of every show area.

The six new atmosphere variables are as follows:

  • env(viewport-segment-width );
  • env(viewport-segment-height );
  • env(viewport-segment-top );
  • env(viewport-segment-left );
  • env(viewport-segment-bottom );
  • env(viewport-segment-right );

The x and y positions signify the two-dimensional grid created by {hardware} options that separate every viewport phase, with the coordinates 0,0 beginning on the top-left phase.

The environment variables laid out on each display screen with the integers for each display

Environment variables outline the place and dimensions of a logically separate area of the viewport. (Large preview)

When you’ve a tool that’s within the vertical fold posture with the viewports aspect by aspect, the viewport phase on the left could be represented by env(viewport-segment-width 0 0), and the one on the fitting could be represented by env(viewport-segment-width 1 0). If you turned the machine into the horizontal fold posture with the viewports stacked, the highest could be represented by env(viewport-segment-height 0 0), and the underside viewport by env(viewport-segment-height 0 1).

When utilizing env(viewport-segment-width) and env(viewport-segment-width), along with the indices, we will set a fallback worth like the next:

env(viewport-segment-width 0 0, 100%);

But this extra fallback worth is elective and as much as the discretion of the writer, in the event that they’d like to incorporate it.

Calculate The Hinge Width

When you’ve a tool that has a hinge obscured by {hardware} options, you’re in a position to calculate it utilizing the atmosphere variables offered.

A foldable device in the horiztonal position

We can calculate the machine hinge with the atmosphere variables. (Large preview)

In our instance, we now have a tool within the vertical posture and wish to discover the hinge width, in order that no content material is obscured. We’ll subtract the left viewport phase of the fitting show from the fitting viewport phase of the left show:

calc(env(viewport-segment-left 1 0) – env(viewport-segment-right 0 0));

Placing Content With The CSS env() Variables

We can use the CSS atmosphere variables to position content material inside the show area boundaries, and these are particularly useful if you wish to place content material instantly in opposition to the hinge or fold.

In our instance under, we’re going to position a picture instantly in opposition to the hinge within the first show area on the left. This space is the fitting phase of the viewport, so we’ll use viewport-segment-right to position it with the next code:

img {
max-width: 400px;
}

@media (horizontal-viewport-segments: 2) {
img {
place: absolute;
left: env(viewport-segment-right 0 0);
}
}

If we emulate our display screen within the Edge Developer Tools in Surface Duo mode, we’ll get the next structure:

A Surface Duo emulated layout in the browser with an image on the right display and text on the left

Initially putting the picture in our structure with the atmosphere variable places it within the improper show area. (Large preview)

This isn’t what we needed. The picture needs to be within the show area on the left aspect.

Because the picture is completely positioned with the left property, the left fringe of the picture finally ends up aligned to the viewport-segment-right show space.

We then have to subtract the width of the picture from the environment variable to get the picture aligned to the right hinge edge:

img {
max-width: 400px;
}

@media (horizontal-viewport-segments: 2) {
img {
place: absolute;
left: calc(env(viewport-segment-right 0 0) – 400px);
}
}

A layout in the Surface Duo emulated in the browser with text and image both in the left display

Subtracting the picture width from the viewport phase will place it alongside the hinge within the left show. (Large preview)

And now we now have the picture positioned the place we wish it. For different examples on tips on how to align gadgets alongside the hinge, you may try this easy field demo. Open the Edge Developer Tools > Device Emulation after which select Surface Duo and guarantee your Duo emulation is within the correction orientation posture.

Putting It All Together: Let’s Build A Recipe Page That Adapts To A Dual Screen Device

As somebody who consistently makes use of her cellphone whereas cooking, a recipe web site that may adapt once I’m on my dual-screen machine could be so useful. Let’s stroll via how to consider adapting a person recipe web page for it.

I wish to take into consideration how I’m going to chunk out my important content material. Typically, at minimal, I see a recipe title, what number of servings it makes, how lengthy it’s going to take to prepare dinner, a picture or a number of photos, the components, and the steps to make the dish.

When I sketch out my wireframe, I get the next:

A sketch of how my website should be laid out on a desktop

A regular structure for a recipe web page on desktop. (Large preview)

I need my title and the recipe particulars on the very high, adopted by a picture that’s going to take up the entire content material width, then the components listing, and the recipe steps. I don’t wish to stack the latter two content material teams, as a result of the ingredient listing can have loads of white area to the fitting of it if I stack them, so I need the steps to sit down subsequent to the components, giving me two columns under the picture.

CSS Grid Or Flexbox For Layout?

I understand how I wish to lay this recipe out on a standard desktop display screen, and there are a number of methods I can go about coding this structure and grouping content material, however how I group it, and what structure I wish to obtain on a dual-screen machine will should be thought-about earlier than I code. Based on the sketch I did for a desktop view, I may use a mixture of flexbox and CSS Grid to attain the structure I need, the place I group the components and steps in a flex container. But let me sketch out how I need my web page to show on a twin display screen.

A sketch of how my website should be laid out on a dual screen device

The perfect structure on a foldable machine within the vertical fold place splits the con-tent up by show so it isn’t obscured by the hinge. (Large preview)

If I need extra flexibility in structure, then I can’t group my components and steps in a flex container, in any other case, there’s going to be a giant hole of white area in whichever column the picture doesn’t go into.

A sketch of how my website would be laid out if I used flexbox, creating a large gap between content on a dual screen device

If I solely use flexbox for this structure, it’s going to create some spacing gaps I wish to keep away from having to hack round. (Large preview)

Adding Our Content

I’m going to make use of nothing however CSS Grid for the desktop and dual-screen layouts. So, let’s construct out our content material.

Pasta carbonara photographed from above on a rustic plate

Next, let’s construct the construction of the web page. I’m going to outline my grid: I solely need three columns, and I need these to be an equal fraction of the container.

.recipe {
show: grid;
grid-template-columns: repeat(3, 1fr);

Next, I’m going to outline my rows, and I’m going to make use of grid-auto-rows with minmax, in order that my rows are a minimal of 175px however can develop to a max of the maximal content material peak.

grid-auto-rows: minmax(175px, max-content);

Then I’m going so as to add just a few extra properties: my grip-gap, my max-content width, and a margin to center my structure on the web page.

grid-gap: 1rem;
max-width: 64rem;
margin: 0 auto;
}

I’m then going to position my content material into the grid I’ve outlined:

.recipe-meta {
grid-column: 1 / 4;
}

.recipe-meta p {
margin: 0;
}

img {
width: 100%;
grid-column: 1 / 4;
}

.recipe-details__ingredients {
grid-row: 3;
}

.recipe-details__preparation {
grid-column: 2 / 4;
grid-row: 3;
}

And that’s going to offer me the structure based mostly on my sketch:

Screenshot of my website laid out on desktop with CSS Grid guides turned on

The structure renders as anticipated on desktop. (Large preview)

Great! But what about my dual-screen structure? Let’s dive in and begin with our horizontal-viewport media function and our grid for twin screens.

Using Media Queries And Adjusting The Container Layout

First, that is what my structure appears like on a twin display screen proper now:

Screenshot of my website emulated on a Surface Duo

Without any twin display screen code applied, if a person needs to span the browser throughout two shows, that is what the web page would seem like. (Large preview)

And if we scroll down:

Screenshot of my website emulated on a Surface Duo showing content being ob-scured by the device hinge

The content material is obscured by the hinge if a person chooses to span throughout each shows. (Large preview)

Not nice. Our content material is being obscured by the hinge, so let me begin redefining my grid.

For my grid columns I’m nonetheless going to make use of three columns, however I need one column to take up the primary viewport phase on the left, and the opposite two break up on the fitting viewport phase, so I’d get to make use of my CSS atmosphere variable env(viewport-segment-width 0 0) which tells the browser, for my first column, I need it to occupy the entire viewport of the primary show area.

@media (horizontal-viewport-segments: 2) {

/* Body kinds for smaller screens */
physique {
font: 1.3em/1.8 base, ‘Playfair Display’, serif;
margin: 0;
}

.recipe {
grid-template-columns: env(viewport-segment-width 0 0 1fr 1fr;
grid-template-rows: repeat(2, 175px) minmax(175px, max-content);
}

}

For my rows, I need just a little extra flexibility within the placement, so I’m going to repeat two rows of 175px, which is in regards to the peak of the container with the recipe title, yield, and time data, and the rows after that ought to match what I outlined in my grid initially.

If I examine my design within the DevTools, I can see that the width and margin I set on my recipe container initially are pushing the grid strains that I wish to be aligned with my viewport phase into the fitting viewport phase.

Screenshot of my website on a Surface Duo with the layout split between displays, so no content is obscured

After including my code, my content material is now not obscured however nonetheless wants some spacing changes. (Large preview)

To reset this, I’m going to reset my margin and max-width.

@media (horizontal-viewport-segments: 2) {

.recipe {
grid-template-columns: env(viewport-segment-width 0 0) 1fr 1fr;
grid-template-rows: repeat(2, 175px) minmax(175px, max-content);
margin: 0;
max-width: 100%;
}

}

Screenshot of my website on a Surface Duo with margin and padding reset

Resetting my margin and padding obscures content material in the fitting show. (Large preview)

And now I’m going to position my content material inside the grid and regulate my structure.

.recipe-meta {
grid-column: 1 / 2;
padding: 0 2rem;
}

img {
grid-column: 2 / 4;
grid-row: 1 / 3;

width: 100%;
peak: 100%;
object-fit: cowl;
/* essential to hold the picture inside the grid strains */
}

.recipe-details__ingredients {
grid-row: 2;
padding: 0 2rem;
}

.recipe-details__preparation {
grid-column: 2 / 4;
grid-row: 3;
padding: 0 2rem 0 3rem;
}

I’ve utilized padding to the content material aside from the picture which I’ve determined I wish to span the entire viewport. For the content material beneath the picture, as a result of nature of the gridline beginning beneath the bodily hinge, I wish to add further padding, so it appears prefer it has the identical padding on the left aspect as the opposite gadgets with padding. If I don’t add further, it’s going to fall too near the hinge. Because I have already got a grid-gap of 1rem and I wish to double the padding, I’ll add 3rem as a substitute of 4rem which supplies us our last structure on a dual-screen machine:

Final adjusted layout with padding and margin added back in to my layout for a dual screen device

I can re-add extra appropriately sized padding to show content material, so it isn’t obscured on a tool with a bodily hinge. (Large preview)

With just a few small changes to our CSS and using one of many new media options, we now have a structure that adapts to a dual-screen machine. To try the expertise, head to the demo web site right here in Edge or a Chromium-based browser and open the browser developer instruments to take a look at Surface Duo emulation. If you’re opening the positioning in Chrome, make sure the experimental web platform options flag is enabled beneath chrome://flags, in order that the demo shows accurately.

Single Screen Responsive Design Details

And simply to make sure we’re making an allowance for small, single-screen units, the code I select for a structure on a cellphone makes use of flexbox and places all the things right into a single column:

@media (max-width: 48rem) {

physique {
font: 1.3em/1.8 base, ‘Playfair Display’, serif;
}

.recipe-details {
show: flex;
flex-direction: column;
}

}

API Browser Availability And Testing Without A Device

These dual-screen APIs can be found in Microsoft Edge and Edge on Android beginning in model 97 by default. These are slated to return to different Chromium browsers quickly, however there isn’t a confirmed date for when that can be. To allow these APIs in Chrome, go to chrome://flags and allow experimental web platform options.

And whereas these are comparatively new units, many at the moment are going into their 2nd and third generations, so firms are investing in them. If you may’t get your palms on a bodily machine, one of the simplest ways to check is within the browser developer instruments. I’ve examined my web site in each the emulation device and on a Surface Duo, and the emulation device for Duo seems to be equivalent. My design appears the identical means on the machine because it does within the DevTools. It makes constructing and designing for a dual-screen machine simply as straightforward as creating for desktop and single display screen cellular units.

If you’re on a desktop or a tool that doesn’t help these APIs, there’s a polyfill out there for the Visual Viewport segments property. There isn’t any API for the CSS Media Queries. Currently, the dual-screen units available on the market are Android-based, and these APIs are deliberate to be in Chromium-based browsers which can be found on Android.

If a browser on a foldable machine doesn’t help these options, you may both use the polyfill or guarantee your website nonetheless renders properly on a small single display screen, because the person has the pliability to decide on tips on how to show a website on a dual-screen machine. They can span a website throughout each shows, or they will select to have it span throughout one show, and in the event that they select the latter, it’s going to show as it might on a pill or cellphone with a single display screen. Even in case your website doesn’t have a dual-screen implementation, customers can nonetheless go for the only show view. The dual-screen APIs provide a strategy to progressively improve the expertise for customers who’ve the units.

Closing

Dual-screen units are simply the following evolution in responsive design. If you’ve a PWA or website, the APIs out there make integrating into your present code base seamless. There are additionally different methods to construct apps for dual-screen units, which you’ll be able to try on the Surface Duo documentation. It’s an thrilling time for structure on the web, and twin screens present a chance to get much more artistic.

Further Resources

Smashing Editorial
(vf, yk, il)

Leave a Reply

Your email address will not be published.