Il existe plusieurs méthodes impératives pour demander l'autorisation d'utiliser des fonctionnalités puissantes telles que l'accès à la position dans les applications Web. Ces méthodes présentent un certain nombre de défis, c'est pourquoi l'équipe chargée des autorisations Chrome teste une nouvelle méthode déclarative : un élément HTML <permission> dédié. Cet élément est en phase d'évaluation depuis Chrome 126. Nous espérons à terme le standardiser.
Méthodes impératives pour demander l'autorisation
Lorsque les applications Web ont besoin d'accéder à des fonctionnalités puissantes, elles doivent demander l'autorisation. Par exemple, lorsque Google Maps a besoin de la position de l'utilisateur à l'aide de l'API Geolocation, les navigateurs invitent l'utilisateur à autoriser l'accès, souvent avec la possibilité de stocker cette décision. Il s'agit d'un concept bien défini dans la spécification des autorisations.
Demande implicite lors de la première utilisation ou demande explicite au préalable
L'API Geolocation est une API puissante qui repose sur l'approche de demande implicite lors de la première utilisation. Par exemple, lorsqu'une application appelle la méthode navigator.geolocation.getCurrentPosition(), l'invite d'autorisation s'affiche automatiquement lors du premier appel.
Voici un autre exemple : navigator.mediaDevices.getUserMedia().
D'autres API, comme l'API Notification ou l'API Device Orientation and Motion, disposent généralement d'un moyen explicite de demander l'autorisation via une méthode statique comme Notification.requestPermission() ou DeviceMotionEvent.requestPermission().
Difficultés liées aux méthodes impératives pour demander l'autorisation
Spam d'autorisations
Auparavant, les sites Web pouvaient appeler des méthodes telles que navigator.mediaDevices.getUserMedia() ou Notification.requestPermission(), mais aussi navigator.geolocation.getCurrentPosition() immédiatement au chargement d'un site Web. Une invite d'autorisation s'affichait avant que l'utilisateur n'ait interagi avec le site Web. On parle parfois de spam d'autorisation. Cela affecte les deux approches, qu'il s'agisse de demander l'autorisation implicitement lors de la première utilisation ou explicitement à l'avance.

Mesures d'atténuation du navigateur et exigence de geste de l'utilisateur
Le spam d'autorisation a conduit les fournisseurs de navigateurs à exiger un geste de l'utilisateur, comme un clic sur un bouton ou un événement keydown, avant d'afficher une invite d'autorisation. Le problème avec cette approche est qu'il est très difficile, voire impossible, pour le navigateur de déterminer si un geste de l'utilisateur donné doit entraîner l'affichage d'une invite d'autorisation ou non. Peut-être que l'utilisateur a cliqué sur la page par frustration, n'importe où, parce que la page a mis trop de temps à se charger, ou peut-être a-t-il effectivement cliqué sur le bouton Me localiser. Certains sites Web sont également devenus très efficaces pour inciter les utilisateurs à cliquer sur du contenu afin de déclencher l'invite.
Une autre mesure d'atténuation consiste à ajouter des mesures d'atténuation des abus d'invite, comme le blocage complet des fonctionnalités au départ, ou l'affichage de l'invite d'autorisation de manière non modale et moins intrusive.

Contextualisation des autorisations
Un autre défi, en particulier sur les grands écrans, est la façon dont l'invite d'autorisation est généralement affichée : au-dessus de la ligne de la mort, c'est-à-dire en dehors de la zone de la fenêtre du navigateur sur laquelle l'application peut dessiner. Il n'est pas rare que les utilisateurs ne voient pas l'invite en haut de la fenêtre de leur navigateur lorsqu'ils viennent de cliquer sur un bouton en bas de la fenêtre. Ce problème est souvent exacerbé lorsque des mesures d'atténuation du spam dans le navigateur sont en place.

Pas d'annulation facile
Enfin, il est trop facile pour les utilisateurs de se retrouver dans une impasse. Par exemple, une fois que l'utilisateur a bloqué l'accès à une fonctionnalité, il doit connaître le menu déroulant des informations sur le site, dans lequel il peut réinitialiser les autorisations ou réactiver les autorisations bloquées. Dans le pire des cas, les deux options nécessitent un rechargement complet de la page jusqu'à ce que le paramètre modifié prenne effet. Les sites ne peuvent pas fournir de raccourci simple aux utilisateurs pour modifier l'état d'une autorisation existante. Ils doivent leur expliquer minutieusement comment modifier leurs paramètres, comme le montre la capture d'écran Google Maps ci-dessous.

Si l'autorisation est essentielle à l'expérience (par exemple, l'accès au micro pour une application de visioconférence), des applications comme Google Meet affichent des boîtes de dialogue intrusives qui indiquent à l'utilisateur comment débloquer l'autorisation.

Un élément <permission> déclaratif
Pour relever les défis décrits dans cet article, l'équipe chargée des autorisations Chrome a lancé un test d'origine pour un nouvel élément HTML, <permission>. Cet élément permet aux développeurs de demander de manière déclarative l'autorisation d'utiliser, pour l'instant, un sous-ensemble des fonctionnalités puissantes disponibles pour les sites Web. Dans sa forme la plus simple, vous l'utilisez comme dans l'exemple suivant :
<permission type="camera" />
La question de savoir si <permission> doit être un élément vide ou non fait toujours l'objet d'un débat actif. Un élément vide est un élément auto-fermant en HTML qui ne peut pas avoir de nœuds enfants, ce qui signifie qu'en HTML, il ne peut pas avoir de balise de fin.
Attribut type
L'attribut type contient une liste d'autorisations que vous demandez, séparées par un espace. Au moment de la rédaction de cet article, les valeurs autorisées sont 'camera', 'microphone' et camera microphone (séparées par un espace). Par défaut, cet élément s'affiche de manière semblable aux boutons avec un style d'agent utilisateur minimaliste.

Attribut type-ext
Pour certaines autorisations qui autorisent des paramètres supplémentaires, l'attribut type-ext accepte les paires clé-valeur séparées par des espaces, comme precise:true pour l'autorisation de géolocalisation.
Attribut lang
Le texte du bouton est fourni par le navigateur et doit être cohérent. Il ne peut donc pas être personnalisé directement. Le navigateur modifie la langue du texte en fonction de la langue héritée du document ou de la chaîne d'éléments parents, ou d'un attribut lang facultatif. Cela signifie que les développeurs n'ont pas besoin de localiser eux-mêmes l'élément <permission>. Si l'élément <permission> dépasse la phase d'essai d'origine, plusieurs chaînes ou icônes peuvent être acceptées pour chaque type d'autorisation afin d'accroître la flexibilité. Si vous souhaitez utiliser l'élément <permission> et avez besoin d'une chaîne ou d'une icône spécifique, contactez-nous.
Comportement
Lorsque l'utilisateur interagit avec l'élément <permission>, il peut parcourir différentes étapes :
S'ils n'ont pas autorisé une fonctionnalité auparavant, ils peuvent l'autoriser à chaque visite ou pour la visite actuelle.

S'ils avaient autorisé la fonctionnalité auparavant, ils peuvent continuer à l'autoriser ou arrêter de l'autoriser.

S'ils avaient refusé une fonctionnalité auparavant, ils peuvent continuer à la refuser ou l'autoriser cette fois-ci.

Le texte de l'élément <permission> est automatiquement mis à jour en fonction de l'état. Par exemple, si l'autorisation d'utiliser une fonctionnalité a été accordée, le texte indique que la fonctionnalité est autorisée. Si l'autorisation doit d'abord être accordée, le texte change pour inviter l'utilisateur à utiliser la fonctionnalité. Comparez la capture d'écran précédente avec la suivante pour voir les deux états.

Conception CSS
Pour que les utilisateurs puissent facilement identifier le bouton comme une surface permettant d'accéder à des fonctionnalités puissantes, le style de l'élément <permission> est limité. Si les restrictions de style ne répondent pas à votre cas d'utilisation, n'hésitez pas à nous le signaler en nous expliquant pourquoi et comment. Bien que nous ne puissions pas répondre à tous les besoins de style, nous espérons trouver des moyens sûrs d'autoriser davantage de styles pour l'élément <permission> après l'origin trial. Le tableau suivant détaille certaines propriétés auxquelles des restrictions ou des règles spéciales s'appliquent. En cas de non-respect de l'une des règles, l'élément <permission> sera désactivé et il ne sera pas possible d'interagir avec lui. Toute tentative d'interaction avec celui-ci entraînera des exceptions pouvant être détectées avec JavaScript. Le message d'erreur contiendra plus de détails sur le cas de non-respect détecté.
| Propriété | Règles |
|---|---|
|
Peut être utilisé pour définir respectivement la couleur du texte et de l'arrière-plan. Le contraste entre les deux couleurs doit être suffisant pour que le texte soit clairement lisible (rapport de contraste d'au moins 3). Le canal alpha doit être défini sur 1. |
|
Doit être défini sur une valeur équivalente à small et xxxlarge. Sinon, l'élément sera désactivé. Le zoom sera pris en compte lors du calcul de font-size. |
|
Les valeurs négatives seront remplacées par 0. |
margin (tout) |
Les valeurs négatives seront remplacées par 0. |
|
Les valeurs inférieures à 200 seront corrigées et remplacées par 200. |
|
Les valeurs autres que normal et italic seront corrigées et remplacées par normal. |
|
Les valeurs supérieures à 0.5em seront corrigées et ramenées à 0.5em. Les valeurs inférieures à 0 seront corrigées et remplacées par 0. |
|
Les valeurs autres que inline-block et none seront corrigées et remplacées par inline-block. |
|
Les valeurs supérieures à 0.2em seront corrigées et ramenées à 0.2em. Les valeurs inférieures à -0.05em seront corrigées et remplacées par -0.05em. |
|
La valeur par défaut sera 1em. Si une valeur est fournie, la valeur maximale calculée entre la valeur par défaut et la valeur fournie sera prise en compte. |
|
La valeur par défaut sera 3em. Si une valeur est fournie, la valeur minimale calculée entre la valeur par défaut et la valeur fournie sera prise en compte. |
|
La valeur par défaut sera fit-content. Si une valeur est fournie, la valeur maximale calculée entre la valeur par défaut et la valeur fournie sera prise en compte. |
|
aura une valeur par défaut de trois fois fit-content. Si une valeur est fournie, la valeur minimale calculée entre la valeur par défaut et la valeur fournie sera prise en compte. |
|
Ne prendra effet que si height est défini sur auto. Dans ce cas, les valeurs supérieures à 1em seront corrigées et ramenées à 1em, et padding-bottom sera défini sur la valeur de padding-top. |
|
Ne prendra effet que si width est défini sur auto. Dans ce cas, les valeurs supérieures à 5em seront corrigées et ramenées à 5em, et padding-right sera défini sur la valeur de padding-left.. |
|
Les effets visuels déformants ne seront pas autorisés. Pour l'instant, nous n'acceptons que la traduction 2D et la mise à l'échelle proportionnelle. |
Les propriétés CSS suivantes peuvent être utilisées normalement :
font-kerningfont-optical-sizingfont-stretchfont-synthesis-weightfont-synthesis-stylefont-synthesis-small-capsfont-feature-settingsforced-color-adjusttext-renderingalign-selfanchor-name aspect-ratioborder(et toutes les propriétésborder-*)clearcolor-schemecontaincontain-intrinsic-widthcontain-intrinsic-heightcontainer-namecontainer-typecounter-*flex-*floatheightisolationjustify-selfleftorderorphansoutline-*(à l'exception deoutline-offset, comme indiqué précédemment)overflow-anchoroverscroll-behavior-*pagepositionposition-anchorcontent-visibilityrightscroll-margin-*scroll-padding-*text-spacing-trimtopvisibilityxyruby-positionuser-selectwidthwill-changez-index
De plus, toutes les propriétés logiquement équivalentes peuvent être utilisées (par exemple, inline-size est équivalent à width), en suivant les mêmes règles que leur équivalent.
Pseudo-classes
Il existe deux pseudo-classes spéciales qui permettent de styliser l'élément <permission> en fonction de l'état :
:granted: la pseudo-classe:grantedpermet d'appliquer un style spécial lorsqu'une autorisation a été accordée.:invalid: la pseudo-classe:invalidpermet d'appliquer un style spécial lorsque l'élément est dans un état non valide, par exemple lorsqu'il est diffusé dans un iFrame d'origine croisée.
permission {
background-color: green;
}
permission:granted {
background-color: light-green;
}
/* Not supported during the origin trial. */
permission:invalid {
background-color: gray;
}
Événements JavaScript
L'élément <permission> est conçu pour être utilisé avec l'API Permissions.
Vous pouvez écouter plusieurs événements :
onpromptdismiss: cet événement est déclenché lorsque l'utilisateur a fermé l'invite d'autorisation déclenchée par l'élément (par exemple, en cliquant sur le bouton de fermeture ou en cliquant en dehors de l'invite).onpromptaction: cet événement est déclenché lorsque l'invite d'autorisation déclenchée par l'élément a été résolue par l'utilisateur qui a effectué une action sur l'invite elle-même. Cela ne signifie pas nécessairement que l'état de l'autorisation a changé. L'utilisateur peut avoir effectué une action qui maintient le statu quo (par exemple, continuer à autoriser une autorisation).onvalidationstatuschange: cet événement est déclenché lorsque l'élément passe de l'état"valid"à l'état"invalid". L'élément est considéré comme"valid"lorsque le navigateur fait confiance à l'intégrité du signal si l'utilisateur clique dessus, et"invalid"dans le cas contraire, par exemple lorsque l'élément est partiellement masqué par un autre contenu HTML.
Vous pouvez enregistrer des écouteurs d'événements pour ces événements directement dans le code HTML (<permission type="…" onpromptdismiss="alert('The prompt was dismissed');" />) ou à l'aide de addEventListener() sur l'élément <permission>, comme illustré dans l'exemple suivant.
<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>
Détection des fonctionnalités
Si un navigateur n'est pas compatible avec un élément HTML, il ne l'affiche pas. Cela signifie que si vous avez l'élément <permission> dans votre code HTML, rien ne se passe si le navigateur ne le connaît pas. Vous pouvez toujours détecter la compatibilité à l'aide de JavaScript, par exemple pour créer une invite d'autorisation déclenchée par un clic sur un <button> normal.
if ('HTMLPermissionElement' in window) {
// The `<permission>` element is supported.
}
Essai Origin Trial
Pour tester l'élément <permission> sur votre site avec de vrais utilisateurs, inscrivez-vous à l'Origin Trial.
Consultez Premiers pas avec les versions d'essai des origines pour savoir comment préparer votre site à utiliser les versions d'essai des origines. La phase d'évaluation des origines se déroulera de Chrome 126 à 131 (19 février 2025).
Démo
Explorez la démonstration et consultez le code source sur GitHub. Voici une capture d'écran de l'expérience sur un navigateur compatible.

Commentaires
Nous aimerions savoir comment <permission> fonctionne pour votre cas d'utilisation. N'hésitez pas à répondre à l'un des problèmes du dépôt ou à en signaler un nouveau. Les signaux publics dans le dépôt pour l'élément <permission> nous indiqueront, ainsi qu'aux autres navigateurs, que vous êtes intéressé.
Questions fréquentes
- En quoi cette solution est-elle meilleure qu'un
<button>classique associé à l'API Permissions ? Un clic sur un<button>est un geste de l'utilisateur, mais les navigateurs n'ont aucun moyen de vérifier qu'il est lié à la demande d'autorisation. Si l'utilisateur a cliqué sur un<permission>, le navigateur peut être sûr que le clic est lié à une demande d'autorisation. Cela permet au navigateur de faciliter les flux qui seraient autrement beaucoup plus risqués. Par exemple, en permettant à l'utilisateur d'annuler facilement le blocage d'une autorisation. - Que se passe-t-il si d'autres navigateurs ne sont pas compatibles avec l'élément
<permission>? L'élément<permission>peut être utilisé comme amélioration progressive. Sur les navigateurs non compatibles, vous pouvez utiliser un flux d'autorisation classique. Par exemple, en fonction du clic sur un<button>standard. L'équipe chargée des autorisations travaille également sur un polyfill. Ajoutez le dépôt GitHub à vos favoris pour être averti lorsqu'il sera prêt. - Avez-vous discuté de ce problème avec d'autres fournisseurs de navigateurs ? L'élément
<permission>a fait l'objet de discussions actives lors de la session spéciale du W3C TPAC en 2023. Vous pouvez consulter les notes de la session publique. L'équipe Chrome a également demandé aux deux fournisseurs de prendre officiellement position sur les normes. Pour en savoir plus, consultez la section Liens associés. L'élément<permission>fait l'objet de discussions continues avec d'autres navigateurs, et nous espérons le standardiser. - Cet élément doit-il vraiment être un élément vide ? La question de savoir si
<permission>doit être un élément vide ou non fait toujours l'objet de vifs débats. Si vous avez des commentaires, n'hésitez pas à les ajouter à l'issue.
Liens associés
Remerciements
Ce document a été examiné par Balázs Engedy, Thomas Nguyen, Penelope McLachlan, Marian Harbach, David Warren et Rachel Andrew.