Una prova dell'origine per un nuovo elemento HTML <permission>

Esistono diversi metodi imperativi per chiedere l'autorizzazione a utilizzare funzionalità avanzate come l'accesso alla posizione nelle app web. Questi metodi presentano una serie di sfide, motivo per cui il team di Chrome che si occupa delle autorizzazioni sta sperimentando un nuovo metodo dichiarativo: un elemento HTML <permission> dedicato. Questo elemento è in prova di origine a partire da Chrome 126 e alla fine speriamo di standardizzarlo.

Metodi imperativi per richiedere l'autorizzazione

Quando le app web hanno bisogno di accedere a funzionalità avanzate, devono chiedere l'autorizzazione. Ad esempio, quando Google Maps richiede la posizione dell'utente utilizzando l'API Geolocation, i browser chiederanno all'utente, spesso con la possibilità di memorizzare la decisione. Si tratta di un concetto ben definito nella specifica delle autorizzazioni.

Chiedere implicitamente al primo utilizzo anziché richiedere esplicitamente in anticipo

L'API Geolocation è un'API potente e si basa sull'approccio di richiesta implicita al primo utilizzo. Ad esempio, quando un'app chiama il metodo navigator.geolocation.getCurrentPosition(), la richiesta di autorizzazioni viene visualizzata automaticamente alla prima chiamata. Un altro esempio è navigator.mediaDevices.getUserMedia().

Altre API, come l'API Notifications o l'API Device Orientation and Motion, in genere hanno un modo esplicito per richiedere l'autorizzazione tramite un metodo statico come Notification.requestPermission() o DeviceMotionEvent.requestPermission().

Problemi con i metodi imperativi per chiedere l'autorizzazione

Spam di autorizzazioni

In passato, i siti web potevano chiamare metodi come navigator.mediaDevices.getUserMedia() o Notification.requestPermission(), ma anche navigator.geolocation.getCurrentPosition() immediatamente dopo il caricamento di un sito web. Prima che l'utente interagisca con il sito web, viene visualizzato un prompt di autorizzazione. Questo fenomeno a volte viene descritto come spam di autorizzazioni e influisce su entrambi gli approcci, chiedendo implicitamente al primo utilizzo e richiedendo esplicitamente in anticipo.

Richiesta di autorizzazione per il microfono visualizzata durante il caricamento di un sito web.

Mitigazioni del browser e requisito del gesto dell'utente

Lo spam di autorizzazioni ha portato i fornitori di browser a richiedere un gesto dell'utente, ad esempio un clic su un pulsante o un evento keydown, prima di mostrare una richiesta di autorizzazione. Il problema di questo approccio è che è molto difficile, se non impossibile, per il browser capire se un determinato gesto dell'utente deve comportare la visualizzazione o meno di una richiesta di autorizzazione. Forse l'utente stava facendo clic sulla pagina per frustrazione ovunque perché il caricamento della pagina richiedeva troppo tempo oppure stava effettivamente facendo clic sul pulsante Individuami. Alcuni siti web sono diventati molto bravi a ingannare gli utenti e indurli a fare clic sui contenuti per attivare la richiesta.

Un'altra mitigazione consiste nell'aggiunta di mitigazioni dell'abuso dei prompt, come il blocco completo delle funzionalità all'inizio o la visualizzazione del prompt di autorizzazione in modo non modale e meno intrusivo.

Browser Chrome che mostra un

Contestualizzazione delle autorizzazioni

Un'altra sfida, soprattutto sugli schermi di grandi dimensioni, è il modo in cui viene visualizzata la richiesta di autorizzazione: sopra la linea della morte, ovvero al di fuori dell'area della finestra del browser su cui l'app può disegnare. Non è raro che gli utenti non vedano il prompt nella parte superiore della finestra del browser quando hanno appena fatto clic su un pulsante nella parte inferiore della finestra. Questo problema è spesso esacerbato quando sono in vigore misure di mitigazione dello spam del browser.

Google Maps con il prompt dell&#39;autorizzazione di accesso alla posizione aperto. Il pulsante di accesso alla posizione che ha attivato la richiesta è lontano.

Nessun annullamento facile

Infine, è troppo facile per gli utenti ritrovarsi in un vicolo cieco. Ad esempio, una volta che l'utente ha bloccato l'accesso a una funzionalità, deve essere a conoscenza del menu a discesa delle informazioni sul sito in cui può reimpostare le autorizzazioni o riattivare le autorizzazioni bloccate. Entrambe le opzioni nel caso peggiore richiedono un ricaricamento completo della pagina finché l'impostazione aggiornata non diventa effettiva. I siti non hanno la possibilità di fornire una scorciatoia semplice per consentire agli utenti di modificare uno stato di autorizzazione esistente e devono spiegare minuziosamente agli utenti come modificare le impostazioni, come mostrato nella parte inferiore dello screenshot di Google Maps riportato di seguito.

Controlli dei siti di Chrome su Google Maps per revocare le autorizzazioni.

Se l'autorizzazione è fondamentale per l'esperienza, ad esempio l'accesso al microfono per un'applicazione di videoconferenza, app come Google Meet mostrano finestre di dialogo intrusive che indicano all'utente come sbloccare l'autorizzazione.

Istruzioni di Google Meet su come aprire i controlli del sito di Chrome.

Un elemento dichiarativo <permission>

Per affrontare le sfide descritte in questo post, il team responsabile delle autorizzazioni di Chrome ha lanciato una prova dell'origine per un nuovo elemento HTML, <permission>. Questo elemento consente agli sviluppatori di richiedere in modo dichiarativo l'autorizzazione a utilizzare, per ora, un sottoinsieme delle potenti funzionalità disponibili per i siti web. Nella sua forma più semplice, lo utilizzi come nell'esempio seguente:

<permission type="camera" />

È ancora in corso un dibattito attivo per stabilire se <permission> debba essere un elemento vuoto o meno. Un elemento vuoto è un elemento autoconclusivo in HTML che non può avere nodi secondari, il che in HTML significa che non può avere un tag di chiusura.

Attributo type

L'attributo type contiene un elenco di autorizzazioni che stai richiedendo, separate da spazi. Al momento della stesura di questo documento, i valori consentiti sono 'camera', 'microphone' e camera microphone (separati da uno spazio). Per impostazione predefinita, questo elemento viene visualizzato in modo simile ai pulsanti con uno stile di user agent essenziale.

Vari pulsanti degli elementi di autorizzazione con autorizzazioni per videocamera, microfono e videocamera più microfono.

Attributo type-ext

Per alcune autorizzazioni che consentono parametri aggiuntivi, l'attributo type-ext accetta coppie chiave-valore separate da spazi, ad esempio precise:true per l'autorizzazione di geolocalizzazione.

Attributo lang

Il testo del pulsante viene fornito dal browser e deve essere coerente, pertanto non può essere personalizzato direttamente. Il browser cambia la lingua del testo in base alla lingua ereditata del documento o della catena di elementi padre oppure a un attributo lang facoltativo. Ciò significa che gli sviluppatori non devono localizzare autonomamente l'elemento <permission>. Se l'elemento <permission> supera la fase di prova dell'origine, potrebbero essere supportate diverse stringhe o icone per ogni tipo di autorizzazione per aumentare la flessibilità. Se ti interessa utilizzare l'elemento <permission> e hai bisogno di una stringa o un'icona specifica, contattaci.

Comportamento

Quando l'utente interagisce con l'elemento <permission>, può scorrere le varie fasi:

  • Se non hanno mai consentito una funzionalità, possono consentirla a ogni visita oppure solo per la visita in corso.

    Prompt di autorizzazione per consentire una funzionalità questa volta o a ogni visita.

  • Se in precedenza aveva consentito la funzionalità, può continuare a consentirla o interrompere l'autorizzazione.

    Richiesta di autorizzazione per continuare a consentire o interrompere l&#39;autorizzazione.

  • Se in precedenza aveva disattivato una funzionalità, può continuare a non consentirla o consentirla questa volta.

    Prompt di autorizzazione per continuare a non consentire o consentire questa volta.

Il testo dell'elemento <permission> si aggiorna automaticamente in base allo stato. Ad esempio, se è stata concessa l'autorizzazione a utilizzare una funzionalità, il testo cambia per indicare che la funzionalità è consentita. Se l'autorizzazione deve essere concessa per prima, il testo cambia per invitare l'utente a utilizzare la funzionalità. Confronta lo screenshot precedente con quello seguente per vedere i due stati.

Pulsanti delle autorizzazioni con i testi

Progettazione CSS

Per garantire che gli utenti possano riconoscere facilmente il pulsante come superficie per accedere a potenti funzionalità, lo stile dell'elemento <permission> è limitato. Se le limitazioni di stile non funzionano per il tuo caso d'uso, ci farebbe piacere sapere come e perché. Sebbene non sia possibile soddisfare tutte le esigenze di stile, speriamo di scoprire modi sicuri per consentire un maggiore stile dell'elemento <permission> dopo la prova dell'origine. La tabella seguente descrive alcune proprietà a cui sono applicate restrizioni o regole speciali. In caso di violazione di una delle regole, l'elemento <permission> verrà disattivato e non sarà possibile interagire con esso. Qualsiasi tentativo di interazione con esso genererà eccezioni che possono essere rilevate con JavaScript. Il messaggio di errore conterrà maggiori dettagli sulla violazione rilevata.

Proprietà Regole

color, background-color

Può essere utilizzato per impostare rispettivamente il colore del testo e dello sfondo. Il contrasto tra i due colori deve essere sufficiente per un testo chiaramente leggibile (rapporto di contrasto di almeno 3). Il canale alfa deve essere 1.

font-size, zoom

Deve essere impostato entro l'equivalente di small e xxxlarge. In caso contrario, l'elemento verrà disattivato. Lo zoom verrà preso in considerazione durante il calcolo di font-size.

outline-offset

I valori negativi verranno corretti in 0.
margin (tutti) I valori negativi verranno corretti in 0.

font-weight

I valori inferiori a 200 verranno corretti a 200.

font-style

I valori diversi da normal e italic verranno corretti in normal.

word-spacing

I valori superiori a 0.5em verranno corretti in 0.5em. I valori inferiori a 0 verranno corretti in 0.

display

I valori diversi da inline-block e none verranno corretti in inline-block.

letter-spacing

I valori superiori a 0.2em verranno corretti in 0.2em. I valori inferiori a -0.05em verranno corretti in -0.05em.

min-height

Avrà un valore predefinito di 1em. Se fornito, verrà considerato il valore massimo calcolato tra i valori predefiniti e quelli forniti.

max-height

Avrà un valore predefinito di 3em. Se fornito, verrà considerato il valore minimo calcolato tra i valori predefiniti e quelli forniti.

min-width

Avrà un valore predefinito di fit-content. Se fornito, verrà considerato il valore massimo calcolato tra i valori predefiniti e quelli forniti.

max-width

Avrà un valore predefinito pari a tre volte fit-content. Se fornito, verrà considerato il valore minimo calcolato tra i valori predefiniti e quelli forniti.

padding-top

Avrà effetto solo se height è impostato su auto. In questo caso, i valori superiori a 1em verranno corretti a 1em e padding-bottom verrà impostato sul valore di padding-top.

padding-left

Avrà effetto solo se width è impostato su auto. In questo caso, i valori superiori a 5em verranno corretti a 5em e padding-right verrà impostato sul valore di padding-left.

transform

Non saranno consentiti effetti visivi distorti. Per il momento, accettiamo solo la traduzione 2D e l'upscaling proporzionale.

Le seguenti proprietà CSS possono essere utilizzate normalmente:

  • font-kerning
  • font-optical-sizing
  • font-stretch
  • font-synthesis-weight
  • font-synthesis-style
  • font-synthesis-small-caps
  • font-feature-settings
  • forced-color-adjust
  • text-rendering
  • align-self
  • anchor-name aspect-ratio
  • border (e tutte le proprietà border-*)
  • clear
  • color-scheme
  • contain
  • contain-intrinsic-width
  • contain-intrinsic-height
  • container-name
  • container-type
  • counter-*
  • flex-*
  • float
  • height
  • isolation
  • justify-self
  • left
  • order
  • orphans
  • outline-* (con l'eccezione indicata in precedenza per outline-offset)
  • overflow-anchor
  • overscroll-behavior-*
  • page
  • position
  • position-anchor
  • content-visibility
  • right
  • scroll-margin-*
  • scroll-padding-*
  • text-spacing-trim
  • top
  • visibility
  • x
  • y
  • ruby-position
  • user-select
  • width
  • will-change
  • z-index

Inoltre, è possibile utilizzare tutte le proprietà logicamente equivalenti (ad esempio, inline-size è equivalente a width), seguendo le stesse regole delle proprietà equivalenti.

Pseudo-classi

Esistono due pseudo-classi speciali che consentono di applicare stili all'elemento <permission> in base allo stato:

  • :granted: la pseudo-classe :granted consente uno stile speciale quando è stata concessa un'autorizzazione.
  • :invalid: la pseudo-classe :invalid consente uno stile speciale quando l'elemento si trova in uno stato non valido, ad esempio quando viene pubblicato in un iframe multiorigine.
permission {
  background-color: green;
}

permission:granted {
  background-color: light-green;
}

/* Not supported during the origin trial. */
permission:invalid {
  background-color: gray;
}

Eventi JavaScript

L'elemento <permission> deve essere utilizzato insieme all'API Permissions. Esistono diversi eventi che possono essere ascoltati:

  • onpromptdismiss: questo evento viene attivato quando la richiesta di autorizzazione attivata dall'elemento è stata chiusa dall'utente (ad esempio facendo clic sul pulsante di chiusura o al di fuori della richiesta).

  • onpromptaction: questo evento viene attivato quando la richiesta di autorizzazione attivata dall'elemento è stata risolta dall'utente che ha eseguito un'azione sulla richiesta stessa. Ciò non significa necessariamente che lo stato dell'autorizzazione sia cambiato, l'utente potrebbe aver intrapreso un'azione che mantiene lo status quo (ad esempio, continuare a consentire un'autorizzazione).

  • onvalidationstatuschange: questo evento viene attivato quando l'elemento passa da "valid" a "invalid". L'elemento è considerato "valid" quando il browser considera attendibile l'integrità del segnale se l'utente dovesse farci clic e "invalid" in caso contrario, ad esempio quando l'elemento è parzialmente oscurato da altri contenuti HTML.

Puoi registrare i listener di eventi per questi eventi direttamente in linea nel codice HTML (<permission type="…" onpromptdismiss="alert('The prompt was dismissed');" />), o utilizzando addEventListener() sull'elemento <permission>, come mostrato nell'esempio seguente.

<permission type="camera" />
<script>
  const permission = document.querySelector('permission');
  permission.addEventListener('promptdismiss', showCameraWarning);

  function showCameraWarning() {
    // Show warning that the app isn't fully usable
    // unless the camera permission is granted.
  }

  const permissionStatus = await navigator.permissions.query({name: "camera"});
  
  permissionStatus.addEventListener('change', () => {
    // Run the check when the status changes.
    if (permissionStatus.state === "granted") {
      useCamera();
    }
  });

  // Run the initial check.
  if (permissionStatus.state === "granted") {
    useCamera();
  }
</script>

Rilevamento delle funzionalità

Se un browser non supporta un elemento HTML, non lo mostrerà. Ciò significa che se hai l'elemento <permission> nel codice HTML, non succede nulla se il browser non lo riconosce. Potresti comunque voler rilevare il supporto utilizzando JavaScript, ad esempio per creare una richiesta di autorizzazione attivata tramite un clic di un <button> normale.

if ('HTMLPermissionElement' in window) {
  // The `<permission>` element is supported.
}

Prova dell'origine

Per provare l'elemento <permission> sul tuo sito con utenti reali, registrati alla prova dell'origine. Leggi l'articolo Inizia a utilizzare le prove di origine per istruzioni su come preparare il tuo sito per utilizzare le prove di origine. La prova dell'origine verrà eseguita da Chrome 126 a 131 (19 febbraio 2025).

Demo

Esplora la demo e dai un'occhiata al codice sorgente su GitHub. Ecco uno screenshot dell'esperienza su un browser supportato.

Demo dell&#39;elemento di autorizzazione che mostra tre pulsanti di autorizzazione.

Feedback

Ci piacerebbe sapere come funziona <permission> per il tuo caso d'uso. Puoi rispondere a uno dei problemi nel repository o aprirne uno nuovo. I segnali pubblici nel repository per l'elemento <permission> ci consentiranno, così come ad altri browser, di sapere che ti interessa.

Domande frequenti

  • In che modo è migliore di un normale <button> abbinato all'API Permissions? Un clic di un <button> è un gesto dell'utente, ma i browser non hanno modo di verificare che sia collegato alla richiesta di autorizzazione. Se l'utente ha fatto clic su un <permission>, il browser può essere certo che il clic sia correlato a una richiesta di autorizzazione. In questo modo, il browser può facilitare i flussi che altrimenti sarebbero molto più rischiosi. Ad esempio, consentire all'utente di annullare facilmente il blocco di un'autorizzazione.
  • Cosa succede se altri browser non supportano l'elemento <permission>? L'elemento <permission> può essere utilizzato come miglioramento progressivo. Sui browser non supportati, è possibile utilizzare un flusso di autorizzazioni classico. Ad esempio, in base al clic di un normale <button>. Il team delle autorizzazioni sta anche lavorando a un polyfill. Aggiungi una stella al repository GitHub per ricevere una notifica quando sarà pronto.
  • È stato discusso con altri fornitori di browser? L'elemento <permission> è stato discusso attivamente al W3C TPAC nel 2023 in una sessione di gruppo. Puoi leggere le note della sessione pubblica. Il team di Chrome ha anche richiesto posizioni formali sugli standard a entrambi i fornitori. Consulta la sezione Link correlati. L'elemento <permission> è un argomento di discussione in corso con altri browser e speriamo di standardizzarlo.
  • Questo dovrebbe essere un elemento vuoto? È ancora in corso un dibattito attivo per stabilire se <permission> debba essere un elemento vuoto o meno. Se hai un feedback, intervieni nel problema.

Ringraziamenti

Questo documento è stato esaminato da Balázs Engedy, Thomas Nguyen, Penelope McLachlan, Marian Harbach, David Warren e Rachel Andrew.