Personalizza l'overlay dei controlli della finestra della barra del titolo della PWA

Usa l'area della barra del titolo accanto ai controlli della finestra per far sembrare la tua PWA più simile a un'app.

Se ricordi l'articolo Rendi la PWA più simile a un'app, potresti ricordare come ho citato la personalizzazione della barra del titolo dell'app come strategia per creare un'esperienza più simile a un'app. Ecco un esempio di come può apparire nell'app macOS Podcasts.

Barra del titolo dell'app macOS Podcasts che mostra i pulsanti di controllo dei contenuti multimediali e i metadati relativi al podcast attualmente in riproduzione.
Una barra del titolo personalizzata rende la tua PWA più simile a un'app specifica per la piattaforma.

Potresti avere la tentazione di opporti al fatto che Podcasts è un'app macOS specifica della piattaforma che non viene eseguita in un browser e che pertanto può fare ciò che vuole senza dover rispettare le regole del browser. Vero, ma la buona notizia è che la funzionalità Overlay dei controlli delle finestre, che è l'argomento di questo articolo, ti consente presto di creare interfacce utente simili per la tua PWA.

Componenti Overlay dei controlli finestra

L'overlay dei controlli della finestra è costituito da quattro funzionalità secondarie:

  1. Il valore "window-controls-overlay" per il campo "display_override" nel file manifest dell'app web.
  2. Le variabili di ambiente CSS titlebar-area-x, titlebar-area-y, titlebar-area-width e titlebar-area-height.
  3. Standardizzazione della proprietà CSS di proprietà -webkit-app-region come proprietà app-region per definire regioni trascinabili nei contenuti web.
  4. Un meccanismo per eseguire query e aggirare la regione dei controlli delle finestre tramite il membro windowControlsOverlay di window.navigator.

Che cos'è l'overlay dei controlli delle finestre

L'area della barra del titolo si riferisce allo spazio a sinistra o a destra dei controlli delle finestre (ovvero i pulsanti per ridurre a icona, ingrandire, chiudere e così via) e spesso contiene il titolo dell'applicazione. L'overlay dei controlli delle finestre consente alle applicazioni web progressive (PWA) di offrire un aspetto più simile a quello di un'app scambiando la barra del titolo a larghezza intera esistente con un piccolo overlay contenente i controlli delle finestre. Ciò consente agli sviluppatori di inserire contenuti personalizzati in quella che in precedenza era l'area della barra dei titoli controllata dal browser.

Stato attuale

Passaggio Stato
1. Crea messaggio esplicativo Completato
2. Crea una bozza iniziale della specifica Completato
3. Raccogli feedback e ottimizza il design In corso
4. Prova dell'origine Completo
5. Lancio Completata (in Chromium 104)

Come utilizzare l'overlay dei controlli delle finestre

Aggiunta di window-controls-overlay al manifest dell'app web in corso...

Un'app web progressiva può attivare l'overlay dei controlli delle finestre aggiungendo "window-controls-overlay" come membro "display_override" principale nel file manifest dell'app web:

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

L'overlay dei controlli delle finestre sarà visibile solo se vengono soddisfatte tutte le seguenti condizioni:

  1. L'app non viene aperta nel browser, ma in una finestra PWA separata.
  2. Il file manifest include "display_override": ["window-controls-overlay"]. (Altri valori sono consentiti successivamente.)
  3. La PWA viene eseguita su un sistema operativo desktop.
  4. L'origine corrente corrisponde a quella per cui è stata installata la PWA.

Il risultato è un'area della barra del titolo vuota con i normali controlli della finestra a sinistra o a destra, a seconda del sistema operativo.

Una finestra dell'app con una barra del titolo vuota con i controlli delle finestre a sinistra.
Una barra del titolo vuota pronta per i contenuti personalizzati.

Spostamento dei contenuti nella barra del titolo

Ora che c'è spazio nella barra del titolo, puoi spostare qualcosa al suo interno. Per questo articolo ho creato una PWA con contenuti in primo piano Wikimedia. Una funzionalità utile per questa app potrebbe essere la ricerca di parole nei titoli degli articoli. Il codice HTML per la funzione di ricerca sarà simile al seguente:

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

Per spostare questo div nella barra del titolo, sono necessari alcuni 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);
}

Puoi vedere l'effetto di questo codice nello screenshot di seguito. La barra del titolo è completamente reattiva. Quando ridimensioni la finestra PWA, la barra del titolo reagisce come se fosse composta da normali contenuti HTML, che in realtà è.

Una finestra dell&#39;app con una barra di ricerca nella barra del titolo.
La nuova barra del titolo è attiva e reattiva.

Stabilire quali parti della barra del titolo è trascinabile

Anche se lo screenshot qui sopra suggerisce che hai finito, non l'hai ancora fatto. La finestra PWA non è più trascinabile (a parte un'area molto piccola), poiché i pulsanti dei controlli della finestra non sono aree di trascinamento e il resto della barra del titolo è costituito dal widget di ricerca. Risolvi il problema utilizzando la proprietà CSS app-region con un valore di drag. Nel caso concreto, è possibile trascinare tutto ciò che non l'elemento input.

/* 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;
}

Una volta configurato questo CSS, l'utente può trascinare la finestra dell'app come al solito trascinando div, img o label. Solo l'elemento input è interattivo, quindi è possibile inserire la query di ricerca.

Rilevamento delle funzionalità

Il supporto dell'overlay dei controlli delle finestre può essere rilevato testando l'esistenza di windowControlsOverlay:

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

Esecuzione di query sulla regione dei controlli delle finestre con windowControlsOverlay

Il codice ha un problema: su alcune piattaforme i controlli delle finestre si trovano a destra e su altre a sinistra. A peggiorare le cose, anche il menu di Chrome con tre puntini cambierà posizione, a seconda della piattaforma. Ciò significa che l'immagine di sfondo a gradiente lineare deve essere adattata in modo dinamico per essere eseguita da #131313maroon o maroon#131313maroon, in modo che si confonda con il colore di sfondo maroon della barra del titolo, determinato da <meta name="theme-color" content="maroon">. A tal fine, puoi eseguire una query all'API getTitlebarAreaRect() sulla proprietà 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');
}

Anziché avere l'immagine di sfondo nelle regole CSS della classe .search direttamente (come in precedenza), il codice modificato ora utilizza due classi impostate dinamicamente dal codice precedente.

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

Determinare se l'overlay dei controlli delle finestre è visibile

L'overlay dei controlli delle finestre non sarà visibile nell'area della barra del titolo in tutti i casi. Sebbene non sia presente nei browser che non supportano la funzionalità di overlay dei controlli delle finestre, non sarà disponibile nemmeno quando la PWA in questione viene eseguita in una scheda. Per rilevare questa situazione, puoi eseguire una query sulla proprietà visible di windowControlsOverlay:

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

In alternativa, puoi anche utilizzare la query supporti display-mode in JavaScript e/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. */ 
}

Ricezione di notifiche per modifiche alla geometria

Eseguire query sull'area di overlay dei controlli delle finestre con getTitlebarAreaRect() può essere sufficiente per operazioni una tantum come l'impostazione dell'immagine di sfondo corretta in base alla posizione dei controlli delle finestre, ma in altri casi è necessario un controllo più granulare. Ad esempio, un possibile caso d'uso potrebbe essere adattare l'overlay dei controlli delle finestre in base allo spazio disponibile e aggiungere una barzelletta direttamente nell'overlay dei controlli delle finestre quando lo spazio è sufficiente.

I controlli della finestra si sovrappongono a una finestra stretta con testo abbreviato.
Controlli della barra del titolo adattati a una finestra stretta.

Per ricevere una notifica in caso di modifiche alla geometria, iscriviti a navigator.windowControlsOverlay.ongeometrychange o imposta un listener di eventi per l'evento geometrychange. Questo evento si attiva solo quando l'overlay dei controlli delle finestre è visibile, ovvero quando navigator.windowControlsOverlay.visible è 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);
}

Anziché assegnare una funzione a ongeometrychange, puoi anche aggiungere un listener di eventi a windowControlsOverlay come indicato di seguito. Puoi scoprire la differenza tra i due su MDN.

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

Compatibilità quando in esecuzione in una scheda e su browser non supportati

Esistono due possibili casi da prendere in considerazione:

  • Il caso in cui un'app è in esecuzione in un browser che supporta l'overlay dei controlli delle finestre, ma in cui l'app viene utilizzata in una scheda del browser.
  • Il caso in cui un'app è in esecuzione in un browser che non supporta l'overlay dei controlli delle finestre.

In entrambi i casi, per impostazione predefinita l'HTML creato per l'overlay dei controlli delle finestre verrà visualizzato in linea come i normali contenuti HTML e i valori di riserva delle variabili env() verranno attivati per il posizionamento. Sui browser supportati, puoi anche decidere di non visualizzare il codice HTML designato per l'overlay dei controlli delle finestre controllando la proprietà visible dell'overlay e, se riporta false, nascondendo i contenuti HTML.

Una PWA in esecuzione in una scheda del browser con l&#39;overlay dei controlli delle finestre visualizzato nel corpo.
I controlli destinati alla barra del titolo possono essere facilmente visualizzati nel corpo nei browser meno recenti.

Ti ricordiamo che i browser non supportati non prenderanno in considerazione la proprietà manifest dell'app web "display_override" o non riconosceranno il valore "window-controls-overlay" e quindi utilizzeranno il successivo valore possibile in base alla catena di fallback, ad esempio "standalone".

Una PWA in esecuzione in modalità autonoma con l&#39;overlay dei controlli delle finestre visualizzato nel corpo.
I controlli destinati alla barra del titolo possono essere facilmente visualizzati nel corpo nei browser meno recenti.

Considerazioni relative all'interfaccia utente

Per quanto possa essere allettante, si sconsiglia di creare un classico menu a discesa nell'area Sovrapposizione controlli finestra. Ciò violerebbe le linee guida sulla progettazione su macOS, una piattaforma su cui gli utenti si aspettano barre dei menu (sia quelle fornite dal sistema sia quelle personalizzate) nella parte superiore dello schermo.

Se l'app offre un'esperienza a schermo intero, valuta attentamente se ha senso che l'overlay dei controlli delle finestre faccia parte della visualizzazione a schermo intero. Potrebbe essere utile riorganizzare il layout quando viene attivato l'evento onfullscreenchange.

Demo

Ho creato una demo che puoi utilizzare in diversi browser di supporto e non, nonché nello stato installato e non installato. Per l'esperienza effettiva di overlay dei controlli delle finestre, devi installare l'app. Di seguito puoi vedere due screenshot di cosa aspettarsi. Il codice sorgente dell'app è disponibile su Glitch.

L&#39;app demo Contenuti in primo piano Wikimedia con l&#39;overlay dei controlli delle finestre.
L'app demo è disponibile per la sperimentazione.

La funzionalità di ricerca nell'overlay dei controlli delle finestre è completamente funzionante:

L&#39;app demo di Contenuti in primo piano di Wikimedia con l&#39;overlay dei controlli della finestra e la ricerca attiva del termine &quot;cleopa...&quot;, che evidenzia uno degli articoli con il termine corrispondente &quot;Cleopatra&quot;.
Una funzionalità di ricerca che utilizza l'overlay dei controlli delle finestre.

Considerazioni sulla sicurezza

Il team di Chromium ha progettato e implementato l'API Window Controls Overlay utilizzando i principi fondamentali definiti nella sezione Controllo dell'accesso alle funzionalità avanzate della piattaforma web, tra cui controllo dell'utente, trasparenza ed ergonomia.

Spoofing

Concedere ai siti il controllo parziale della barra del titolo lascia agli sviluppatori lo spazio per eseguire lo spoofing dei contenuti in quella che in precedenza era un'area geografica affidabile e controllata dal browser. Attualmente, nei browser Chromium, la modalità autonoma include una barra del titolo che, all'avvio iniziale, mostra il titolo della pagina web a sinistra e l'origine della pagina a destra (seguita dal pulsante "Impostazioni e altro" e dai controlli delle finestre). Dopo alcuni secondi, il testo di origine scompare. Se il browser è impostato su una lingua da destra a sinistra (RTL), il layout viene capovolto in modo che il testo di origine sia a sinistra. In questo modo si apre l'overlay dei controlli della finestra per eseguire lo spoofing dell'origine se non è presente una spaziatura interna insufficiente tra l'origine e il bordo destro dell'overlay. Ad esempio, all'origine "evil.ltd" potrebbe essere aggiunto un sito attendibile "google.com", in modo da far credere agli utenti che la fonte sia affidabile. Il piano è mantenere questo testo di origine in modo che gli utenti sappiano qual è l'origine dell'app e possono assicurarsi che corrisponda alle loro aspettative. Per i browser configurati in RTL, deve essere presente una spaziatura interna sufficiente a destra del testo di origine per evitare che un sito web dannoso aggiunga l'origine non sicura con un'origine attendibile.

Impronta

L'attivazione dell'overlay dei controlli delle finestre e delle regioni trascinabili non pone notevoli problemi di privacy oltre al rilevamento delle funzionalità. Tuttavia, a causa delle diverse dimensioni e posizioni dei pulsanti di controllo delle finestre nei diversi sistemi operativi, il metodo navigator.windowControlsOverlay.getTitlebarAreaRect() restituisce un DOMRect la cui posizione e dimensioni rivelano informazioni sul sistema operativo su cui è in esecuzione il browser. Attualmente gli sviluppatori possono già trovare il sistema operativo dalla stringa dello user agent, ma, a causa di problemi relativi al fingerprinting, si discute del blocco della stringa UA e dell'unificazione delle versioni del sistema operativo. All'interno della community dei browser c'è un impegno costante per capire la frequenza con cui le dimensioni degli overlay dei controlli delle finestre cambiano sulle varie piattaforme, dato che attualmente si presuppone che siano abbastanza stabili tra le varie versioni del sistema operativo e che quindi non sarebbero utili per osservare versioni secondarie del sistema operativo. Sebbene si tratti di un potenziale problema di fingerprint, si applica solo alle PWA installate che utilizzano la funzionalità della barra dei titoli personalizzata e non all'utilizzo generale del browser. Inoltre, l'API navigator.windowControlsOverlay non sarà disponibile per gli iframe incorporati in una PWA.

Se si naviga verso un'origine diversa all'interno di una PWA, torni alla normale barra dei titoli autonoma, anche se soddisfa i criteri precedenti e viene avviata con l'overlay dei controlli delle finestre. per inserire la barra nera visualizzata durante la navigazione verso un'origine diversa. Dopo essere tornato all'origine originale, verrà utilizzato di nuovo l'overlay dei controlli delle finestre.

Una barra degli URL nera per la navigazione fuori origine.
Una barra nera viene mostrata quando l'utente passa a un'origine diversa.

Feedback

Il team di Chromium vuole conoscere la tua esperienza con l'API Window Controls Overlay.

Parlaci della progettazione dell'API

C'è qualcosa nell'API che non funziona come previsto? Oppure mancano metodi o proprietà di cui hai bisogno per implementare la tua idea? Hai domande o commenti sul modello di sicurezza? Segnala un problema relativo alle specifiche nel repository GitHub corrispondente o aggiungi le tue opinioni su un problema esistente.

Segnala un problema con l'implementazione

Hai trovato un bug nell'implementazione di Chromium? Oppure l'implementazione è diversa dalle specifiche? Segnala un bug all'indirizzo new.crbug.com. Assicurati di includere il maggior numero di dettagli possibile e di istruzioni semplici per la riproduzione e inserisci UI>Browser>WebAppInstalls nella casella Componenti. Glitch funziona benissimo per condividere riproduzioni rapide e semplici.

Mostra il supporto dell'API

Intendi utilizzare l'API Window Controls Overlay? Il supporto pubblico aiuta il team di Chromium a dare la priorità alle funzionalità e mostra ad altri fornitori di browser l'importanza di supportarle.

Invia un tweet a @ChromiumDev con l'hashtag #WindowControlsOverlay e facci sapere dove e come lo stai usando.

Link utili

Ringraziamenti

L'overlay dei controlli della finestra è stato implementato e specificato da Amanda Baker del team di Microsoft Edge. Questo articolo è stato recensito da Joe Medley e Kenneth Rohde Christiansen. Immagine hero di Sigmund su Unsplash.