Como criar experiências em tela cheia

Temos a capacidade de criar sites e aplicativos de tela cheia imersivos com facilidade, mas como tudo na Web, há algumas maneiras de fazer isso. Isso é especialmente importante agora que mais navegadores oferecem suporte a uma experiência de "aplicativo da Web instalado" que é iniciada em tela cheia.

Como deixar seu app ou site em tela cheia

Há diversas formas com que um usuário ou desenvolvedor pode colocar um app da Web em tela cheia:

  • Solicitar ao navegador a exibição em tela cheia em resposta a um gesto do usuário.
  • Instalar o app na tela inicial.
  • Simular uma, escondendo a barra de endereço automaticamente.

Solicitar ao navegador a exibição em tela cheia em resposta a um gesto do usuário

Nem todas as plataformas são iguais. O Safari para iOS não tem uma API de tela cheia, mas temos uma para o Chrome para Android, Firefox e IE 11+. A maioria dos aplicativos que você cria usa uma combinação da API JS e dos seletores CSS fornecidos pela especificação de tela cheia. As principais APIs JS que você precisa considerar ao criar uma experiência em tela cheia são:

  • element.requestFullscreen() (atualmente prefixado no Chrome, no Firefox e no IE) exibe o elemento em modo de tela cheia.
  • document.exitFullscreen() (atualmente prefixado no Chrome, no Firefox e no IE. O Firefox usa cancelFullScreen() no lugar dele), que cancela o modo de tela cheia.
  • document.fullscreenElement (atualmente prefixado no Chrome, no Firefox e no IE) retorna "true" se algum dos elementos estiver em modo de tela cheia.

Quando o app está em tela cheia, você não tem mais acesso aos controles da interface do navegador. Isso muda a forma como os usuários interagem com a experiência. Eles não têm acesso aos controles de navegação padrão, como "Avançar" e "Voltar", nem o botão de atualizar. É importante atender a esse cenário. Você pode usar alguns seletores CSS para ajudar a mudar o estilo e a apresentação do seu site quando o navegador entrar no modo de tela cheia.

<button id="goFS">Go fullscreen</button>
<script>
  var goFS = document.getElementById('goFS');
  goFS.addEventListener(
    'click',
    function () {
      document.body.requestFullscreen();
    },
    false,
  );
</script>

O exemplo acima é um pouco irreal, porque eu escondi toda a complexidade que envolve o uso dos prefixos do fornecedor.

O código real é muito mais complexo. O Mozilla criou um script muito útil que você pode usar para alternar para tela cheia. Como você pode ver, a situação do prefixo do fornecedor é complexa e difícil de lidar se comparada à API especificada. Mesmo com o código um pouco mais simples abaixo, ele ainda é complexo.

function toggleFullScreen() {
  var doc = window.document;
  var docEl = doc.documentElement;

  var requestFullScreen =
    docEl.requestFullscreen ||
    docEl.mozRequestFullScreen ||
    docEl.webkitRequestFullScreen ||
    docEl.msRequestFullscreen;
  var cancelFullScreen =
    doc.exitFullscreen ||
    doc.mozCancelFullScreen ||
    doc.webkitExitFullscreen ||
    doc.msExitFullscreen;

  if (
    !doc.fullscreenElement &&
    !doc.mozFullScreenElement &&
    !doc.webkitFullscreenElement &&
    !doc.msFullscreenElement
  ) {
    requestFullScreen.call(docEl);
  } else {
    cancelFullScreen.call(doc);
  }
}

Nós, desenvolvedores web, odiamos complexidade. Uma boa API abstrata de alto nível que você pode usar é o módulo Screenfull.js de Sindre Sorhus, que unifica os dois prefixos ligeiramente diferentes da API JS e do fornecedor em uma API consistente.

Dicas para a API Fullscreen

Como colocar o documento em tela cheia
Tela cheia no elemento &quot;body&quot;
Figura 1: tela cheia no elemento "body".

É natural pensar em colocar o elemento "body" em tela cheia, mas se você trabalha com um motor de renderização baseado no WebKit ou no Blink, verá que isso produz um efeito estranho de comprimir a largura do corpo ao menor tamanho possível que comporta todo o conteúdo. (o Mozilla Gecko funciona bem).

Tela cheia no elemento do documento
Figura 2: tela cheia no elemento "document".

Para corrigir isso, use o elemento "document" em vez de "body":

document.documentElement.requestFullscreen();
Como levar um elemento "video" para a tela cheia

Levar um elemento "video" para tela cheia é exatamente igual para todos os outros elementos. Chame o método requestFullscreen no elemento de vídeo.

<video id="videoElement"></video>
<button id="goFS">Go Fullscreen</button>
<script>
  var goFS = document.getElementById('goFS');
  goFS.addEventListener(
    'click',
    function () {
      var videoElement = document.getElementById('videoElement');
      videoElement.requestFullscreen();
    },
    false,
  );
</script>

Se o elemento <video> não tiver o atributo "controls" definido, o usuário não poderá controlar o vídeo quando ele estiver em tela cheia. A forma recomendada de fazer isso é ter um contêiner básico que encapsule o vídeo e os controles que você quer que o usuário tenha acesso.

<div id="container">
  <video></video>
  <div>
    <button>Play</button>
    <button>Stop</button>
    <button id="goFS">Go fullscreen</button>
  </div>
</div>
<script>
  var goFS = document.getElementById('goFS');
  goFS.addEventListener(
    'click',
    function () {
      var container = document.getElementById('container');
      container.requestFullscreen();
    },
    false,
  );
</script>

Isso dá muita flexibilidade, porque você consegue combinar o objeto de contêiner com o pseudo-seletor CSS (por exemplo, para esconder o botão "goFS").

<style>
  #goFS:-webkit-full-screen #goFS {
    display: none;
  }
  #goFS:-moz-full-screen #goFS {
    display: none;
  }
  #goFS:-ms-fullscreen #goFS {
    display: none;
  }
  #goFS:fullscreen #goFS {
    display: none;
  }
</style>

Com esses padrões, é possível detectar quando a tela cheia está ativa e adaptar a interface do usuário a ela, por exemplo:

  • Fornecendo um link para voltar à página inicial
  • Fornecendo um mecanismo para fechar caixas de diálogo ou navegar retornando

Inicialização de uma página em tela cheia pela tela inicial

Não é possível abrir uma página da Web em tela cheia quando o usuário navega até ela. Os fornecedores de navegadores sabem que uma experiência em tela cheia em cada carregamento de página é muito irritante. Portanto, um gesto do usuário é necessário para entrar no modo de tela cheia. Os fornecedores permitem que os usuários "instalem" apps, e o ato de instalar é um sinal para o sistema operacional de que o usuário quer iniciar como um app na plataforma.

Nas principais plataformas móveis, é bem fácil implementar usando metatags ou arquivos de manifesto como mostrado abaixo.

iOS

Desde o lançamento do iPhone, os usuários podem instalar apps da Web na tela inicial e inicializá-los em modo de tela cheia.

<meta name="apple-mobile-web-app-capable" content="yes" />

Se "content" for definido como "yes", o aplicativo da Web será executado em modo de tela cheia. Caso contrário, ele não será executado. O comportamento padrão é usar o Safari para mostrar conteúdo da Web. Você pode determinar se uma página da Web é exibida em tela cheia usando a propriedade booleana somente leitura JavaScript window.navigator.standalone.

Apple

Google Chrome para Android

A equipe do Chrome recentemente implementou um recurso que instrui o navegador a inicializar a página em tela cheia quando o usuário a tiver adicionado na tela inicial. Ela é semelhante ao modelo do Safari para iOS.

<meta name="mobile-web-app-capable" content="yes" />

Você pode configurar seu app da Web para adicionar um ícone de atalho à tela inicial de um dispositivo e abrir o app em modo de tela cheia usando o item de menu "Add to Home Screen" do Chrome for Android.

Google Chrome

Uma melhor opção é usar o manifesto do app da Web.

Manifesto dos apps da Web (Chrome, Opera, Firefox, Samsung)

O manifesto para aplicativos da Web é um arquivo JSON simples que permite que você, desenvolvedor, controle como o app aparece para o usuário nas áreas em que ele pode encontrar aplicativos (por exemplo, na tela inicial do dispositivo móvel), direcione o que o usuário pode iniciar e, mais importante, como ele pode iniciar. No futuro, o manifesto vai dar ainda mais controle sobre seu app, mas no momento estamos apenas focando em como o app pode ser inicializado. Especificamente:

  1. Informar o navegador sobre o manifesto
  2. Descrevendo como inicializar

Depois que criar o manifesto e hospedá-lo no seu site, basta adicionar uma tag "link" para cada página que envolve o seu aplicativo. Veja como a seguir:

<link rel="manifest" href="/manifest.json" />

O Chrome oferece suporte a manifestos desde a versão 38 para Android (outubro de 2014) e permite controlar como o app da Web aparece quando é instalado na tela inicial (usando as propriedades short_name, name e icons) e como ele é iniciado quando o usuário clica no ícone de inicialização (usando start_url, display e orientation).

Confira um exemplo de manifesto abaixo. Ele não mostra tudo que pode estar em um manifesto.

{
  "short_name": "Kinlan's Amaze App",
  "name": "Kinlan's Amazing Application ++",
  "icons": [
    {
      "src": "launcher-icon-4x.png",
      "sizes": "192x192",
      "type": "image/png"
    }
  ],
  "start_url": "/index.html",
  "display": "standalone",
  "orientation": "landscape"
}

Esse recurso é totalmente progressivo e permite criar experiências melhores e mais integradas para os usuários de um navegador compatível com o recurso.

Quando o usuário adiciona o seu site ou aplicativo à tela inicial, há uma intenção do usuário de tratá-lo como um aplicativo. Isso significa que você deve buscar direcionar o usuário para a operação do seu app, não para uma página de destino do produto. Por exemplo, se o usuário precisa fazer login no app, essa é uma boa página para iniciar.

Apps utilitários

A maioria dos aplicativos utilitários se beneficiará disso de maneira imediata. Para esses aplicativos, você provavelmente quer que eles sejam inicializados na forma autônoma, assim como todo aplicativo em uma plataforma móvel. Para instruir um app a inicializar na forma autônoma, adicione o seguinte ao manifesto do app da Web:

    "display": "standalone"
Jogos

A maioria dos jogos se beneficiará do manifesto de maneira imediata. A grande maioria dos jogos vai querer a inicialização em tela cheia e uma orientação específica forçada.

Se você esta desenvolvendo um jogo de vista aérea ou um como o Flappy Birds, é em provável que você queira que o jogo sempre fique em modo retrato.

    "display": "fullscreen",
    "orientation": "portrait"

Por outro lado, se estiver criando um jogo de quebra cabeças ou um como o X-Com, provavelmente você vai querer que o jogo sempre use a orientação de paisagem.

    "display": "fullscreen",
    "orientation": "landscape"
Sites de notícias

Na maioria dos casos, os sites de notícia oferecem experiência puramente baseada em conteúdo. A maioria dos desenvolvedores não pensaria em adicionar um manifesto a um site de notícias. O manifesto permite definir o que inicializar (a página principal do site de notícias) e como inicializar (em tela cheia ou como uma guia de navegador comum).

A escolha depende de você e de como você acha que os usuários gostariam de acessar a experiência. Se você quiser que o site tenha todo o aparato dos navegadores que se espera que um site tenha, defina a exibição como browser.

    "display": "browser"

Se quiser que o site de notícias pareça com a maioria dos aplicativos centrados em notícias na forma de que apresentam suas experiências como aplicativos e removem da IU todos os recursos que remetem à web, você pode fazer isso definindo a exibição como standalone.

    "display": "standalone"

Simular uma tela cheia, escondendo a barra de endereço automaticamente.

Você pode "simular uma tela cheia" escondendo a barra de endereço automaticamente da seguinte forma:

window.scrollTo(0, 1);

Esse é um método bem simples: a página carrega e a barra do navegador é instruída a desaparecer. Infelizmente, ele não está padronizado e não tem compatibilidade. Além disso, você tem que encontrar alternativas para um monte de peculiaridades.

Por exemplo, muitas vezes os navegadores restauram a posição na página quando o usuário volta a ela. O uso de window.scrollTo anula isso, o que irrita o usuário. Para encontrar uma alternativa para esse comportamento, você tem que armazenar a última posição em localStorage e lidar com os casos extremos (por exemplo, se o usuário tiver a página aberta em diversas janelas).

Orientações de UX

Ao criar um site que tira vantagem da tela cheia, há diversas possíveis mudanças na experiência do usuário que você precisa conhecer para criar um serviço que encante os usuários.

Não dependa dos controles de navegação

O iOS não tem um botão de voltar nem gesto de atualizar. Portanto, você precisa garantir que os usuários possam navegar por todo o app sem ficarem presos.

Você pode detectar se está executando em modo de tela cheia ou em um modo instalado com facilidade em todas as principais plataformas.

iOS

No iOS, você pode usar o booleano navigator.standalone para saber se o usuário iniciou a partir da tela inicial ou não.

if (navigator.standalone == true) {
  // My app is installed and therefore fullscreen
}

Manifesto de app da Web (Chrome, Opera, Samsung)

Ao inicializar como um app instalado, o Chrome não é executado em tela cheia de verdade, então document.fullscreenElement retorna "null" e os seletores CSS não funcionam.

Quando o usuário solicita a tela cheia por um gesto no site, as APIs de tela cheia padrão ficam disponíveis, incluindo o pseudo-seletor CSS que permite adaptar a IU para reagir ao estado de tela cheia da seguinte forma:

selector:-webkit-full-screen {
  display: block; // displays the element only when in fullscreen
}

selector {
  display: none; // hides the element when not in fullscreen mode
}

Se o usuário inicializar o site pela tela inicial, a consulta de mídia display-mode será definida como definida no manifesto do aplicativo da Web. No caso de tela cheia pura, isso seria:

@media (display-mode: fullscreen) {
}

Se o usuário iniciar o aplicativo no modo autônomo, a consulta de mídia display-mode será standalone:

@media (display-mode: standalone) {
}

Firefox

Quando o usuário solicita a tela cheia pelo seu site ou inicializa o app no modo de tela cheia, todas as APIs de tela cheia padrão ficam disponíveis, incluindo o pseudo-seletor CSS, que permite adaptar a IU para reagir ao estado de tela cheia da seguinte forma:

selector:-moz-full-screen {
  display: block; // hides the element when not in fullscreen mode
}

selector {
  display: none; // hides the element when not in fullscreen mode
}

Internet Explorer

No IE, a pseudo-classe CSS não tem hífen, mas mesmo assim funciona de forma parecida no Chrome e no Firefox.

selector:-ms-fullscreen {
  display: block;
}

selector {
  display: none; // hides the element when not in fullscreen mode
}

Especificação

A grafia da especificação corresponde à sintaxe usada pelo IE.

selector:fullscreen {
  display: block;
}

selector {
  display: none; // hides the element when not in fullscreen mode
}

Manter o usuário na experiência de tela cheia

A API de tela cheia pode ter algumas frescuras às vezes. Os fornecedores de navegador não querem prender os usuários em uma página de tela cheia, por isso, desenvolveram mecanismos para sair da tela cheia assim que possível. Isso significa que você não pode criar um site em tela cheia que abra muitas páginas porque:

  • Alterar o URL programaticamente usando window.location = "http://example.com" sai da tela cheia.
  • O clique de um usuário em um link externo da sua página fará com que a tela cheia seja abandonada.
  • Alterar o URL pela API navigator.pushState também sai da experiência de tela cheia.

Você tem duas opções se quiser manter o usuário em uma experiência de tela cheia:

  1. Use os mecanismos instaláveis dos apps da Web para ir para a tela cheia.
  2. Gerencie a interface e o estado do app usando o fragmento #.

Ao usar a #syntax para atualizar o URL (window.location = "#somestate") e ouvir o evento window.onhashchange, você pode usar a própria pilha de histórico do navegador para gerenciar mudanças no estado do aplicativo, permitir que o usuário use os botões de retorno de hardware ou oferecer uma experiência simples de botão de retorno programático usando a API History da seguinte maneira:

window.history.go(-1);

Deixe o usuário escolher quando ativar a tela cheia

Não existe nada mais irritante para o usuário do que um site que faz algo inesperado. Quando um usuário navega para o site, não tente fazê-lo ir para o modo de tela cheia.

Não intercepte o primeiro evento de toque e chame requestFullscreen().

  1. É irritante.
  2. Os navegadores podem decidir perguntar ao usuário em algum momento se ele quer que o app seja aberto em tela cheia.

Se quiser inicializar aplicativos em tela cheia, pense em usar as experiências de instalação de cada plataforma.

Não fique insistindo que o usuário instale o seu app na tela de início.

Se você planeja oferecer uma experiência de tela cheia pelos mecanismos instalados do app, pense no usuário.

  • Aja com discrição. Use um banner ou rodapé para informar que eles podem instalar o app.
  • Se eles descartarem a proposta, não a mostre novamente.
  • No primeiro acesso dos usuários, é bem provável que eles não queiram instalar o app, a menos que estejam muito satisfeitos com o seu serviço. Pense em convidá-los a instalar depois de uma interação positiva no site.
  • Se o usuário acessa o site regularmente e não instala o app, é improvável que ele o instale no futuro. Não insista.

Conclusão

Apesar de não termos uma API totalmente padronizada e implementada, usando algumas das orientações apresentadas neste artigo, fica fácil criar experiências que tiram vantagem de toda a tela do usuário, independentemente do cliente.

Feedback