Uma caixa de diálogo modal é um tipo especial de caixa pop-up em uma página da Web: um pop-up que interrompe o usuário para se concentrar em si mesmo. Existem alguns casos de uso válidos para mostrar uma caixa de diálogo, mas é importante considerar isso antes. As caixas de diálogo modais forçam os usuários a se concentrar em um conteúdo específico e, pelo menos, ignorar o restante da página.
As caixas de diálogo podem ser modais (só é possível interagir com o conteúdo da caixa de diálogo) ou não modais (ainda é possível interagir com o conteúdo fora da caixa de diálogo). As caixas de diálogo modais são exibidas sobre o restante do conteúdo da página. O restante da página é inerte e, por padrão, é coberto por um pano de fundo semitransparente.
O elemento HTML semântico <dialog>
para criar uma caixa de diálogo
vem com semântica, interações de teclado e todas as propriedades e métodos da interface HTMLDialogElement
.
Caixas de diálogo modais
Veja um exemplo de <dialog>
modal. Abra a caixa de diálogo com o botão "Abrir caixa de diálogo modal". Depois de aberta, há três maneiras de fechar a caixa de diálogo: usando a tecla de escape, enviando um formulário com
um botão que tenha o formmethod="dialog"
definido (ou se o próprio formulário tiver method="dialog"
definido) e o método HTMLDialogElement.close()
.
O HTMLDialogElement
tem três métodos principais, além de todos os métodos herdados de HTMLElement
.
dialog.show() /* opens the dialog */
dialog.showModal() /* opens the dialog as a modal */
dialog.close() /* closes the dialog */
Como esse <dialog>
foi aberto pelo método HTMLDialogElement.showModal()
, ele é uma caixa de diálogo modal. Abrir uma caixa de diálogo modal desativa e oculta tudo, exceto a caixa em si. Se você
passar o cursor sobre a interface fora da caixa de diálogo, vai notar que todos os elementos se comportam como se a pointer-events: none;
tivesse sido definida. Mesmo o botão que abre a caixa de diálogo não reage às interações.
Quando a caixa de diálogo é aberta, o foco passa para ela. O foco é definido no primeiro elemento da ordem de navegação sequencial do teclado dessa caixa de diálogo.
Se você pressionar a tecla tab
repetidamente, observará que apenas o conteúdo da caixa de diálogo poderá receber foco enquanto ela estiver
aberta. Tudo fora da caixa de diálogo modal fica inerte, desde que ela esteja aberta.
Quando uma caixa de diálogo é fechada, modal ou não, o foco retorna ao elemento que a abriu. Se você abrir uma caixa de diálogo de forma programática não baseada na ação do usuário, reconsidere. Se necessário, verifique se o foco foi colocado novamente onde estava antes da abertura da caixa de diálogo, especialmente se o usuário dispensar a caixa de diálogo sem interagir com ela.
Há um atributo inert
global que pode ser usado para desativar um elemento e todos os descendentes dele, exceto qualquer caixa de diálogo
ativa. Quando uma caixa de diálogo modal é aberta usando showModal()
, a inércia ou a desativação é sem custo financeiro. O atributo
não é definido explicitamente.
O pano de fundo que oculta tudo o que não seja a caixa de diálogo pode ser estilizado usando o
pseudoelemento ::backdrop
. O pano de fundo só aparece quando uma <dialog>
é mostrada com o método .showModal()
. Esse pseudoelemento
corresponde a todos os panos de fundo, incluindo o mostrado quando a API FullScreen é usada,
por exemplo, ao visualizar um vídeo no modo de tela cheia que não tem a mesma proporção da tela ou do monitor.
Caixas de diálogo não modais
O HTMLDialogElement.show()
abre uma caixa de diálogo de forma semelhante, mas sem adicionar um pano de fundo ou fazer com que algo fique inerte.
A tecla Esc não fecha caixas de diálogo não modais. Por isso, é ainda mais importante incluir um método
para fechar a caixa de diálogo não modal. Ao fazer isso, se a tela estiver fora da caixa de diálogo, o foco vai para o elemento
que abriu a caixa, o que talvez não seja a melhor experiência do usuário.
Embora um botão para fechar a caixa de diálogo não seja oficialmente exigido pela especificação, considere-o como necessário. A tecla de escape fecha uma caixa de diálogo modal, mas não uma não modal. Um botão visível capaz de receber foco melhora a acessibilidade e a experiência do usuário.
Fechar uma caixa de diálogo
O método HTMLDialogElement.close()
não é necessário para fechar uma caixa de diálogo. Você não precisa de JavaScript. Para fechar a <dialog>
sem JavaScript, inclua um formulário com um método de caixa de diálogo definindo method="dialog"
no <form>
ou formmethod="dialog"
no botão.
Quando um usuário faz envios usando o método dialog
, o estado dos dados inseridos pelo usuário é mantido. Enquanto houver um evento de envio, o
formulário vai passar pela validação de restrição (a menos que novalidate
esteja definido), os dados do usuário não serão apagados nem enviados.
Um botão Fechar sem JavaScript pode ser escrito como:
<dialog open>
<form method="dialog">
<button type="submit" autofocus>close</button>
</form>
</dialog>
Você deve ter notado o atributo autofocus
definido no <button>
de fechamento deste exemplo. Elementos com o atributo autofocus
definido em um <dialog>
não vão receber
foco no carregamento da página, a menos que ela seja carregada com a caixa de diálogo visível. No entanto, eles vão receber o foco quando a caixa de diálogo for aberta.
Por padrão, quando uma caixa de diálogo é aberta, o primeiro elemento focalizável nela recebe o foco, a menos que outro
elemento tenha o atributo autofocus
definido. Definir o atributo autofocus
no botão "Fechar" garante
que ele receba foco quando a caixa de diálogo for aberta. No entanto, a inclusão de autofocus
em um <dialog>
precisa ser feita com muita consideração. Todos os elementos na sequência que vêm antes do elemento com foco automático são ignorados.
Falaremos mais sobre esse atributo na lição de foco.
A interface HTMLDialogElement
inclui uma propriedade
returnValue
. O envio de um formulário com method="dialog"
define a returnValue
como name
, se houver, do botão de envio usado para enviar o formulário. Se tivéssemos escrito <button type="submit" name="toasty">close</button>
, returnValue
seria toasty
.
Quando uma caixa de diálogo é aberta, o atributo booleano open
está presente, o que significa que a caixa está ativa e pode ser usada para interagir. Quando uma caixa de diálogo é aberta adicionando o atributo open
em vez
de .show()
ou .showModal()
, ela fica sem modal. A propriedade HTMLDialogElement.open
retorna true
ou false
, dependendo se a caixa de diálogo está disponível para interação, não se ela é modal ou não.
Embora o JavaScript seja o método recomendado para abrir uma caixa de diálogo, incluir o atributo open
no carregamento da página e removê-lo
com .close()
pode ajudar a garantir que a caixa de diálogo esteja disponível mesmo quando o JavaScript não está.
Mais detalhes
Não usar o app tabindex
O elemento ativado para abrir a caixa de diálogo e o botão "Fechar" contido nela (e possivelmente outro conteúdo) podem receber
foco e são interativos. O elemento <dialog>
não é interativo e não recebe foco. Não adicione a propriedade tabindex
à caixa de diálogo.
Papéis ARIA
O papel implícito é dialog
. Se ela
for uma janela de confirmação que comunica uma mensagem importante que exige uma confirmação ou outra resposta do usuário, defina role="alertdialog"
.
A caixa de diálogo também precisa ter um nome acessível. Se um texto visível puder fornecer para o nome acessível, adicione aria-labelledby="idOfLabelingText"
.
Padrões de CSS
Os navegadores oferecem o estilo padrão para dialog
. O Firefox, o Chrome e o Edge definem color: CanvasText;
como background-color: Canvas;
, e o Safari define color: black; background-color: white;
nas folhas de estilo do user agent. O color
é herdado
de dialog
, e não de body
ou :root
, o que pode ser inesperado. A propriedade background-color
não é herdada.
Teste seu conhecimento
Teste seus conhecimentos sobre o elemento da caixa de diálogo.
Como definir o estilo da área atrás da caixa de diálogo?
::background
.::backdrop
.background
.