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 PWA più simile a un'app, forse ti ricorderai che ho menzionato la personalizzazione della barra del titolo dell'app come strategia per creare un'esperienza più simile a quella di un'app. Ecco un esempio di come può apparire l'app Podcast di macOS.

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

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

Componenti dell'overlay controlli finestra

L'overlay controlli finestra è composto da quattro funzionalità secondarie:

  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 proprietaria -webkit-app-region precedente come proprietà app-region per definire le regioni trascinabili nei contenuti web.
  4. Un meccanismo per eseguire query e aggirare la regione dei controlli della finestra tramite il membro windowControlsOverlay di window.navigator.

Cos'è l'overlay dei controlli delle finestre

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 delle finestre consente alle applicazioni web progressive (PWA) di offrire un'esperienza più simile a quella di un'app sostituendo la barra del titolo a tutta larghezza esistente con un piccolo overlay contenente i controlli della finestra. In questo modo, gli sviluppatori possono inserire contenuti personalizzati in quella che in precedenza era l'area della barra del titolo controllata dal browser.

Stato attuale

Passaggio Stato
1. Creare una spiegazione Completato
2. Crea la bozza iniziale delle specifiche Completato
3. Raccogli feedback e itera il design In corso
4. Prova dell'origine Completa
5. Avvia Completa (in Chromium 104)

Come utilizzare l'overlay dei controlli delle finestre

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

La sovrapposizione dei controlli della finestra sarà visibile solo quando tutte le seguenti condizioni sono soddisfatte:

  1. L'app non viene aperta nel browser, ma in una finestra PWA separata.
  2. Il manifest include "display_override": ["window-controls-overlay"]. (Altri valori sono consentiti in seguito.)
  3. La PWA è in esecuzione su un sistema operativo desktop.
  4. L'origine corrente corrisponde all'origine 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 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. Per questo articolo, ho creato 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 riportato di seguito. La barra del titolo è completamente reattiva. Quando ridimensioni la finestra della PWA, la barra del titolo reagisce come se fosse composta da normali contenuti HTML, cosa che in effetti è.

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

Determinare quali parti della barra del titolo sono trascinabili

Anche se lo screenshot precedente suggerisce che hai finito, non è ancora così. La finestra della PWA non è più trascinabile (tranne una piccola area), poiché i pulsanti di controllo 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 rendere trascinabile 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 delle funzionalità

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

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

Esecuzione di query nella regione dei controlli della finestra con windowControlsOverlay

Il codice finora presenta un problema: su alcune piattaforme i controlli della finestra si trovano a destra, su altre a sinistra. A peggiorare le cose, anche la posizione del menu "tre puntini" di Chrome cambierà in base alla piattaforma. Ciò significa che l'immagine di sfondo con sfumatura lineare deve essere adattata dinamicamente per andare da #131313maroon o maroon#131313maroon, in modo che si fonda con il colore di sfondo maroon della barra del titolo, determinato da <meta name="theme-color" content="maroon">. Per farlo, esegui una query sull'API getTitlebarAreaRect() nella 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 in precedenza), il codice modificato ora utilizza due classi che il codice riportato sopra imposta in modo dinamico.

/* 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 tutte le circostanze. Anche se non sarà presente sui browser che non supportano la funzionalità di sovrapposizione dei controlli della finestra, non sarà presente anche quando la PWA in questione viene eseguita in una scheda. Per rilevare questa situazione, puoi interrogare la proprietà visible di windowControlsOverlay:

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

In alternativa, puoi utilizzare anche 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. */ 
}

Ricevere notifiche sulle modifiche alla geometria

L'interrogazione dell'area di 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 quello di adattare l'overlay dei controlli della finestra in base allo spazio disponibile e aggiungere una battuta direttamente nell'overlay dei controlli della finestra quando c'è spazio sufficiente.

Area di sovrapposizione dei controlli della finestra su una finestra stretta con testo abbreviato.
Controlli della barra del titolo adattati a una finestra stretta.

Puoi ricevere una notifica delle modifiche alla geometria abbonandoti a navigator.windowControlsOverlay.ongeometrychange o configurando un listener di eventi per l'evento geometrychange. Questo evento viene attivato solo quando è visibile la sovrapposizione dei controlli della finestra, 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 di seguito. Puoi leggere la differenza tra i due su MDN.

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

Compatibilità durante l'esecuzione in una scheda e su browser non supportati

Esistono due possibili casi da considerare:

  • Il caso in cui un'app viene eseguita 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 viene eseguita in un browser che non supporta l'overlay dei controlli della finestra.

In entrambi i casi, per impostazione predefinita l'HTML creato per l'overlay dei controlli della finestra verrà visualizzato in linea come normale contenuto HTML e i valori di riserva delle variabili env() verranno utilizzati per il posizionamento. Nei browser supportati, puoi anche decidere di non visualizzare l'HTML designato per l'overlay dei controlli della finestra selezionando la proprietà visible dell'overlay e, se restituisce 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.
I controlli destinati alla barra del titolo possono essere visualizzati facilmente nel corpo dei browser meno recenti.

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

Una PWA in esecuzione in modalità autonoma con la sovrapposizione dei controlli della finestra visualizzata nel corpo.
I controlli destinati alla barra del titolo possono essere visualizzati facilmente nel corpo dei browser meno recenti.

Considerazioni relative alla UI

Anche se può sembrare allettante, la creazione di un menu a discesa classico nell'area di sovrapposizione dei controlli della finestra non è consigliata. In questo modo, violeresti le linee guida di 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 la tua app offre un'esperienza a schermo intero, valuta attentamente se è opportuno che l'overlay dei controlli della finestra faccia parte della visualizzazione a schermo intero. Potresti voler riorganizzare il layout quando viene attivato l'evento onfullscreenchange.

Demo

Ho creato una demo che puoi provare in diversi browser supportati e non supportati e nello stato installato e non installato. Per l'esperienza effettiva di Window Controls Overlay, devi installare l'app. Di seguito puoi vedere due screenshot di ciò che ti aspetta. Il codice sorgente dell'app è disponibile su Glitch.

L&#39;app demo Wikimedia Featured Content con l&#39;overlay dei controlli delle finestre.
L'app demo è disponibile per la sperimentazione.

La funzionalità di ricerca nell'overlay dei controlli della finestra è perfettamente funzionante:

L&#39;app demo Wikimedia Featured Content con la sovrapposizione 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 controlli finestra.

Considerazioni sulla sicurezza

Il team di Chromium ha progettato e implementato l'API Window Controls Overlay utilizzando i principi di base definiti in Controlling Access to Powerful Web Platform Features, tra cui controllo utente, trasparenza ed ergonomia.

Spoofing

Se i siti hanno il controllo parziale della barra del titolo, gli sviluppatori possono falsificare i contenuti in quella che in precedenza 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 originale scompare. Se il browser è impostato su una lingua da destra a sinistra (RTL), questo layout viene invertito in modo che il testo originale si trovi a sinistra. Si apre l'overlay dei controlli della finestra per falsificare l'origine se non è presente un padding sufficiente tra l'origine e il bordo destro dell'overlay. Ad esempio, l'origine "evil.ltd" potrebbe essere aggiunta a un sito attendibile "google.com", inducendo gli utenti a credere che la fonte sia affidabile. Il piano è di 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 per la lettura da destra a sinistra, deve essere presente un padding 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 trascinabili non pone problemi di privacy significativi, 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à scoprire il sistema operativo dalla stringa user agent, ma a causa di problemi di fingerprinting, si sta discutendo di bloccare la stringa UA e unificare le versioni del sistema operativo. La community dei browser sta lavorando per capire con quale frequenza le dimensioni dell'overlay dei controlli della finestra cambiano tra le piattaforme, poiché si presume che siano abbastanza stabili tra le 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 alle PWA installate 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 in una PWA.

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

Una barra degli URL nera per la navigazione cross-origin.
Una barra nera viene visualizzata quando l'utente passa a un'origine diversa.

Feedback

Il team di Chromium vuole conoscere le tue esperienze con l'API Window Controls Overlay.

Descrivi la progettazione dell'API

C'è qualcosa nell'API che non funziona come previsto? Oppure mancano metodi o proprietà che ti servono per implementare la tua idea? Hai una domanda o un commento sul modello di sicurezza? Segnala un problema relativo alle specifiche nel repository GitHub corrispondente o aggiungi i tuoi commenti a un problema esistente.

Segnalare un problema relativo all'implementazione

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

Mostra il tuo sostegno all'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 a @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.