Teste de origem para APIs dobráveis

O Chrome está testando duas APIs, a Device Posture e a Viewport Segments Enumeration, que estão disponíveis como um teste de origem do Chrome 125. Elas são conhecidas coletivamente como APIs dobráveis, projetadas para ajudar os desenvolvedores a criar apps para dispositivos dobráveis. Esta postagem apresenta essas APIs e oferece informações sobre como começar a testá-las.

Há basicamente dois formatos físicos diferentes: dispositivos com uma tela flexível única (seamless) e dispositivos com duas telas (com costura, também conhecidos como dispositivos de tela dupla).

Desenho esquemático de um dispositivo com uma única tela flexível (sem emendas) à esquerda e um dispositivo com duas telas (com emenda, também conhecido como tela dupla) à direita.

Esses dispositivos apresentam desafios e oportunidades para os desenvolvedores. Eles oferecem outras maneiras de visualizar o conteúdo. Por exemplo, um usuário pode segurar um dispositivo sem costura como um livro e depois mudar para usá-lo como um tablet com uma tela plana. Dispositivos com duas telas têm uma união física entre as telas que pode precisar ser considerada.

Essas novas APIs oferecem aos desenvolvedores maneiras de oferecer experiências de usuário melhores para esses dispositivos. Cada API expõe as primitivas necessárias da plataforma da Web de duas maneiras, pelo CSS e pelo JavaScript.

API Device Posture

Os dispositivos dobráveis têm recursos que permitem mudar a _postura_, ou o estado físico do dispositivo. Eles podem mudar de formato, permitindo que os autores de conteúdo ofereçam uma experiência de usuário diferente. Essas novas APIs garantem que o conteúdo da Web possa reagir aos vários estados de dobramento.

Há duas posturas que um dispositivo pode ter:

  • folded: posturas de laptop ou livro.

Desenho esquemático de dispositivos em posições planas ou de tablet e uma tela curva contínua.

  • continuous: telas planas, de tablet ou até mesmo curvas sem emendas.

Desenho esquemático de dispositivos em posições de laptop ou livro.

CSS

A especificação da API Device Posture define um novo recurso de mídia CSS, device-posture. Esse recurso de mídia é resolvido em um conjunto de posturas fixas. Essas posturas consistem em vários valores predefinidos que abrangem um estado físico do dispositivo.

Os valores do recurso device-posture correspondem à descrição anterior de possíveis posturas:

  • folded
  • continuous

Novas posturas podem ser adicionadas no futuro se novos dispositivos chegarem ao mercado.

Exemplos:

/* Using the device in a 'book' posture. */
@media (device-posture: folded) { ... }

/* Using the device in a 'flat' posture, or any typical device like a laptop or
desktop device. */
@media (device-posture: continuous) { ... }

JavaScript

Para consultar a postura de um dispositivo, um novo objeto DevicePosture está disponível.

const { type } = navigator.devicePosture;
console.log(`The current device is of type ${type}.`);

Para reagir a mudanças na postura do dispositivo, como um usuário que abre totalmente um dispositivo e, portanto, passa de folded para continuous, inscreva-se nos eventos change.

navigator.devicePosture.addEventListener('change', (e) => {
  console.log(`The device posture changed to type ${e.type}`);
});

API Viewport Segments

Os segmentos de viewport são variáveis de ambiente do CSS que definem a posição e as dimensões de uma região logicamente separada da viewport. Os segmentos de viewport são criados quando a viewport é dividida por um ou mais recursos de hardware (como uma dobra ou uma articulação entre telas separadas) que funcionam como um divisor. Os segmentos são as regiões da viewport que podem ser tratadas como logicamente distintas pelo autor.

CSS

O número de divisões lógicas é exposto por dois novos recursos de mídia, definidos na especificação do nível 5 das consultas de mídia do CSS: vertical-viewport-segments e horizontal-viewport-segments. Elas são resolvidas para o número de segmentos em que a janela de visualização é dividida.

Além disso, novas variáveis de ambiente foram adicionadas para consultar as dimensões de cada divisão lógica. Essas variáveis são:

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

Cada variável tem duas dimensões, que representam a posição x e y, respectivamente, na grade bidimensional criada pelos recursos de hardware que separam os segmentos.

Diagrama mostrando segmentos horizontais e verticais. O primeiro segmento horizontal é x 0 e y 0, o segundo é x 1 e y 0. O primeiro segmento vertical é x 0 e y 0, o segundo x 0 e y 1.
O primeiro segmento horizontal é x 0 e y 0, o segundo x 1 e y 0. O primeiro segmento vertical é x 0 e y 0, o segundo x 0 e y 1.

O snippet de código abaixo é um exemplo simplificado de criação de uma UX dividida, em que temos duas seções de conteúdo (col1 e col2) em cada lado da dobra.

<style>
  /* Segments are laid out horizontally. */
  @media (horizontal-viewport-segments: 2) {
    #segment-css-container {
      flex-direction: row;
    }

    #col1 {
      display: flex;
      flex: 0 0 env(viewport-segment-right 0 0);
      background-color: steelblue;
    }

    #fold {
      width: calc(env(viewport-segment-left 1 0) - env(viewport-segment-right 0 0));
      background-color: black;
      height: 100%;
    }

    #col2 {
      display: flex;
      background-color: green;
    }
  }

  /* Segments are laid out vertically. */
  @media (vertical-viewport-segments: 2) {
    #segment-css-container {
      flex-direction: column;
    }

    #col1 {
      display: flex;
      flex: 0 0 env(viewport-segment-bottom 0 0);
      background-color: pink;
    }

    #fold {
      width: 100%;
      height: calc(env(viewport-segment-top 0 1) - env(viewport-segment-bottom 0 0));
      background-color: black;
    }

    #col2 {
      display: flex;
     background-color: seagreen;
    }
  }
</style>

<div id="segment-css-container">
   <div id="col1"></div>
   <div id="fold"></div>
   <div id="col2"></div>
 </div>

As fotos a seguir mostram como a experiência fica em um dispositivo físico.

Smartphone dobrável na posição de livro vertical.

Smartphone dobrável na posição horizontal de livro.

Tablet dobrável na posição de livro horizontal.

JavaScript

Para conferir o número de segmentos de viewport, verifique a entrada segments no visualViewport.

const segments = window.visualViewport.segments;
console.log('The viewport has the following segments:', segments);

Cada entrada na matriz segments representa cada segmento lógico da janela de visualização com um DOMArray que descreve as coordenadas e o tamanho. O campo segments é um snapshot do estado fornecido quando consultado. Para receber valores atualizados, você precisa detectar mudanças de postura ou redimensionar eventos e consultar novamente a propriedade segments.

Testar as APIs dobráveis

As APIs Foldable estão disponíveis em um teste de origem do Chrome 125 ao Chrome 128. Consulte Começar a usar os testes de origem para saber mais sobre os testes de origem.

Para testes locais, as APIs dobráveis podem ser ativadas com a flag de recursos da plataforma experimental da Web em chrome://flags/#enable-experimental-web-platform-features. Também é possível ativá-lo executando o Chrome na linha de comando com --enable-experimental-web-platform-features.

Demonstrações

Para ver demonstrações, consulte o repositório de demonstrações. Se você não tiver um dispositivo físico para testar, escolha o dispositivo emulado Galaxy Z Fold 5 ou Asus Zenbook Fold nas Ferramentas do desenvolvedor do Chrome e alterne entre Continuo e Dobrado. Também é possível visualizar a dobradiça, quando aplicável.

O Chrome DevTools emulando um dispositivo dobrável.