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

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

Se ricordi il mio articolo Rendere la tua PWA più simile a un'app, potresti ricordare come ho menzionato 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 l'app Podcasts per macOS.

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

Ora potresti essere tentato di obiettare dicendo che Podcasts è un'app per macOS specifica della piattaforma che non viene eseguita in un browser e quindi può fare ciò che vuole senza dover rispettare le regole del browser. È vero, ma la buona notizia è che la funzionalità di overlay dei controlli della finestra, che è l'argomento di questo articolo, a breve ti consentirà di creare interfacce utente simili per la tua PWA.

Componenti dell'overlay dei controlli delle finestre

L'overlay dei controlli finestra è composto da quattro sottofunzionalità:

  1. Il valore "window-controls-overlay" per il campo "display_override" nel manifest dell'app web.
  2. Le variabili di ambiente CSS titlebar-area-x, titlebar-area-y, titlebar-area-width e titlebar-area-height.
  3. La standardizzazione della proprietà CSS -webkit-app-region, precedentemente proprietaria, come proprietà app-region per definire le regioni trascinabili nei contenuti web.
  4. Un meccanismo per eseguire query sulla regione dei controlli della finestra e aggirarla tramite l'elemento windowControlsOverlay di window.navigator.

Che cos'è l'overlay dei controlli della finestra

L'area della barra del titolo si riferisce allo spazio a sinistra o a destra dei controlli della finestra (ovvero i pulsanti per ridurre a icona, ingrandire, chiudere e così via) e spesso contiene il titolo dell'applicazione. L'overlay dei controlli della finestra consente alle applicazioni web progressive (PWA) di offrire un'esperienza più simile a quella di un'app sostituendo la barra del titolo esistente a larghezza intera con un piccolo overlay contenente i controlli della finestra. In questo modo, gli sviluppatori possono inserire contenuti personalizzati nell'area della barra del titolo precedentemente controllata dal browser.

Stato attuale

Passaggio Stato
1. Creare un'animazione esplicativa Completato
2. Creare una bozza iniziale della specifica Completato
3. Raccogli feedback e esegui l'iterazione sul design In corso
4. Prova dell'origine Completa
5. Lancio Completa (in Chromium 104)

Come utilizzare l'overlay dei controlli finestra

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

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

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

L'overlay dei controlli della finestra sarà visibile solo se si verificano tutte le seguenti condizioni:

  1. L'app non si apre nel browser, ma in una finestra PWA separata.
  2. Il file manifest include "display_override": ["window-controls-overlay"]. (Dopo questa data sono consentiti altri valori).
  3. La PWA è in esecuzione 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 controlli della finestra normali a sinistra o a destra, a seconda del sistema operativo.

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

Spostare i contenuti nella barra del titolo

Ora che c'è spazio nella barra del titolo, puoi spostare qualcosa lì. Per questo articolo, ho sviluppato una PWA di contenuti in primo piano di Wikimedia. Una funzionalità utile per questa app potrebbe essere la ricerca di parole nei titoli degli articoli. Il codice HTML per la funzionalità di ricerca ha il seguente aspetto:

<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, è necessario un po' di 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 adattabile. Quando ridimensioni la finestra della PWA, la barra del titolo reagisce come se fosse composta da normali contenuti HTML, che in effetti è.

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

Determinare quali parti della barra del titolo sono trascinabili

Anche se lo screenshot qui sopra suggerisce che hai finito, non è ancora così. La finestra della PWA non è più trascinabile (tranne che per un'area molto piccola), poiché i pulsanti di controllo della finestra non sono aree di trascinamento e il resto della barra del titolo è costituito dal widget di ricerca. Per risolvere il problema, utilizza la proprietà CSS app-region con un valore di drag. Nel caso specifico, è possibile trascinare tutto tranne 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;
}

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

Rilevamento di funzionalità

Il supporto dell'overlay dei controlli della finestra può essere rilevato verificando l'esistenza di: windowControlsOverlay

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

Eseguire query sulla regione dei controlli della finestra con windowControlsOverlay

Finora il codice ha un problema: su alcune piattaforme i controlli della finestra sono a destra, su altre a sinistra. A peggiorare le cose, anche il menu di Chrome con i "tre puntini" cambierà posizione in base alla piattaforma. Ciò significa che l'immagine di sfondo con sfumatura lineare deve essere adattata dinamicamente in modo da passare da #131313maroon o maroon#131313maroon, in modo da fondersi con il colore di sfondo maroon della barra del titolo, determinato da <meta name="theme-color" content="maroon">. Per farlo, puoi eseguire una query sull'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 direttamente nelle regole CSS della classe .search (come prima), il codice modificato ora utilizza due classi impostate dinamicamente dal codice riportato sopra.

/* 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 della finestra non sarà visibile nell'area della barra del titolo in tutte le circostanze. Naturalmente, non sarà presente sui browser che non supportano la funzionalità di overlay dei controlli della finestra, né quando la PWA in questione viene eseguita in una scheda. Per rilevare questa situazione, puoi eseguire query sulla proprietà visible di windowControlsOverlay:

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

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

Ricevere notifiche delle modifiche alla geometria

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

Area di overlay dei controlli della finestra in una finestra stretta con testo abbreviato.
I controlli della barra del titolo sono adattati a una finestra stretta.

Puoi ricevere una notifica delle modifiche alla geometria sottoscrivendo un abbonamento a navigator.windowControlsOverlay.ongeometrychange o configurando un gestore eventi per l'evento navigator.windowControlsOverlay.ongeometrychange.geometrychange Questo evento viene attivato solo quando l'overlay dei controlli della finestra è 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 gestore 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 viene eseguito in una scheda e su browser non supportati

Esistono due possibili casi da considerare:

  • Il caso in cui un'app sia in esecuzione in un browser che supporta Window Controls Overlay, ma in cui l'app viene utilizzata in una scheda del browser.
  • Il caso in cui un'app venga eseguita in un browser che non supporta l'overlay dei controlli della finestra.

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

Una PWA in esecuzione in una scheda del browser con l&#39;overlay dei controlli della finestra visualizzato nel corpo.
Nei browser meno recenti, i controlli destinati alla barra del titolo possono essere facilmente visualizzati nel corpo.

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

Una PWA in esecuzione in modalità autonoma con il rivestimento dei controlli della finestra 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

Sebbene possa essere allettante, non è consigliabile creare un menu a discesa classico nell'area dell'overlay dei controlli della finestra. In questo modo verrebbero violate le linee guida per il design su macOS, una piattaforma su cui gli utenti si aspettano di trovare barre dei menu (sia quelle fornite dal sistema sia quelle personalizzate) nella parte superiore dello schermo.

Se la tua app offre un'esperienza a schermo intero, valuta attentamente se ha senso includere l'overlay dei controlli della finestra nella visualizzazione a schermo intero. Potresti dover riorganizzare il layout quando viene attivato l'evento onfullscreenchange.

Demo

Ho creato una demo che puoi utilizzare in diversi browser supportati e non supportati e nello stato di installazione e non installazione. Per provare l'esperienza effettiva dell'overlay dei controlli della finestra, devi installare l'app. Di seguito puoi vedere due screenshot di cosa aspettarti. Il codice sorgente dell'app è disponibile su Glitch.

L&#39;app demo Contenuti in primo piano di Wikimedia con overlay dei controlli della finestra.
L'app demo è disponibile per la sperimentazione.

La funzionalità di ricerca nell'overlay dei controlli della finestra è completamente funzionale:

L&#39;app demo dei contenuti in primo piano di Wikimedia con overlay dei controlli della finestra e ricerca attiva del termine &quot;cleopa…&quot; che mette in evidenza uno degli articoli con il termine corrispondente &quot;Cleopatra&quot;.
Una funzionalità di ricerca che utilizza l'overlay dei controlli finestra.

Considerazioni sulla sicurezza

Il team di Chromium ha progettato e implementato l'API Window Controls Overlay utilizzando i principi fondamentali definiti in Controllo dell'accesso a funzionalità potenti della piattaforma web, tra cui il controllo dell'utente, la trasparenza e l'ergonomia.

Spoofing

Dare ai siti il controllo parziale della barra del titolo lascia spazio agli sviluppatori per contraffare i contenuti in quella che precedentemente era una regione attendibile controllata dal browser. Attualmente, nei browser Chromium, la modalità autonoma include una barra del titolo che al primo avvio mostra il titolo della pagina web a sinistra e l'origine della pagina a destra (seguita dal pulsante "Impostazioni e altro" e dai controlli della finestra). Dopo alcuni secondi, il testo di origine scompare. Se il browser è impostato su una lingua da destra a sinistra (RTL), questo layout viene capovolto in modo che il testo di origine sia a sinistra. Viene aperto l'overlay dei controlli della finestra per falsificare l'origine se lo spazio tra l'origine e il bordo destro dell'overlay non è sufficiente. Ad esempio, all'origine "evil.ltd" potrebbe essere aggiunto un sito attendibile "google.com", inducendo gli utenti a credere che la sorgente sia attendibile. Il piano è mantenere questo testo di origine in modo che gli utenti sappiano qual è l'origine dell'app e possano assicurarsi che corrisponda alle loro aspettative. Per i browser configurati in RTL, deve essere presente un'area di a capo sufficiente a destra del testo dell'origine per impedire a un sito web dannoso di aggiungere l'origine non sicura a un'origine attendibile.

Fingerprinting

L'attivazione dell'overlay dei controlli della finestra e delle regioni spostabili non comporta considerevoli problemi di privacy, a parte il rilevamento delle funzionalità. Tuttavia, a causa delle diverse dimensioni e posizioni dei pulsanti di controllo della finestra nei vari 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à rilevare il sistema operativo dalla stringa dell'agente utente, ma a causa di problemi di fingerprinting, si discute di bloccare la stringa UA e unificare le versioni del sistema operativo. La community dei browser si impegna costantemente per capire con quale frequenza le dimensioni dell'overlay dei controlli della finestra cambiano tra le piattaforme, poiché l'attuale presupposto è che queste siano abbastanza stabili nelle varie versioni del sistema operativo e quindi non sarebbero utili per osservare le versioni minori del sistema operativo. Sebbene si tratti di un potenziale problema di fingerprinting, si applica solo ai PWA installati che utilizzano la funzionalità della barra del titolo personalizzata e non all'utilizzo generale del browser. Inoltre, l'API navigator.windowControlsOverlay non sarà disponibile per gli iframe incorporati all'interno di una PWA.

Se si passa a un'origine diversa all'interno di una PWA, verrà utilizzata la normale barra del titolo autonoma, anche se la PWA soddisfa i criteri sopra indicati e viene avviata con l'overlay dei controlli della finestra. Questo è per adattarsi alla barra nera che viene visualizzata durante la navigazione verso un'origine diversa. Dopo aver eseguito nuovamente la navigazione all'origine originale, verrà utilizzato di nuovo l'overlay dei controlli della finestra.

Una barra degli URL nera per la navigazione al di fuori della pagina di origine.
Quando l'utente passa a un'origine diversa, viene visualizzata una barra nera.

Feedback

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

Fornisci informazioni sul design 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? Invia una segnalazione relativa alle specifiche nel repository GitHub corrispondente o aggiungi il tuo parere a un problema esistente.

Segnalare un problema con l'implementazione

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

Mostra il supporto per l'API

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

Invia un tweet all'account @ChromiumDev con l'hashtag #WindowControlsOverlay e facci sapere dove e come lo utilizzi.

Link utili

Ringraziamenti

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