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.
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à:
- Il valore
"window-controls-overlay"
per il campo"display_override"
nel manifest dell'app web. - Le variabili di ambiente CSS
titlebar-area-x
,titlebar-area-y
,titlebar-area-width
etitlebar-area-height
. - La standardizzazione della proprietà CSS
-webkit-app-region
, precedentemente proprietaria, come proprietàapp-region
per definire le regioni trascinabili nei contenuti web. - Un meccanismo per eseguire query sulla regione dei controlli della finestra e aggirarla tramite l'elemento
windowControlsOverlay
diwindow.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:
- L'app non si apre nel browser, ma in una finestra PWA separata.
- Il file manifest include
"display_override": ["window-controls-overlay"]
. (Dopo questa data sono consentiti altri valori). - La PWA è in esecuzione su un sistema operativo desktop.
- 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.
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 è.
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 #131313
→maroon
o maroon
→#131313
→maroon
, 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.
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.
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"
.
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.
La funzionalità di ricerca nell'overlay dei controlli della finestra è completamente funzionale:
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.
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.
non sarà disponibile per gli iframe incorporati all'interno di una PWA.
Navigazione
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.
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
- Spiegazione
- Bozza delle specifiche
- Bug di Chromium
- Voce dello stato della piattaforma Chrome
- Revisione TAG
- Documentazione correlata di Microsoft Edge
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.