Personaliza la superposición de los controles de la ventana de la barra de título de tu AWP

Usa el área de la barra de título junto a los controles de la ventana para que tu AWP parezca más una app.

Si recuerdas mi artículo Haz que tu AWP se parezca más a una app, es posible que también lo recuerdes Mencioné cómo personalizar la barra de título de la app como para crear una experiencia similar a la de una aplicación. Este es un ejemplo de cómo podría verse esto que muestra la app de macOS Podcasts.

La barra de título de la app de macOS Podcasts que muestra botones de control multimedia y metadatos sobre el podcast que se está reproduciendo.
Una barra de título personalizada hace que tu AWP se sienta más como una app específica de una plataforma.
.

Es posible que sientas la tentación de objetar diciendo que Podcasts es una app de macOS no se ejecuta en un navegador y, por lo tanto, puede hacer lo que quiera sin tener que jugar por la las reglas de firewall. Es cierto, pero la buena noticia es que la función Superposición de controles de ventana este artículo, te permitirá crear interfaces de usuario similares para tu AWP.

Componentes de la superposición de controles de ventana

La superposición de controles de ventana consta de las siguientes cuatro subfunciones:

  1. El valor "window-controls-overlay" para el campo "display_override" en el manifiesto de la app web.
  2. Las variables de entorno de CSS titlebar-area-x, titlebar-area-y, titlebar-area-width y titlebar-area-height
  3. La estandarización de la propiedad de CSS -webkit-app-region que era propiedad anteriormente como el La propiedad app-region para definir regiones arrastrables en el contenido web.
  4. Un mecanismo para consultar y trabajar en la región de controles de ventana a través de la windowControlsOverlay miembro de window.navigator.

¿Qué es la superposición de controles de la ventana?

El área de la barra de título se refiere al espacio a la izquierda o derecha de los controles de la ventana (es decir, botones para minimizar, maximizar, cerrar, etc.) y a menudo contiene el título de la aplicación. Ventana La superposición de controles permite que las aplicaciones web progresivas (AWP) proporcionen una apariencia similar a la de una aplicación mediante el intercambio la barra de título de ancho completo existente para una pequeña superposición con los controles de la ventana. Esto permite los desarrolladores colocaran contenido personalizado en lo que antes era el área de la barra de título controlada por el navegador.

Estado actual

Paso Estado
1. Crear explicación Completo
2. Crea el borrador inicial de la especificación Completo
3. Recopila comentarios y iterar en el diseño En curso
4. Prueba de origen Completado
5. Lanzamiento Completo (en Chromium 104)

Cómo usar la superposición de controles de la ventana

Agrega window-controls-overlay al manifiesto de la app web

Una app web progresiva puede habilitar la superposición de controles de ventana agregando "window-controls-overlay" como el miembro principal de "display_override" en el manifiesto de la app web:

{
  "display_override": ["window-controls-overlay"]
}

La superposición de controles de ventana será visible solo cuando se cumplan las siguientes condiciones:

  1. La app no se abre en el navegador, sino en una ventana independiente de la AWP.
  2. El manifiesto incluye "display_override": ["window-controls-overlay"]. (El resto de los valores se a partir de esa fecha).
  3. La AWP se ejecuta en un sistema operativo de computadora de escritorio.
  4. El origen actual coincide con el origen para el que se instaló la AWP.

Como resultado, se obtiene un área de barra de título vacía con los controles de ventana normales a la izquierda o bien, según el sistema operativo.

La ventana de una app con una barra de título vacía con los controles de ventana a la izquierda.
Una barra de título vacía lista para el contenido personalizado.

Mover contenido a la barra de título

Ahora que hay espacio en la barra de título, puedes mover algo allí. Para este artículo, compiló una AWP de contenido destacado de Wikimedia. Una función útil para esta aplicación puede ser la búsqueda de palabras en los títulos de los artículos. El código HTML de la función de búsqueda se ve de la siguiente manera:

<div class="search">
  <img src="logo.svg" alt="Wikimedia logo." width="32" height="32" />
  <label>
    <input type="search" />
    Search for words in articles
  </label>
</div>

Para mover este div a la barra de título, se necesita un poco de CSS:

.search {
  /* Make sure the `div` stays there, even when scrolling. */
  position: fixed;
  /**
   * Gradient, because why not. Endless opportunities.
   * The gradient ends in `#36c`, which happens to be the app's
   * `<meta name="theme-color" content="#36c">`.
   */
  background-image: linear-gradient(90deg, #36c, #131313, 33%, #36c);
  /* Use the environment variable for the left anchoring with a fallback. */
  left: env(titlebar-area-x, 0);
  /* Use the environment variable for the top anchoring with a fallback. */
  top: env(titlebar-area-y, 0);
  /* Use the environment variable for setting the width with a fallback. */
  width: env(titlebar-area-width, 100%);
  /* Use the environment variable for setting the height with a fallback. */
  height: env(titlebar-area-height, 33px);
}

Puedes ver el efecto de este código en la siguiente captura de pantalla. La barra de título es totalmente responsiva. Cuándo cambias el tamaño de la ventana de la AWP, la barra de título reacciona como si estuviera compuesta por contenido HTML normal, que, de hecho, lo es.

La ventana de una app con una barra de búsqueda en la barra de título
La nueva barra de título está activa y responsiva.

Determina qué partes de la barra de título se pueden arrastrar

Si bien la captura de pantalla anterior sugiere que terminaste, aún no lo has hecho. La ventana de la AWP es ya no es arrastrable (excepto en un área muy pequeña), ya que los botones de los controles de las ventanas no son arrastrables, y el resto de la barra de título está formada por el Widget de la Búsqueda. Soluciona este problema con La propiedad de CSS app-region con un valor de drag. En el caso concreto, es correcto hacer todo excepto el elemento input arrastrable.

/* The entire search `div` is draggable… */
.search {
  -webkit-app-region: drag;
  app-region: drag;
}

/* …except for the `input`. */
input {
  -webkit-app-region: no-drag;
  app-region: no-drag;
}

Con este CSS implementado, el usuario puede arrastrar la ventana de la app como de costumbre arrastrando div, img, o label. Solo el elemento input es interactivo, por lo que se puede ingresar la búsqueda.

Detección de funciones

La compatibilidad con la superposición de controles de ventana se puede detectar probando la existencia de windowControlsOverlay:

if ('windowControlsOverlay' in navigator) {
  // Window Controls Overlay is supported.
}

Consulta la región de controles de ventana con windowControlsOverlay

Hasta ahora, el código tiene un problema: en algunas plataformas, los controles de la ventana están a la derecha, en a los demás, a la izquierda. Para empeorar la situación, los "tres puntos" El menú de Chrome cambiará según la plataforma. Esto significa que la imagen de fondo con gradiente lineal adaptarse dinámicamente para ejecutarse desde #131313maroon o maroon#131313maroon, de modo que se combina con el color de fondo maroon de la barra de título, que está determinado por <meta name="theme-color" content="maroon"> Para ello, puedes consultar La API de getTitlebarAreaRect() en la propiedad navigator.windowControlsOverlay

if ('windowControlsOverlay' in navigator) {
  const { x } = navigator.windowControlsOverlay.getTitlebarAreaRect();
  // Window controls are on the right (like on Windows).
  // Chrome menu is left of the window controls.
  // [ windowControlsOverlay___________________ […] [_] [■] [X] ]
  if (x === 0) {
    div.classList.add('search-controls-right');
  }
  // Window controls are on the left (like on macOS).
  // Chrome menu is right of the window controls overlay.
  // [ [X] [_] [■] ___________________windowControlsOverlay [⋮] ]
  else {
    div.classList.add('search-controls-left');
  }
} else {
  // When running in a non-supporting browser tab.
  div.classList.add('search-controls-right');
}

En lugar de tener la imagen de fondo directamente en las reglas de CSS de la clase .search (como antes), el El código modificado ahora usa dos clases que el código anterior configura de forma dinámica.

/* For macOS: */
.search-controls-left {
  background-image: linear-gradient(90deg, #36c, 45%, #131313, 90%, #36c);
}

/* For Windows: */
.search-controls-right {
  background-image: linear-gradient(90deg, #36c, #131313, 33%, #36c);
}

Determina si la superposición de controles de la ventana es visible

En todas las circunstancias, la superposición de los controles de la ventana no se puede ver en el área de la barra de título. Si bien no estará disponible en navegadores que no admiten la función de superposición de controles de ventana, tampoco estará allí cuando la AWP en cuestión se ejecute en una pestaña. Para detectar esta situación, puedes consulta la propiedad visible de windowControlsOverlay:

if (navigator.windowControlsOverlay.visible) {
  // The window controls overlay is visible in the title bar area.
}

Como alternativa, también puedes usar la consulta de medios display-mode en JavaScript o CSS:

// Create the query list.
const mediaQueryList = window.matchMedia('(display-mode: window-controls-overlay)');

// Define a callback function for the event listener.
function handleDisplayModeChange(mql) {
  // React on display mode changes.
}

// Run the display mode change handler once.
handleDisplayChange(mediaQueryList);

// Add the callback function as a listener to the query list.
mediaQueryList.addEventListener('change', handleDisplayModeChange);
@media (display-mode: window-controls-overlay) { 
  /* React on display mode changes. */ 
}

Cómo recibir notificaciones de cambios de geometría

Consultar el área de superposición de los controles de ventana con getTitlebarAreaRect() puede bastar para una operación única opciones como configurar la imagen de fondo correcta según dónde estén los controles de la ventana, en otros casos, se necesita un control más detallado. Por ejemplo, un posible caso de uso podría ser Adapta la superposición de los controles de la ventana en función del espacio disponible y agrega un chiste en la ventana. la superposición de controles cuando hay suficiente espacio.

La ventana controla el área superpuesta en una ventana estrecha con texto acortado.
Controles de la barra de título adaptados a una ventana estrecha

Para recibir notificaciones de los cambios de geometría, te suscribes a navigator.windowControlsOverlay.ongeometrychange o configurando un objeto de escucha de eventos para la geometrychange evento. Este evento solo se activará cuando la superposición de los controles de la ventana esté visible, la es cuando navigator.windowControlsOverlay.visible es true.

const debounce = (func, wait) => {
  let timeout;
  return function executedFunction(...args) {
    const later = () => {
      clearTimeout(timeout);
      func(...args);
    };
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
  };
};

if ('windowControlsOverlay' in navigator) {
  navigator.windowControlsOverlay.ongeometrychange = debounce((e) => {
    span.hidden = e.titlebarAreaRect.width < 800;
  }, 250);
}

En lugar de asignar una función a ongeometrychange, también puedes agregar un objeto de escucha de eventos a windowControlsOverlay como se muestra a continuación. Puedes leer acerca de la diferencia entre ambos en MDN (en inglés)

navigator.windowControlsOverlay.addEventListener(
  'geometrychange',
  debounce((e) => {
    span.hidden = e.titlebarAreaRect.width < 800;
  }, 250),
);

Compatibilidad cuando se ejecuta en una pestaña y en navegadores no compatibles

Hay dos casos posibles que debes considerar:

  • Es el caso en el que una app se ejecuta en un navegador que admite la superposición de controles de ventana, pero cuando la aplicación se usa en una pestaña del navegador.
  • Es el caso en el que una app se ejecuta en un navegador que no admite la superposición de controles de ventana.

En ambos casos, de forma predeterminada, el código HTML creado para los controles de ventana La superposición se mostrará intercalada como el contenido HTML normal y las variables env(). valores de resguardo para el posicionamiento. En navegadores compatibles, también puedes optar por no mostrar el HTML designado para la superposición de controles de ventana verificando la propiedad visible de la superposición y si informa false y, luego, oculta el contenido HTML.

Una AWP que se ejecuta en una pestaña del navegador con la superposición de controles de ventana que se muestra en el cuerpo
Los controles diseñados para la barra de título se pueden mostrar fácilmente en el cuerpo en navegadores más antiguos.

Como recordatorio, los navegadores no compatibles no tendrán en cuenta las "display_override", o no reconoce la propiedad del manifiesto "window-controls-overlay" y, por lo tanto, usa el siguiente valor posible según la cadena de resguardo por ejemplo, "standalone".

Una AWP que se ejecuta en modo independiente con la superposición de controles de ventana que se muestra en el cuerpo.
Los controles diseñados para la barra de título se pueden mostrar fácilmente en el cuerpo en navegadores más antiguos.

Consideraciones sobre la IU

Aunque puede resultar tentador, no se recomienda crear un menú desplegable clásico en el área Window Controls Overlay. Hacerlo infringiría lineamientos de diseño en macOS, una plataforma en la que los usuarios esperan barras de menú (tanto las proporcionadas por el sistema como personalizadas) en la parte superior de la pantalla.

Si tu app proporciona una experiencia de pantalla completa, considera cuidadosamente si tiene sentido para que la superposición de controles de ventana forme parte de la vista de pantalla completa. Es posible que quieras reorganizar tu diseño cuando onfullscreenchange se activa el evento.

Demostración

Creé una demostración que puedes usar en en distintos navegadores compatibles y no compatibles, en el estado instalado y en el no instalado. Para la experiencia real de Window Controls Overlay, debes instalar la app. A continuación, puedes ver dos capturas de pantalla de lo que sucederá. El El código fuente de la app está disponible en Glitch.

La app de demostración de contenido destacado de Wikimedia con superposición de controles de ventana.
La app de demostración está disponible para la experimentación.

La función de búsqueda en la superposición de controles de ventana funciona completamente:

La app de demostración de contenido destacado de Wikimedia con superposición de controles de ventana y búsqueda activa del término &quot;cleopa...&quot; destacando uno de los artículos que contienen el término coincidente &quot;Cleopatra&quot;.
Función de búsqueda que usa la superposición de controles de la ventana.

Consideraciones de seguridad

El equipo de Chromium diseñó e implementó la API de Window Controls Overlay usando los principios básicos se definen en Controla el acceso a las funciones potentes de la plataforma web, incluida la información la transparencia y la ergonomía.

Falsificación de identidad

Dar a los sitios control parcial de la barra de título permite a los desarrolladores falsificar el contenido de qué era antes una región de confianza controlada por el navegador. Actualmente, en los navegadores Chromium, la función incluye una barra de título que, en el inicio inicial, muestra el título de la página web a la izquierda el origen de la página a la derecha (seguido del botón “configuración y más” y la ventana de seguridad). Después de unos segundos, el texto de origen desaparece. Si el navegador está configurado de derecha a izquierda (RTL), este diseño está invertido de modo que el texto de origen queda a la izquierda. Esto abrirá el Los controles de ventana se superponen para falsificar la identidad del origen si no hay suficiente relleno entre el origen y el borde derecho de la superposición. Por ejemplo, el origen "evil.ltd" podría agregarle un nombre de usuario el sitio "google.com", lo que lleva a los usuarios a creer que la fuente es confiable. El plan es mantener esto texto de origen para que los usuarios sepan cuál es el origen de la aplicación y puedan asegurarse de que coincida con su con sus expectativas. En el caso de los navegadores configurados con escritura de derecha a izquierda, debe haber suficiente relleno a la derecha del origen. texto para evitar que un sitio web malicioso agregue el origen no seguro con uno confiable.

Creación de huellas digitales

La habilitación de la superposición de controles de ventana y las regiones arrastrables no aparecen. problemas de privacidad considerables, además de la detección de funciones. Sin embargo, debido a diferentes tamaños y posiciones de los botones de control de ventana en las de la industria, navigator.windowControlsOverlay.getTitlebarAreaRect() El método muestra un DOMRect. cuya posición y dimensiones revelan información sobre el sistema operativo tras que se ejecuta en el navegador. Actualmente, los desarrolladores ya pueden descubrir de la cadena de usuario-agente, pero por cuestiones relacionadas con la creación de huellas digitales, debate sobre cómo inmovilizar la cadena de UA y unificar las versiones del SO. Hay un esfuerzo constante dentro de la comunidad de navegadores para comprender la frecuencia con la que el tamaño de la superposición de los controles de la ventana cambia entre las plataformas, a medida que es que son bastante estables en todas las versiones de SO y, por lo tanto, no ser útil para observar versiones secundarias del SO. Aunque se trata de un posible de huellas digitales, solo se aplica a las AWP instaladas que usan la configuración barra de título y no se aplica al uso general del navegador. Además, el La API de navigator.windowControlsOverlay no estará disponible para iframes incorporados en una AWP

Si navegas a un origen diferente dentro de una AWP, esta volverá a la versión independiente normal. de la barra de título aunque cumpla con los criterios anteriores y se inicie con la superposición de controles de la ventana. De esta forma, se adapta la barra negra que aparece en la navegación a un origen diferente. Después del cuando regresas al origen original, se volverá a usar la superposición de controles de ventana.

Una barra de URL negra para la navegación fuera de origen.
Se muestra una barra negra cuando el usuario navega a un origen diferente.

Comentarios

El equipo de Chromium quiere conocer tu experiencia con la API de Window Controls Overlay.

Cuéntanos sobre el diseño de la API

¿Algo en la API no funciona como esperabas? ¿O faltan métodos o propiedades que necesitas para implementar tu idea? Haz una pregunta o comentario sobre la seguridad modelo? Informa un problema de especificaciones en el repositorio de GitHub correspondiente o agrega lo que piensas a un problema existente.

Informar un problema con la implementación

¿Encontraste un error en la implementación de Chromium? ¿O la implementación es diferente de la especificación? Informa un error en new.crbug.com. Asegúrate de incluir tantos detalles como puedas instrucciones simples para la reproducción y, luego, ingresa UI>Browser>WebAppInstalls en Components. . Glitch funciona muy bien para compartir repros rápidos y fáciles.

Demuestra compatibilidad con la API

¿Planeas usar la API de Window Controls Overlay? Tu asistencia pública ayuda al equipo de Chromium para priorizar funciones y muestra a otros proveedores de navegadores la importancia de admitirlas.

Envía un tweet a @ChromiumDev con el #WindowControlsOverlay hashtag y cuéntanos dónde y cómo lo usas.

Vínculos útiles

Agradecimientos

Se implementó y especificó la superposición de controles de la ventana Amanda Baker, del equipo de Microsoft Edge. Joe Medley revisó este artículo, y Kenneth Rohde Christiansen. Hero image de Sigmund en Unsplash.