Há vários métodos imperativos para pedir permissão de uso
de recursos avançados, como acesso à localização em apps da Web. Esses métodos vêm com vários desafios. Por isso, a equipe de permissões do Chrome está testando um novo método declarativo: um elemento HTML <permission> dedicado. Esse
elemento está em teste de origem no Chrome 126, e esperamos
padronizá-lo.
Métodos imperativos para solicitar permissão
Quando os apps da Web precisam de acesso a recursos avançados, eles precisam pedir permissão. Por exemplo, quando o Google Maps exige a localização do usuário usando a API Geolocation, os navegadores pedem permissão ao usuário, muitas vezes com a opção de armazenar essa decisão. Esse é um conceito bem definido na especificação de permissões.
Perguntar implicitamente no primeiro uso em vez de pedir explicitamente de antemão
A API Geolocation é avançada e depende da abordagem de solicitação implícita no primeiro uso. Por exemplo, quando um app chama o método
navigator.geolocation.getCurrentPosition(), o pedido de permissões aparece automaticamente na primeira chamada.
Outro exemplo é
navigator.mediaDevices.getUserMedia().
Outras APIs, como a
API Notification ou
a
API Device Orientation and Motion,
geralmente têm uma maneira explícita de solicitar permissão por um método estático como
Notification.requestPermission()
ou
DeviceMotionEvent.requestPermission().
Desafios com métodos imperativos para pedir permissão
Spam de permissão
Antes, os sites podiam chamar métodos como
navigator.mediaDevices.getUserMedia() ou Notification.requestPermission(),
mas também navigator.geolocation.getCurrentPosition() imediatamente quando um site
era carregado. Uma solicitação de permissão aparecia antes que o usuário interagisse com
o site. Isso às vezes é descrito como spam de permissão e afeta as duas abordagens, pedindo implicitamente no primeiro uso e explicitamente de forma antecipada.

Mitigações do navegador e requisito de gesto do usuário
O spam de permissão fez com que os fornecedores de navegadores exigissem um gesto do usuário, como um clique de botão ou um evento de tecla pressionada, antes de mostrar uma solicitação de permissão. O problema com essa abordagem é que é muito difícil, se não impossível, para o navegador descobrir se um determinado gesto do usuário deve resultar em uma solicitação de permissão a ser mostrada ou não. Talvez o usuário tenha clicado na página em frustração em qualquer lugar porque ela demorou muito para carregar ou talvez ele tenha clicado no botão Localizar minha posição. Alguns sites também ficaram muito bons em enganar os usuários para que clicassem no conteúdo e acionassem a solicitação.
Outra mitigação é adicionar proteções contra abuso de comandos, como bloquear completamente recursos para começar ou mostrar a solicitação de permissão de maneira não modal e menos intrusiva.

Contextualização de permissões
Outro desafio, principalmente em telas grandes, é a maneira como o pedido de permissão é exibido: acima da linha da morte, ou seja, fora da área da janela do navegador em que o app pode desenhar. É comum que os usuários não vejam o aviso na parte de cima da janela do navegador quando acabaram de clicar em um botão na parte de baixo. Esse problema geralmente piora quando as mitigações de spam do navegador estão ativas.

Não é fácil desfazer
Por fim, é muito fácil para os usuários se perderem. Por exemplo, depois que o usuário bloqueia o acesso a um recurso, ele precisa conhecer o menu suspenso de informações do site, em que é possível redefinir as permissões ou reativar as permissões bloqueadas. Ambas as opções no pior caso exigem uma atualização completa da página até que a configuração atualizada entre em vigor. Os sites não têm como oferecer um atalho fácil para os usuários mudarem um estado de permissão atual e precisam explicar cuidadosamente como mudar as configurações, conforme mostrado na parte de baixo da captura de tela do Google Maps a seguir.

Se a permissão for essencial para a experiência, por exemplo, acesso ao microfone para um aplicativo de videoconferência, apps como o Google Meet vão mostrar caixas de diálogo intrusivas que instruem o usuário a desbloquear a permissão.

Um elemento <permission> declarativo
Para resolver os desafios descritos nesta postagem, a equipe de permissões do Chrome
lançou um teste de origem para um novo elemento HTML, <permission>. Esse
elemento permite que os desenvolvedores peçam permissão para usar, por enquanto, um
subconjunto dos recursos avançados disponíveis para sites. Na forma mais simples, você
usa como no exemplo a seguir:
<permission type="camera" />
Ainda está sendo debatido ativamente se <permission> deve ser um elemento nulo ou não. Um elemento vazio é um elemento de fechamento automático em HTML que não pode ter nós filhos. Em HTML, isso significa que ele não pode ter uma tag de fechamento.
O atributo type
O atributo
type
contém uma lista de permissões separadas por espaço que você está solicitando. No momento em que este artigo foi escrito, os valores permitidos eram 'camera', 'microphone' e camera microphone (separados por espaço). Por padrão, esse elemento é renderizado
de maneira semelhante a botões com estilo de user agent básico.

O atributo type-ext
Para algumas permissões que permitem parâmetros adicionais, o atributo
type-ext
aceita pares de chave-valor separados por espaços, como
precise:true para a permissão de geolocalização.
O atributo lang
O texto do botão é fornecido pelo navegador e deve ser consistente. Por isso, ele
não pode ser personalizado diretamente. O navegador muda o idioma do texto com base no idioma herdado do documento ou da cadeia de elementos pai, ou em um atributo lang opcional. Isso significa que os desenvolvedores não precisam localizar o elemento <permission>
por conta própria. Se o elemento <permission> passar da fase de teste de origem, várias strings ou ícones poderão ser compatíveis com cada tipo de permissão para aumentar a flexibilidade. Se você tiver interesse em usar o elemento <permission> e precisar de uma string ou um ícone específico, entre em contato.
Comportamento
Quando o usuário interage com o elemento <permission>, ele pode passar por
várias etapas:
Se a pessoa não tiver permitido um recurso antes, ela poderá permitir em todos os acessos ou permitir para o acesso atual.

Se eles já tinham permitido o recurso, podem continuar permitindo ou parar de permitir.

Se eles já tiverem negado um recurso, poderão continuar negando ou permitir desta vez.

O texto do elemento <permission> é atualizado automaticamente com base no status. Por exemplo, se a permissão para usar um recurso foi concedida, o texto
muda para dizer que o recurso está permitido. Se for necessário conceder permissão primeiro,
o texto muda para convidar o usuário a usar o recurso. Compare a captura de tela anterior com a seguinte para ver os dois estados.

Design de CSS
Para garantir que os usuários reconheçam facilmente o botão como uma superfície para acessar recursos
poderosos, o estilo do elemento <permission> é restrito. Se as restrições de estilo não funcionarem no seu caso de uso, conte para nós como e por quê. Embora nem todas as necessidades de estilização possam ser atendidas, esperamos descobrir maneiras seguras de permitir mais estilização do elemento <permission> após o teste de origem. A tabela a seguir detalha algumas propriedades que têm restrições ou regras especiais aplicadas a elas. Se alguma das regras for violada, o elemento
<permission> será desativado e não poderá ser usado. Qualquer
tentativa de interagir com ele vai resultar em exceções que podem ser capturadas com
JavaScript. A mensagem de erro vai conter mais detalhes sobre a violação detectada.
| Propriedade | Regras |
|---|---|
|
Pode ser usado para definir a cor do texto e do plano de fundo, respectivamente. O contraste entre as duas cores precisa ser suficiente para um texto claramente legível (taxa de contraste de pelo menos 3). O canal alfa precisa ser 1. |
|
Precisa ser definido no equivalente a small e
xxxlarge. Caso contrário, o elemento será desativado. O zoom será considerado ao calcular font-size. |
|
Valores negativos serão corrigidos para 0. |
margin (todas) |
Valores negativos serão corrigidos para 0. |
|
Valores abaixo de 200 serão corrigidos para 200. |
|
Valores diferentes de normal e italic serão corrigidos para normal. |
|
Valores acima de 0.5em serão corrigidos para 0.5em. Valores abaixo de 0 serão corrigidos para 0. |
|
Valores diferentes de inline-block e none serão corrigidos para inline-block. |
|
Valores acima de 0.2em serão corrigidos para 0.2em. Valores abaixo de -0.05em serão corrigidos para -0.05em. |
|
Terá um valor padrão de 1em. Se fornecido, o valor máximo calculado entre os valores padrão e fornecidos será considerado. |
|
Terá um valor padrão de 3em. Se fornecido, o valor mínimo calculado entre os valores padrão e fornecidos será considerado. |
|
Terá um valor padrão de fit-content. Se fornecido, o valor máximo calculado entre os valores padrão e os fornecidos será considerado. |
|
Terá um valor padrão de três vezes fit-content. Se fornecido, o valor mínimo calculado entre os valores padrão e fornecidos será considerado. |
|
Só vai entrar em vigor se height estiver definido como
auto. Nesse caso, valores acima de 1em serão corrigidos para 1em, e padding-bottom será definido como o valor de padding-top. |
|
Só vai entrar em vigor se width estiver definido como
auto. Nesse caso, os valores acima de 5em serão corrigidos para 5em, e padding-right será definido como o valor de padding-left.. |
|
Não será permitido usar efeitos visuais que distorçam a imagem. Por enquanto, só aceitamos tradução 2D e ampliação proporcional. |
As seguintes propriedades CSS podem ser usadas normalmente:
font-kerningfont-optical-sizingfont-stretchfont-synthesis-weightfont-synthesis-stylefont-synthesis-small-capsfont-feature-settingsforced-color-adjusttext-renderingalign-selfanchor-name aspect-ratioborder(e todas as propriedadesborder-*)clearcolor-schemecontaincontain-intrinsic-widthcontain-intrinsic-heightcontainer-namecontainer-typecounter-*flex-*floatheightisolationjustify-selfleftorderorphansoutline-*(com a exceção observada anteriormente paraoutline-offset)overflow-anchoroverscroll-behavior-*pagepositionposition-anchorcontent-visibilityrightscroll-margin-*scroll-padding-*text-spacing-trimtopvisibilityxyruby-positionuser-selectwidthwill-changez-index
Além disso, todas as propriedades logicamente equivalentes podem ser usadas (por exemplo, inline-size é equivalente a width), seguindo as mesmas regras do equivalente.
Pseudoclasses
Há duas pseudoclasses especiais que permitem estilizar o elemento <permission> com base no estado:
:granted: a pseudoclasse:grantedpermite um estilo especial quando uma permissão é concedida.:invalid: a pseudoclasse:invalidpermite um estilo especial quando o elemento está em um estado inválido, por exemplo, quando é veiculado em um iframe de origem cruzada.
permission {
background-color: green;
}
permission:granted {
background-color: light-green;
}
/* Not supported during the origin trial. */
permission:invalid {
background-color: gray;
}
Eventos JavaScript
O elemento <permission> foi criado para ser usado com a
API Permissions.
Há vários eventos que podem ser detectados:
onpromptdismiss: esse evento é acionado quando o usuário dispensa a solicitação de permissão acionada pelo elemento (por exemplo, clicando no botão de fechar ou fora da solicitação).onpromptaction: esse evento é acionado quando a solicitação de permissão disparada pelo elemento é resolvida pelo usuário ao realizar alguma ação na solicitação em si. Isso não significa necessariamente que o estado da permissão mudou. O usuário pode ter realizado uma ação que mantém o status quo (como continuar permitindo uma permissão).onvalidationstatuschange: esse evento é acionado quando o elemento muda de"valid"para"invalid". O elemento é considerado"valid"quando o navegador confia na integridade do sinal se o usuário clicar nele e"invalid"caso contrário, por exemplo, quando o elemento está parcialmente oculto por outro conteúdo HTML.
É possível registrar listeners de eventos para esses eventos diretamente no código HTML
(<permission type="…" onpromptdismiss="alert('The prompt was dismissed');" />)
ou usando addEventListener() no elemento <permission>, conforme mostrado no
exemplo a seguir.
<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>
Detecção de recursos
Se um navegador não for compatível com um elemento HTML, ele não será mostrado. Isso significa que, se você tiver o elemento <permission> no seu código HTML, nada vai acontecer se o navegador não o reconhecer. Talvez você ainda queira detectar o suporte usando JavaScript,
por exemplo, para criar uma solicitação de permissão acionada por um clique em um
<button> comum.
if ('HTMLPermissionElement' in window) {
// The `<permission>` element is supported.
}
Teste de origem
Para testar o elemento <permission> no seu site com usuários reais, inscreva-se no teste de origem.
Leia Começar a usar testes de origem para
instruções sobre como preparar seu site para usar testes de origem. O teste de origem será executado do Chrome 126 ao 131 (19 de fevereiro de 2025).
Demonstração
Confira a demonstração e o código-fonte no GitHub. Confira uma captura de tela da experiência em um navegador compatível.

Feedback
Queremos saber como o <permission> funciona para seu caso de uso. Responda a um dos problemas no repositório ou envie um novo. Os indicadores públicos no repositório do elemento
<permission> informam a nós e a outros navegadores que você tem interesse
nele.
Perguntas frequentes
- Por que isso é melhor do que um
<button>comum pareado com a API Permissions? Um clique em um<button>é um gesto do usuário, mas os navegadores não têm como verificar se ele está conectado à solicitação de permissão. Se o usuário tiver clicado em um<permission>, o navegador poderá ter certeza de que o clique está relacionado a uma solicitação de permissão. Isso permite que o navegador facilite fluxos que, de outra forma, seriam muito mais arriscados. Por exemplo, permitir que o usuário desfaça facilmente o bloqueio de uma permissão. - E se outros navegadores não forem compatíveis com o elemento
<permission>? O elemento<permission>pode ser usado como um aprimoramento progressivo. Em navegadores que não oferecem suporte, é possível usar um fluxo de permissão clássico. Por exemplo, com base no clique de um<button>normal. A equipe de permissões também está trabalhando em um polyfill. Marque o repositório do GitHub para receber uma notificação quando ele estiver pronto. - Isso foi discutido com outros fornecedores de navegadores? O elemento
<permission>foi discutido ativamente no W3C TPAC em 2023 em uma sessão paralela. Leia as observações da sessão pública. A equipe do Chrome também pediu posições formais sobre padrões de ambos os fornecedores. Consulte a seção Links relacionados. O elemento<permission>é um tema constante de discussões com outros navegadores, e esperamos padronizá-lo. - Isso deveria ser um elemento vazio? Ainda está sendo ativamente debatido se
<permission>deve ser um elemento vazio ou não. Se você tiver feedback, participe do problema.
Links relacionados
Agradecimentos
Este documento foi revisado por Balázs Engedy, Thomas Nguyen, Penelope McLachlan, Marian Harbach, David Warren e Rachel Andrew.