DEV Community

Cover image for Construindo uma modal semântica com o elemento <dialog>
Angela Caldas
Angela Caldas

Posted on

Construindo uma modal semântica com o elemento <dialog>

Construir um bom e velho pop-up na sua aplicação já foi bem mais difícil! Quer aprender uma forma mais simples e, o melhor de tudo, mais acessível de criar uma Modal na tua página web? Então, chega mais!

Sumário
Estrutura inicial
O elemento <dialog>
Estilizando nossa Modal
Abrindo e fechando a Modal com JavaScript
Uma palavra sobre Acessibilidade
E só pra terminar

Guaxinim surgindo na tela


Estrutura inicial

Vamos começar criando uma página simples com:

  • 01 parágrafo;
  • 01 botão para abrir a Modal; e
  • A Modal propriamente dita.

Normalmente, colocamos a estrutura da Modal ao final da estrutura da página, antes de fechar o <body>, apenas por uma questão de organização mesmo.

<body>
  <main>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat.</p>
    <button class="btn open">Abrir modal</button>
  </main>

  <!-- AQUI CRIAREMOS A MODAL -->
</body>
Enter fullscreen mode Exit fullscreen mode

Vamos começar a criar a nossa Modal usando a tag genérica <div>. Você vai perceber que, à medida que vai escrevendo o código, a estrutura da sua Modal vai aparecer normalmente no fluxo da página. Não se preocupe com isso por enquanto, vamos focar em estruturar todo o conteúdo da Modal primeiro.

  <div class="modal">
    <h2>Header da Modal</h2>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
    <form>
      <label for="name">Nome:</label>
      <input
        type="text"
        id="name"
        placeholder="Digite seu nome"
        required
      />
      <button type="submit">Enviar</button>
    </form>
    <button type="button" class="btn close">X</button>
  </div>
Enter fullscreen mode Exit fullscreen mode

Vamos também adicionar alguns estilos nessa página:

@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@400;500&display=swap");

body {
  background: #fafafa;
  height: 100vh;
  padding: 0 1rem;
}

body, button {
  font-family: "Poppins", sans-serif;
}

.btn {
  border: none;
  border-radius: 0.5rem;
  font-weight: 500;
  font-size: 1rem;
  background: #3485ff;
  color: #fafafa;
  transition: filter 0.2s;
  padding: 1rem 2rem;
  cursor: pointer;
}

.btn.close {
  display: flex;
  align-items: center;
  clip-path: circle();
  position: absolute;
  top: 2rem;  
  right: 2rem;
  height: 1rem;
  aspect-ratio: 1/1;
}

.btn:hover, .btn:focus, button:hover, button:focus {
  filter: brightness(1.2);
}
Enter fullscreen mode Exit fullscreen mode

Esse é o resultado parcial do nosso código até agora:

Estrutura inicial da página


O elemento <dialog>

Criada na atual versão do HTML, a tag <dialog> é uma tag semântica para criação de caixas de diálogo, também conhecidas no mundo dev como Modal ou, mais popularmente, Pop-Ups.

Além de proporcionar uma melhor semântica e ajudar no SEO da sua página, existem outras vantagens no uso da tag <dialog> em vez de uma simples <div>. Veremos a seguir algumas dessas vantagens!

No código da nossa Modal, vamos trocar a div por dialog. E só em fazer essa troca, já é possível ver uma consequência: toda a estrutura da Modal simplesmente sumiu da nossa página! Mas fique calmo, esse é o comportamento padrão: quando definimos uma <dialog> na página, o browser automaticamente o coloca com display: none, fazendo-o desaparecer. Para visualizar a sua Modal enquanto trabalhamos nela, adicione o atributo open na tag <dialog>, dessa forma:

  <dialog open class="modal">
    <!-- código interno da modal -->
  </dialog>
Enter fullscreen mode Exit fullscreen mode

Podemos perceber que toda a estrutura da <dialog> agora já se mantém organizada dentro de um bloco definido por uma borda preta. Você pode retirar essa borda através do CSS, se desejar. Aqui nesse tutorial, manteremos dessa forma.

Prévia da dialog na página

Observação: O atributo open só vai ser usado nesse primeiro momento, enquanto estilizamos nossa Modal. Apesar de ela poder ser usada para a função de abrir e fechar a Modal, perdemos alguns vantagens da tag <dialog> ao fazer isso, portanto, faremos essa funcionalidade de outra forma mais à frente nesse tutorial!

Agora, vamos estilizar nossa Modal!


Estilizando nossa Modal

Agora chegamos na parte divertida, que é a estilização da nossa Modal. Vamos acrescentar:

  • Uma cor de fundo, com a propriedade background (ou background-color);
  • Uma borda arredondada, com border-radius;
  • Um espaçamento entre borda e elementos internos, com padding;
  • Um alinhamento de texto ao centro, com text-align; e
  • Uma largura mínima para a <dialog>, que pode ser de 37rem ou 80%, o que for menor.
.modal {
  background: #fafafa;
  border-radius: 0.5rem;
  padding: 2rem;
  text-align: center;
  width: min(37rem, 80%);
}
Enter fullscreen mode Exit fullscreen mode

Agora, adicionaremos estilos aos elementos internos da Modal:

.modal h2 {
  font-size: 1.5rem;
  font-weight: 700;
  margin: 0 0 0.75rem;
  color: #0d114f;
}

.modal p {
  margin-bottom: 1.5rem;
  color: #4d5e77;
}

.modal button {
  cursor: pointer;
}
Enter fullscreen mode Exit fullscreen mode

E assim ficou nossa Modal, quase 100% pronta! A seguir, vamos trabalhar a abertura e fechamento dessa Modal com JavaScript!

Dialog estilizada


Abrindo e fechando a Modal com JavaScript

Uma das vantagens mais legais em usar a tag <dialog> é que as coisas ficam bem mais simples no JavaScript! Em outra situação, teríamos que criar um estilo extra para uma classe .active ou .open e fazer uma função .toggle() pra ativar ou desativar essa classe e fazer a Modal aparecer e sumir.

Porém, quando usamos a tag <dialog>, podemos simplesmente usar os métodos showModal() e close(), nativos do JavaScript, para lidar com a abertura e fechamento da Modal. Vamos ver como fazer?

Nosso primeiro passo é capturar os elementos que vamos precisar no DOM e salvá-los em variáveis com o uso de querySelector():

// A modal em si
const modal = document.querySelector(".modal");

// O botão de Abrir Modal
const openModalBtn = document.querySelector(".open");

// O botão de Fechar Modal
const closeModalBtn = document.querySelector(".close");
Enter fullscreen mode Exit fullscreen mode

Depois, vamos adicionar para cada botão um "escutador de eventos", que vai identificar quando o botão vai ser clicado e executar uma função de abrir ou fechar a Modal:

/* Ao clicar no botão de Abrir Modal, executamos a função
showModal() na Modal: */
openModalBtn.addEventListener("click", () => modal.showModal());

/* Ao clicar no botão de Fechar Modal, executamos a função
close() na Modal */
closeModalBtn.addEventListener("click", () => modal.close());
Enter fullscreen mode Exit fullscreen mode

A partir daqui, podemos voltar lá no nosso HTML e excluir o atributo open da nossa <dialog>, pois agora a abertura e fechamento da nossa Modal já está sendo gerenciada pelo JavaScript. Além disso, o uso de dialog em combinação com o método showModal() faz com que a Modal já permita, por padrão, o fechamento através da tecla ESC, sem nenhuma configuração adicional!

Modal funcionando com JavaScript

Na ilustração acima, é possível ver que temos um fundo um pouquinho mais escuro quando a Modal é aberta. Esse overlay também é adicionado automaticamente pela combinação de <dialog> com showModal() e não aparece quando abrimos a Modal usando o atributo open.

Para finalizar os estilos da nossa Modal, podemos fazer com que esse fundo fique um pouco mais escuro, deixando a Modal com mais destaque. Para estilizar esse overlay, faremos uso da pseudo-classe ::backdrop. Vamos acrescentar o seguinte CSS em nosso projeto:

.modal::backdrop {
  background: rgba(0, 0, 0, .7);
}
Enter fullscreen mode Exit fullscreen mode

Isso vai fazer com que nosso overlay fique mais escuro e mais agradável:

Dialog com fundo alterado


Uma palavra sobre Acessibilidade

Quando criamos uma Modal, é imprescindível que tenhamos o cuidado de estruturá-la da maneira adequada, evitando problemas sérios de Acessibilidade Web.

O uso da tag <dialog>, além de tornar sua Modal mais semântica, também a torna mais acessível aos leitores de tela e à navegação via teclado. Ela já traz por padrão algumas coisas que, anteriormente, precisávamos adicionar manualmente ao HTML, como os atributos aria-modal="true" e role="dialog".

Outra coisa que a tag <dialog> faz por padrão é fazer com que todo o conteúdo da página principal fique inerte, ou seja, quando a Modal está aberta, os conteúdos da sua página que estejam fora da Modal não podem ser selecionados via mouse ou tecla TAB, o que é excelente para a Acessibilidade. Quando não usamos dialog, precisamos fazer isso manualmente através do JavaScript, o que gera bastante código extra.

Elementos inertes

Antes de abrir a Modal, os elementos são selecionáveis. Após abrir a Modal, não é possível selecionar o texto ou clicar no botão principal.

Além de podermos fechar a modal com a tecla ESC, caso você tenha um formulário nessa Modal, a tag dialog também fecha automaticamente ela quando enviamos dados desse formulário, evitando termos que clicar em um botão de envio e, novamente, em outro botão para fechá-la. Para ativarmos essa funcionalidade, basta adicionarmos o atributo method="dialog" no nosso <form> (lembre-se que o botão de envio deve ser do tipo submit)

<form method="dialog">
  <label for="name">Nome:</label>
  <input
    type="text"
    id="name"
    placeholder="Digite seu nome"
    required
  />
  <button type="submit">Enviar</button>
</form>
Enter fullscreen mode Exit fullscreen mode

Fechamento da Modal no envio do formulário

Ao enviar o formulário corretamente, a Modal fecha automaticamente.

Para melhorar ainda mais a Acessibilidade da nossa Modal, vamos fazer mais duas pequenas alterações no nosso HTML. A primeira alteração será adicionar um atributo aria-label no nosso botão de Fechar Modal, pois o conteúdo textual dele é apenas um "X", e é isso que os leitores de tela vão falar para os usuários com deficiência visual, dificultando o entendimento do que aquele botão faz. Nosso botão ficará assim:

<button type="button" class="btn close" aria-label="Fechar modal">X</button>
Enter fullscreen mode Exit fullscreen mode

Agora, nosso leitor de tela vai ler "Fechar modal botão" em vez de "X botão". Muito mais claro, não?

A segunda alteração que faremos será no <h2>, que é o título principal da nossa Modal. Quando usamos a tag dialog, ao abrirmos a Modal, a página automaticamente foca nela e o leitor de tela anuncia que um "Diálogo" foi aberto, mas o ideal é que o usuário saiba de imediato do que se trata essa Modal.

Para isso, vamos usar nosso h2 como título da nossa dialog, fazendo com que o leitor de tela anuncie corretamente nossa Modal com "Diálogo" mais o texto do H2. Só precisamos utilizar os atributos aria-labelledby na nossa dialog e vincularmos ela com uma id em nosso h2:

<dialog class="modal" aria-labelledby="dialog-title">
  <h2 id="dialog-title">Header da Modal</h2>
  <!-- restante do código da Modal -->
</dialog>
Enter fullscreen mode Exit fullscreen mode

Com isso, nós já deixamos nossa Modal bem mais acessível e agradável para uso de todos os usuários, o que chamamos na Arquitetura de Desenho Universal. 😉


E só pra terminar...

Atualmente, a criação de Modal usando a tag dialog é nossa melhor opção em termos de funcionalidade e acessibilidade. Em combinação com o método showModal() do JavaScript, temos uma código mais limpo, mais organizado e uma implementação mais fácil!

Espero que com esse artigo, de aqui em diante seja mais fácil implementar caixas de diálogo nas suas aplicações e que isso te seja útil na sua evolução como Front Ender! Um xêro pra você!

E se quiser ver o código por completo, basta acessar o Codepen abaixo:


Fontes

Top comments (11)

Collapse
 
zeotoni profile image
Ezequiel Otoni

Adorei. Eu tava perdido na vida usando div kkk. Agora não mais. Arrasou Angela 👏🏻👏🏻

Collapse
 
sucodelarangela profile image
Angela Caldas

Ah, eu também saí recentemente das modais com divs, haha! Que bom que curtiu, Ezequiel, obrigada!

Collapse
 
malopestorres profile image
Marcus Torres • Edited

Que lindeza de tutorial deixo aqui meu muito obrigado ☺️

Collapse
 
sucodelarangela profile image
Angela Caldas

Muito obrigada, Marcus! 😍

Collapse
 
marcelluscaio profile image
Caio Marcellus Cabral

Artigo maravilhoso juntando o que tem de mais moderno. Menos código e melhor acessibilidade, win-win. E com uma didática impecável. Bora geral usar o o/

Collapse
 
sucodelarangela profile image
Angela Caldas

Valeu, Caioooo <3
Eu sempre tive muito pé atrás com modal por conta da acessibilidade, mas essa abordagem melhora bastante a UX.

Collapse
 
fabianoraiser profile image
Fabiano Raiser

Obrigado por trazer essa tag nova, Angela. Estava aqui quebrando a cabeça de como eu iria implementar as modais num novo projeto que estou trabalhando, agora já sei por onde seguir de uma maneira mais fácil

Collapse
 
schemetastic profile image
Schemetastic (Rodrigo)

And the overall browser support is not bad, you might want to give it a look:

caniuse.com/?search=dialog

Collapse
 
filipeexercito profile image
Filipe Macedo Teixeira • Edited

Após eu colocar a tag dialog meu modal não desapareceu da página. Ficou lá me olhando e eu olhando pra ele kkkk... e agora, será que é meu navegador? Estou utilizando o Chrome. Esse comportamento de aplicar "display none" não deveria ser padrão da tag dialog?

Collapse
 
cademeucode profile image
Cade Meu Code

Eu não fazia idéia de como era implementado um modal... O artigo está muito bem escrito, claro e objetivo. Obrigado por compartilhar!

Collapse
 
augustowhonorata profile image
Augusto Honorata

Que artigo maravilhoso, completo e muito bem detalhado. Muito obrigado pelos esclarecimentos