Como criar experiências em tela cheia

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

Como colocar seu app ou site em tela cheia

Um usuário ou desenvolvedor pode colocar um aplicativo da Web em tela cheia de várias maneiras.

  • Solicitar que o navegador entre no modo de tela cheia em resposta a um gesto do usuário.
  • Instale o app na tela inicial.
  • Simular: oculte a barra de endereço automaticamente.

Solicitar que o navegador entre no modo de 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 o Chrome no Android, no Firefox e no IE 11+. A maioria dos apps que você criar usará uma combinação da API JS e dos seletores de CSS fornecidos pela especificação de tela cheia. As principais APIs JS com as quais você precisa se preocupar ao criar uma experiência em tela cheia são:

  • element.requestFullscreen() (atualmente prefixado no Chrome, Firefox e IE) mostra o elemento no modo de tela cheia.
  • document.exitFullscreen() (prefixado atualmente no Chrome, Firefox e IE. O Firefox usa cancelFullScreen()) cancela o modo de tela cheia.
  • document.fullscreenElement (atualmente prefixado no Chrome, Firefox e IE) retornará "true" se algum dos elementos estiver no modo de tela cheia.

Quando o app está em tela cheia, os controles de interface do navegador não ficam mais disponíveis. Isso muda a maneira como os usuários interagem com sua experiência. Eles não têm os controles de navegação padrão, como "Para frente" e "Para trás", não têm a saída de emergência, que é o botão "Atualizar". É importante atender a esse cenário. Você pode usar alguns seletores de 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 irreversível. Ocultei toda a complexidade que envolve o uso dos prefixos do fornecedor.

O código em si é 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 em comparação com a API especificada. Mesmo com o código um pouco simplificado abaixo, isso 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 pode ser usada é o módulo Screenfull.js do Sindre Sorhus, que unifica os dois prefixos do fornecedor e da API JS ligeiramente diferentes em uma API consistente.

Dicas sobre a API Fullscreen

Colocando o documento em tela cheia
Tela cheia no elemento do corpo
Figura 1: tela cheia no elemento do corpo.

É natural pensar que o elemento do corpo está em tela cheia, mas se você estiver usando um mecanismo de renderização baseado no WebKit ou no Blink, vai notar que ele tem um efeito estranho de reduzir a largura do corpo para o menor tamanho possível que vai conter todo o conteúdo. (o Mozilla Gecko funciona bem.)

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

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

document.documentElement.requestFullscreen();
Colocar um elemento de vídeo em tela cheia

Para colocar um elemento de vídeo em tela cheia é exatamente o mesmo que colocar qualquer outro elemento em tela cheia. 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 vai poder controlar o vídeo quando ele estiver em tela cheia. A maneira recomendada de fazer isso é ter um contêiner básico que envolva o vídeo e os controles que você quer que o usuário veja.

<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 oferece muito mais flexibilidade, porque é possível combinar o objeto contêiner com o pseudoseletor CSS (por exemplo, para ocultar 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>

Usando esses padrões, é possível detectar quando a tela cheia está em execução e adaptar a interface do usuário de forma adequada, por exemplo:

  • Fornecendo um link de volta para a página inicial
  • Fornecendo um mecanismo para fechar caixas de diálogo ou retroceder.

Abrir 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 de tela cheia em cada carregamento de página é um grande inconveniente. Por isso, é necessário um gesto do usuário para entrar no modo de tela cheia. No entanto, 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 para dispositivos móveis, é muito fácil implementar usando metatags ou arquivos de manifesto, como mostrado a seguir.

iOS

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

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

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

Apple

Google Chrome para Android

A equipe do Chrome recentemente implementou um recurso que instrui o navegador a abrir a página em tela cheia quando o usuário a adicionar à tela inicial. Ele é 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 iniciar o app no "modo de aplicativo" em tela cheia usando o item de menu "Adicionar à tela inicial" do Chrome para Android.

Google Chrome

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

Manifesto do app da Web (Chrome, Opera, Firefox, Samsung)

O Manifesto para aplicativos da Web é um arquivo JSON simples que oferece a você, desenvolvedor, a capacidade de controlar como o app aparece para o usuário nas áreas em que ele espera ver apps (por exemplo, a tela inicial do dispositivo móvel), direcionar o que o usuário pode iniciar e, o mais importante, como pode iniciá-lo. No futuro, o manifesto vai oferecer ainda mais controle sobre o app, mas, por enquanto, vamos nos concentrar apenas em como o app pode ser iniciado. Especificamente:

  1. Como informar o navegador sobre seu manifesto
  2. Descrição de como iniciar

Depois de criar o manifesto e hospedá-lo no seu site, basta adicionar uma tag de link para todas as páginas que abrangem seu app, da seguinte maneira:

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

O Chrome oferece suporte a manifestos desde a versão 38 para Android (outubro de 2014) e oferece o controle sobre como seu app da Web aparece quando é instalado na tela inicial (pelas propriedades short_name, name e icons) e como ele deve ser iniciado quando o usuário clicar no ícone de inicialização (via start_url, display e orientation).

Confira um exemplo de manifesto abaixo. Ele não representa tudo o 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 um usuário adiciona seu site ou app à tela inicial, há uma intenção do usuário de tratá-lo como um app. Isso significa que você precisa direcionar o usuário à funcionalidade do app, e não a uma página de destino do produto. Por exemplo, se o usuário precisa fazer login no app, essa é uma boa página para abrir.

Apps utilitários

A maioria dos apps utilitários se beneficiará imediatamente. Para esses apps, você provavelmente vai querer que eles sejam iniciados na forma autônoma, assim como todos os outros apps de plataformas para dispositivos móveis. Para instruir um app a iniciar sozinho, adicione este código ao manifesto do app da Web:

    "display": "standalone"
Jogos

A maioria dos jogos vai se beneficiar do uso de um manifesto de forma imediata. A grande maioria dos jogos vai querer iniciar em tela cheia e forçar uma orientação específica.

Se você estiver desenvolvendo um botão de rolagem vertical ou um jogo como o Flappy Birds, é provável que você queira que o jogo sempre esteja no modo retrato.

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

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

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

Na maioria dos casos, os sites de notícias são experiências baseadas em conteúdo. A maioria dos desenvolvedores naturalmente não pensaria em adicionar um manifesto a um site de notícias. O manifesto permite definir o que será iniciado (a página principal do seu site de notícias) e como a inicialização (em tela cheia ou como uma guia normal do navegador).

A escolha depende de você e de como acha que os usuários gostariam de acessar sua experiência. Se quiser que seu site tenha todas as opções de navegador do Chrome que um site precisa, defina a exibição como browser.

    "display": "browser"

Se você quiser que seu site de notícias pareça que a maioria dos apps voltados a notícias trata as experiências como apps e remove da interface todos os recursos do Chrome semelhantes a Web, defina a exibição como standalone.

    "display": "standalone"

Simular: ocultar a barra de endereço automaticamente

Você pode "simular a tela cheia" ocultando automaticamente a barra de endereço 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 sair do caminho. Infelizmente, ele não está padronizado e não é bem aceito. Você também tem que contornar um monte de peculiaridades.

Por exemplo, geralmente, os navegadores restauram a posição na página quando o usuário volta a ela. O uso de window.scrollTo substitui isso, o que incomoda o usuário. Para contornar esse problema, você precisa armazenar a última posição no localStorage e lidar com os casos extremos (por exemplo, se o usuário estiver com a página aberta em várias janelas).

Orientações de UX

Ao criar um site que aproveita a tela cheia, há várias possíveis mudanças na experiência do usuário que você precisa conhecer para criar um serviço que agrade seus usuários.

Não depender dos controles de navegação

O iOS não tem um botão "Voltar" ou gesto de atualização. Portanto, você precisa garantir que os usuários possam navegar por todo o app sem ficarem presos.

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

iOS

No iOS, você pode usar o booleano navigator.standalone para ver se o usuário foi iniciado pela tela inicial ou não.

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

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

Quando o Chrome é iniciado como um app instalado, ele não é executado na experiência real de tela cheia. Por isso, document.fullscreenElement retorna nulo e os seletores de CSS não funcionam.

Quando o usuário solicita a tela cheia com um gesto no site, as APIs de tela cheia padrão ficam disponíveis, incluindo o pseudoseletor CSS que permite adaptar a interface para reagir ao estado de tela cheia, como no exemplo abaixo.

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 iniciar o site pela tela inicial, a consulta de mídia display-mode vai ser definida como o que foi definido no manifesto do app da Web. No caso de tela cheia pura, isso será:

@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 site ou abre o app no modo de tela cheia, todas as APIs de tela cheia padrão estão disponíveis, incluindo o pseudoseletor CSS, que permite adaptar a interface para reagir ao estado de tela cheia da seguinte maneira:

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 pseudoclasse CSS não tem hífen, mas funciona de maneira semelhante ao Chrome e ao 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 ser um pouco minuciosa às vezes. Os fornecedores de navegadores não querem bloquear os usuários em uma página em tela cheia, por isso, desenvolveram mecanismos para sair da tela cheia assim que possível. Isso significa que não é possível criar um site em tela cheia que abrange várias páginas porque:

  • A alteração do URL de maneira programática usando window.location = "http://example.com" sai da tela cheia.
  • Quando um usuário clica em um link externo na sua página, ela sai da tela cheia.
  • A mudança do URL pela API navigator.pushState também sairá da experiência em 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 do app da Web para entrar em tela cheia.
  2. Gerencie a interface e o estado do app usando o fragmento #.

Ao usar a sintaxe # 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 as alterações no estado do aplicativo, permitir que o usuário use os botões "Voltar" do hardware ou oferecer uma experiência simples e programática de botão "Voltar" usando a API de histórico da seguinte maneira:

window.history.go(-1);

Permitir que o usuário escolha quando ativar a tela cheia

Não há nada mais irritante para o usuário do que um site fazendo algo inesperado. Quando o usuário navegar até o site, não tente fazer com que ele apareça em tela cheia.

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

  1. É irritante.
  2. Os navegadores podem decidir pedir ao usuário em algum momento no futuro sobre como permitir que o app ocupe a tela cheia.

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

Não envie spam ao usuário para instalar o app em uma tela inicial

Se você planeja oferecer uma experiência de tela cheia usando os mecanismos do app instalado, considere o usuário.

  • Tenha discrição. Use um banner ou rodapé para informar que eles podem instalar o app.
  • Se a solicitação for dispensada, não a mostre novamente.
  • No primeiro acesso dos usuários, é improvável que eles queiram instalar o app, a menos que estejam satisfeitos com seu serviço. Considere solicitar que eles instalem depois de uma interação positiva no site.
  • Se um usuário acessa o site regularmente e não instala o app, é provável que ele não instale o app no futuro. Não fique enviando spam.

Conclusão

Embora não tenhamos uma API totalmente padronizada e implementada, usando algumas das orientações apresentadas neste artigo, você pode criar facilmente experiências que aproveitam toda a tela do usuário, independentemente do cliente.

Feedback