Popups e Modals nativos com o elemento "dialog" do HTML5
() translation by (you can also view the original English article)
Muitos processos na web hoje em dia requerem o consentimento do usuário para para então continuar. Por exemplo, os usuários podem precisar remover uma conta, trocar o usuário, ou confirmar uma transação monetária.
Uma prática de UX utilizada em alguns casos seria apresentar uma caixa de diálogo, tipicamente com dois botões; um para cancelar e o outro para dar continuidade a ação. A tempos utilizamos bibliotecas JavaScript para criar a caixa de diálogo, mas nesse tutorial vamos analisar como criar essa caixa nativamente utilizando o elemento experimental <dialog>
.
Utilizando o elemento Dialog
<dialog>
é um elemento do HTML5 (5.1 especificamente). Ele é classificado com um "elemento de seção", assim como a tag <body>
, <blockquote>
, e o elemento <details>
, que definem uma nova seção de conteúdo independente. Você pode declarar o elemento como um elemento filho do body, ou mesclar com outro elemento como uma <div>
ou <section>
- os duas alternativas são válidas.
1 |
<body>
|
2 |
|
3 |
<div>
|
4 |
<dialog></dialog>
|
5 |
</div>
|
6 |
|
7 |
<section>
|
8 |
<dialog></dialog>
|
9 |
</section>
|
10 |
|
11 |
<dialog></dialog>
|
12 |
</body>
|
Os navegadores com suporte ao elemento <dialog>
(Chrome 37+ e Opera 27+) devem renderizar o elemento escondido, por padrão. O elemento é apresentado mediante uma requisição via JavaScript utilizando os métodos show()
ou showModal()
, e para fechar, é utilizado o método close()
. (Chrome 37+ and Opera 27+ Normalmente, utilizamos este método com um evento click
, como no exemplo abaixo:
1 |
var $accountDelete = $('#delete-account'), |
2 |
$accountDeleteDialog = $('#confirm-delete'); |
3 |
|
4 |
$accountDelete.on('click', function() { |
5 |
$accountDeleteDialog[0].showModal(); |
6 |
});
|
7 |
|
8 |
$('#cancel').on('click', function() { |
9 |
$accountDeleteDialog[0].close(); |
10 |
});
|
A diferença entre os métodos show()
e showModal()
Vale notar que o show()
e o showModal()
tem ações diferentes.
O metódo show()
apresenta o objeto de acordo com a posição no fluxo do DOM. Se você adicionar o elemento logo após fechar a tag body, ele deve ser apresentado no rodapé da página. Neste caso, vamos precisar declarar alguns estilos, caso a intenção seja posicionar o elemento no centro da página. Esses estilos normalmente utilizam o z-index
para determinar a posição no topo de outros elementos, a propriedade position
como absolute
, junto com o left
e top
.
O método showModal()
, por outro lado, vai apresentar o elemento como um modal. Por padrão o modal é apresentado no centro da página, e ele fica no topo das camadas, como a API fullScreen, por exemplo, o que previne a interferência do z-index
, posições relativas e o overflow de elementos pai.
Na maioria dos casos, por conveniência, utilizamos o método showModal()
ao invés do show()
.
Customizando os estilos
A caixa de diálogo é apresentada no estilo padrão do navegador, mas podemos aplicar estilos CSS assim como qualquer outro elemento. Você pode, por exemplo, deixar a borda do modal mais fina, com bordas arredondadas, e adicionar uma sombra.
Quando o elemento <dialog>
é apresentado (utilizando o método showModal()
), temos a nossa disposição um novo pseudo-elemento, o ::backdrop
. O elemento ::backdrop
fica logo abaixo da caixa de diálogo, cobrindo todo o viewport e elementos.
É comum estilizar o backdrop com uma cor escura e pouca opacidade - clique no botão vermelho para visualizar o exemplo:
Adicionando transições
Customizar a caixa de diálogo deve ser bem simples, mas e sobre transição CSS? E que tal apresentar a caixa de dialogo gradativamente, utilizando efeitos de transição, mais ou menos parecido com o OS X?
Primeiro passo
Para começar, vamos posicionar a caixa de diálogo para baixo em 90%, especificar a transição
1 |
dialog { |
2 |
visibility: hidden; |
3 |
transform: scale(0.1); |
4 |
transition: transform 200ms; |
5 |
}
|
Segundo passo
Agora definimos uma class que vai fazer com que a caixa de diálogo fique visível na tela no tamanho determinado.
1 |
dialog.dialog-scale { |
2 |
visibility: visible; |
3 |
transform: scale(1); |
4 |
}
|
Terceiro passo
O truque agora é que vamos "segurar" a caixa de diálogo durante alguns milisegundos antes de adicionar a class dialog-scale
. Para isso, vamos utilizar o método setTimeout()
do JavaScript para adicionar a class:
1 |
var transition; |
2 |
|
3 |
$accountDelete.on('click', function() { |
4 |
$accountDeleteDialog[0].showModal(); |
5 |
transition = setTimeout(function() { |
6 |
$accountDeleteDialog.addClass('dialog-scale'); |
7 |
}, 0.5); |
8 |
});
|
Quarto passo
Não se esqueça de remover a class e limpar o timeOut quando a caixa de diálogo for fechada.
1 |
$('#cancel').on('click', function() { |
2 |
$accountDeleteDialog[0].close(); |
3 |
$accountDeleteDialog.removeClass('dialog-scale'); |
4 |
clearTimeout(transition); |
5 |
});
|
Agora está tudo pronto! Você pode visualizar o o demo no exemplo abaixo:
Conclusão
O elemento <dialog>
é realmente bem útil, porém ainda são poucos os navegadores que apresentam suporte a ele. Quando todos os principais navegadores implementarem o recurso, não vamos mais precisar de bibliotecas de terceiros, a estrutura do conteúdo vai ser mais semântica, apropriada para tecnologias relacionadas a acessibilidade, e vamos finalmente ter uma maneira padrão de criar diálogos em modal.



Enquanto isso, você pode utilizar o polyfill do Google Chrome para simular o recurso em navegadores sem suporte.
Considerações finais e referências
- HTML5 Dialog Element Specification
- Dialog Element Browser Support
- Modal and Modeless Boxes in Web Design
- What You May Not Know About the Z-Index Property
Seja o primeiro a saber sobre novas traduções–siga @tutsplus_pt no Twitter!