Desarrollar experiencias en pantalla completa

Podemos crear aplicaciones y sitios web envolventes de pantalla completa con facilidad, pero como todo en la Web, hay varias formas de hacerlo. Esto es especialmente importante ahora que más navegadores admiten una experiencia de "aplicación web instalada" que inicia la pantalla completa.

Obtener la pantalla completa de tu aplicación o sitio

Un usuario o desarrollador puede obtener el modo de pantalla completa de una app web de varias maneras.

  • Solicitar al navegador el modo de pantalla completa en respuesta a un gesto del usuario
  • Instala la app en la pantalla principal.
  • Simulación: esconder automáticamente la barra de direcciones.

Cómo solicitar que el navegador cambie a pantalla completa en respuesta a un gesto del usuario

No todas las plataformas son iguales. Safari de iOS no tiene una API en pantalla completa, pero sí en Chrome para Android, IE 11 y Firefox, y versiones posteriores. La mayoría de las aplicaciones que compilas usarán una combinación de la API de JS y los selectores CSS que proporciona la especificación de pantalla completa. Las principales API de JS por las que te tienes que preocupar cuando desarrollas una experiencia en pantalla completa son las siguientes:

  • element.requestFullscreen() (actualmente con prefijo en Chrome, Firefox y en IE) muestra el elemento en el modo de pantalla completa.
  • document.exitFullscreen() (actualmente con prefijo en Chrome, Firefox y en IE. En cambio, Firefox usa cancelFullScreen()) cancela el modo de pantalla completa.
  • document.fullscreenElement (actualmente con prefijo en Chrome, Firefox y en IE) se muestra como verdadero si alguno de los elementos está en modo de pantalla completa.

Cuando la app está en pantalla completa, ya no tienes disponibles los controles de la IU del navegador. Esto cambia la forma en que los usuarios interactúan con tu experiencia. No tienen los controles de navegación estándar, como Forwards y Backwards; no tienen su salida de escape que es el botón Refresh. Es importante contemplar este escenario. Puedes usar algunos selectores CSS que te ayuden a cambiar el estilo y la presentación de tu sitio cuando el navegador entra en el modo de pantalla completa.

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

El ejemplo anterior es un poco forzado; oculté toda la complejidad en torno al uso de prefijos de proveedores.

El código real es mucho más complejo. Mozilla creó una secuencia de comandos muy útil que puedes usar para activar o desactivar la pantalla completa. Como puedes ver, la situación del prefijo del proveedor es compleja y engorrosa en comparación con la API especificada. Incluso con el siguiente código un poco simplificado, sigue siendo complejo.

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);
  }
}

Nosotros, los desarrolladores web odiamos la complejidad. Una buena API abstracta de alto nivel que puedes usar es el módulo Screenfull.js de Sindre Sorhus, que unifica las dos API de JS ligeramente diferentes y los prefijos del proveedor en una API coherente.

Sugerencias para la API de pantalla completa

Activar el modo de pantalla completa del documento
Pantalla completa en el elemento de cuerpo
Figura 1: pantalla completa en el elemento de cuerpo

Es natural pensar que tomas el modo de pantalla completa del elemento del cuerpo, pero si estás en un motor de procesamiento basado en WebKit o Blink, verás que tiene el efecto raro de reducir el ancho del cuerpo al tamaño más pequeño posible que contendrá todo el contenido. (Mozilla Gecko está bien).

Pantalla completa en el elemento del documento
Figura 2: Pantalla completa en el elemento del documento

Para solucionar este problema, usa el elemento de documento en lugar del elemento de cuerpo:

document.documentElement.requestFullscreen();
Activa el modo de pantalla completa de un elemento de video

Activar el modo de pantalla completa de un elemento de video es exactamente lo mismo que activar el modo de pantalla completa de cualquier otro elemento. Llamas al método requestFullscreen en el elemento de video.

<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>

Si tu elemento <video> no tiene definido el atributo de controles, el usuario no podrá controlar el video una vez que esté en pantalla completa. La forma recomendada de hacerlo es tener un contenedor básico que una el video y los controles que quieres que vea el usuario.

<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>

Esto te brinda mucha más flexibilidad, ya que puedes combinar el objeto contenedor con el seudoselector CSS (por ejemplo, para ocultar el botón “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>

Con estos patrones, puedes detectar cuándo se ejecuta la pantalla completa y adaptar tu interfaz de usuario de manera adecuada, por ejemplo:

  • Proporcionando un vínculo a la página de inicio
  • Proporcionar un mecanismo para cerrar diálogos o desplazarse hacia atrás

Iniciar el modo de pantalla completa de una página desde la pantalla principal

No es posible iniciar una página web en pantalla completa cuando el usuario navega hacia ella. Los proveedores de navegadores son muy conscientes de que una experiencia de pantalla completa en cada carga de página es una gran molestia, por lo que se requiere un gesto del usuario para entrar en pantalla completa. Sin embargo, los proveedores sí permiten que los usuarios "instalen" apps, y el hecho de hacerlo es una señal para el sistema operativo que el usuario desea iniciar como una app en la plataforma.

En las principales plataformas móviles es bastante fácil implementar el uso de metaetiquetas o archivos de manifiesto de la siguiente manera.

iOS

Desde el lanzamiento del iPhone, los usuarios han podido instalar apps web en la pantalla principal y hacer que se inicien como apps web de pantalla completa.

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

Si el contenido está configurado en sí, la aplicación web se ejecuta en el modo de pantalla completa; de lo contrario, no lo hace. El comportamiento predeterminado es usar Safari para mostrar contenido web. Puedes determinar si una página web se muestra en modo de pantalla completa con la propiedad booleana de solo lectura de JavaScript window.navigator.standalone.

Apple

Chrome para Android

Recientemente, el equipo de Chrome implementó una función que le indica al navegador que inicie la pantalla completa de la página cuando el usuario la agregó a la pantalla principal. Es similar al modelo Safari de iOS.

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

Puedes configurar tu app web para que agregue un ícono de acceso directo a la aplicación en la pantalla principal de un dispositivo y que la app se inicie en "modo de app" en pantalla completa mediante el elemento de menú "Agregar a la pantalla principal" de Chrome para Android.

Google Chrome

Una mejor opción es usar el manifiesto de apps web.

El manifiesto de apps web (Chrome, Opera, Firefox, Samsung)

El manifiesto para aplicaciones web es un archivo JSON simple que te brinda a ti, el desarrollador, la capacidad de controlar cómo se muestra tu app al usuario en las áreas en las que espera ver apps (por ejemplo, la pantalla principal de un dispositivo móvil), indicar lo que el usuario puede iniciar y, lo que es más importante, cómo puede iniciarla. En el futuro, el manifiesto te permitirá tener aún más control sobre tu app, pero por ahora solo nos enfocamos en cómo se puede iniciar. En particular, haz lo siguiente:

  1. Cómo informar al navegador sobre el manifiesto
  2. Describir cómo iniciar

Una vez que hayas creado el manifiesto y esté alojado en tu sitio, solo debes agregar una etiqueta de vínculo en todas las páginas que incluyen tu app, de la siguiente manera:

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

Chrome admite manifiestos desde la versión 38 para Android (octubre de 2014) y te permite controlar cómo aparece tu app web cuando se instala en la pantalla principal (mediante las propiedades short_name, name y icons) y cómo debe iniciarse cuando el usuario hace clic en el ícono de inicio (a través de start_url, display y orientation).

A continuación, se muestra un ejemplo de manifiesto. No muestra todo lo que puede haber en un manifiesto.

{
  "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"
}

Esta función es completamente progresiva y te permite crear experiencias mejores y más integradas para los usuarios de un navegador que la admite.

Cuando un usuario agrega tu sitio o app a la pantalla principal, existe la intención de tratarlos como una app. Esto significa que debes dirigir al usuario a la funcionalidad de tu app en lugar de a la página de destino del producto. Por ejemplo, si se le solicita al usuario que acceda a tu app, entonces esa es una buena página para iniciar.

Apps de utilidad

La mayoría de las apps de utilidad se beneficiarán de inmediato. En el caso de esas apps, querrás que se inicien de manera independiente como el resto de las apps en una plataforma móvil. Para indicarle a una app que se inicie de forma independiente, agrega esto al manifiesto de apps web:

    "display": "standalone"
Juegos

La mayoría de los juegos aprovecharán un manifiesto inmediatamente. Se querrá iniciar la amplia mayoría de los juegos en pantalla completa y se fuerza una orientación específica.

Si estás desarrollando un juego con desplazamiento vertical o como Flappy Birds, lo más probable es que quieras que siempre esté en modo vertical.

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

Por otro lado, si creas un juego de habilidad mental o un juego como X-Com, es probable que quieras que el juego siempre use la orientación horizontal.

    "display": "fullscreen",
    "orientation": "landscape"
Sitios de noticias

En la mayoría de los casos, los sitios de noticias son experiencias basadas en contenido puro. Naturalmente, la mayoría de los desarrolladores no piensan en agregar un manifiesto a un sitio de noticias. El manifiesto te permitirá definir qué iniciar (la portada de tu sitio de noticias) y cómo iniciarlo (en pantalla completa o como una pestaña normal del navegador).

La decisión depende de ti y de cómo crees que les gustaría a tus usuarios acceder a tu experiencia. Si quieres que tu sitio tenga todos los navegadores Chrome que se espera que tengan, puedes configurar la pantalla como browser.

    "display": "browser"

Si quieres que tu sitio de noticias sienta que la mayoría de las apps centradas en noticias tratan sus experiencias como apps y quite de la IU todas las versiones de Chrome similares a la Web, puedes configurar la pantalla como standalone.

    "display": "standalone"

Simulación: esconder automáticamente la barra de direcciones

Puedes "simular la pantalla completa" ocultando automáticamente la barra de direcciones de la siguiente manera:

window.scrollTo(0, 1);

Este es un método bastante simple, la página se carga y se le indica a la barra del navegador que se quite del camino. Lamentablemente, no es estandarizado y no es muy compatible. También debes trabajar en varias peculiaridades.

Por ejemplo, los navegadores a menudo restablecen la posición en la página cuando el usuario regresa a ella. El uso de window.scrollTo anula esto, lo que resulta molesto para el usuario. Para solucionar esto, debes almacenar la última posición en localStorage y abordar los casos extremos (por ejemplo, si el usuario tiene la página abierta en varias ventanas).

Lineamientos de UX

Cuando compilas un sitio que aprovecha la pantalla completa, hay una serie de posibles cambios en la experiencia del usuario que debes conocer para poder crear un servicio que les encante a tus usuarios.

No dependas de los controles de navegación

iOS no tiene un botón Atrás de hardware ni un gesto de actualización. Por lo tanto, debes asegurarte de que los usuarios puedan navegar por la app sin bloquearse.

Puedes detectar con facilidad si ejecutas en pantalla completa o en modo instalado en todas las plataformas principales.

iOS

En iOS, puedes usar el valor booleano navigator.standalone para ver si el usuario inició desde la pantalla principal o no.

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

Manifiesto de apps web (Chrome, Opera, Samsung)

Cuando se inicia como una app instalada, Chrome no se ejecuta en una verdadera experiencia de pantalla completa, por lo que document.fullscreenElement muestra un valor nulo y los selectores CSS no funcionan.

Cuando el usuario solicita pantalla completa a través de un gesto en tu sitio, las APIs de pantalla completa estándar están disponibles, incluido el seudoselector CSS que te permite adaptar tu IU para reaccionar al estado de pantalla completa de la siguiente manera:

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

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

Si los usuarios inician tu sitio desde la pantalla principal, la consulta de medios display-mode se establecerá en lo que se definió en el manifiesto de apps web. En el caso de la pantalla completa pura, será:

@media (display-mode: fullscreen) {
}

Si el usuario inicia la aplicación en modo independiente, la consulta de medios display-mode será standalone:

@media (display-mode: standalone) {
}

Firefox

Cuando el usuario solicita pantalla completa a través de tu sitio o inicia la app en el modo de pantalla completa, están disponibles todas las APIs estándar de pantalla completa, incluido el seudoselector CSS, que te permite adaptar tu IU para reaccionar al estado de pantalla completa de la siguiente manera:

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

En IE, la seudoclase CSS no tiene un guion, pero funciona de manera similar en Chrome y Firefox.

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

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

Especificación

La ortografía en la especificación coincide con la sintaxis que utiliza IE.

selector:fullscreen {
  display: block;
}

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

Cómo mantener al usuario en la experiencia de pantalla completa

La API en pantalla completa puede ser un poco complicada a veces. Los proveedores del navegador no quieren bloquear a los usuarios en una página de pantalla completa, por lo que desarrollaron mecanismos para salir de la pantalla completa lo antes posible. Esto significa que no puedes crear un sitio web de pantalla completa que abarque varias páginas porque:

  • Para cambiar la URL de manera programática mediante window.location = "http://example.com", se sale de la pantalla completa.
  • Un usuario que haga clic en un vínculo externo dentro de tu página saldrá de la pantalla completa.
  • Si cambias la URL a través de la API de navigator.pushState, también se saldrá de la experiencia de pantalla completa.

Si quieres mantener al usuario en una experiencia de pantalla completa, tienes dos opciones:

  1. Usa los mecanismos de la app web instalable para activar el modo de pantalla completa.
  2. Administra el estado de tu IU y de la app con el fragmento #.

Si usas la #syntax para actualizar la URL (window.location = "#somestate") y escuchas el evento window.onhashchange, puedes usar la pila del historial del navegador para administrar los cambios en el estado de la aplicación, permitir que el usuario use sus botones Atrás de hardware u ofrecer una experiencia programática simple y programática con la API de History de la siguiente manera:

window.history.go(-1);

Permitir que el usuario elija cuándo activar el modo de pantalla completa

No hay nada más molesto para el usuario que un sitio web que hace algo inesperado. Cuando un usuario navega a tu sitio, no intentes engañarlo para que acceda a la pantalla completa.

No interceptes el primer evento táctil y llama a requestFullscreen().

  1. Es molesto.
  2. Es posible que, en algún momento, los navegadores decidan solicitarle al usuario que permita que la app ocupe la pantalla completa.

Si quieres iniciar la pantalla completa de las apps, considera usar las experiencias de instalación para cada plataforma.

No le envíes spam al usuario para que instale tu app en una pantalla principal

Si planeas ofrecer una experiencia de pantalla completa a través de los mecanismos de la app instalada, ten en cuenta al usuario.

  • Sé discreto. Usa un banner o un pie de página para indicarles que pueden instalar la app.
  • Si descartan el mensaje, no lo vuelvas a mostrar.
  • En una primera visita de los usuarios, es poco probable que quieran instalar la app, a menos que estén conformes con tu servicio. Considera sugerirles la instalación después de una interacción positiva en tu sitio.
  • Si un usuario visita tu sitio con frecuencia y no instala la app, es poco probable que instale la app en el futuro. No les sigas enviando spam.

Conclusión

Si bien no tenemos una API completamente estandarizada e implementada, con algunas de las indicaciones que se presentan en este artículo, puedes compilar con facilidad experiencias que aprovechen toda la pantalla del usuario, independientemente del cliente.

Comentarios