Conteúdo pop-up com CSS e Javascript

O pop-up é um tipo de janela que se abre no navegador ao visitar uma página web ou acessar uma hiperligação específica. O pop-up é utilizado por criadores de sites para abrir alguma informação extra ou como meio de propaganda.

Pop-up – Wikipédia, a enciclopédia livre

O código abaixo, adaptado de um exemplo da Wikipédia, mostra como criar uma janela pop-up baseada em CSS, que torna-se visível quando uma função em JavaScript altera o atributo display e uma DIV é exibida por cima da página:


<style type="text/css">
  .popup{
     position: fixed;
     top: 0; bottom: 0;
     left: 0; right: 0;
     margin: auto;
     width: 300px;
     height: 150px;
     padding: 20px;
     border: solid 1px #331;
     background: #ffffd0;
     display: none;
  }
</style>

<script type="text/javascript">

   function fechar(){
     document.getElementById('popup').style.display = 'none';
   }

   function abrir(){
     document.getElementById('popup').style.display = 'block';
   }

</script>

<body>...

<div id="popup" class="popup"> 
  <p>Conteúdo do pop-up aqui.</p>
  <p><small class="fechar"><a href="javascript: fechar();">Fechar pop-up</a></small></p>
</div>

<p>
  <a href="javascript: abrir();">Abrir POPUP</a>
  <a href="javascript: fechar();">Fechar POPUP</a>
</p>

  1. A propriedade position: fixed manterá o conteúdo pop-up sempre visível, mesmo que o usuário role a página.
  2. O conteúdo é ocultado com diplay: none.
  3. A função abrir muda a propriedade display para block, tornando o pop-up visível.
  4. A função fechar apenas retorna o pop-up ao seu estado original aplicando novamente o estilo display: none.

Revisitando os pop-ups

Basicamente, o modal ou pop-up funciona muito bem, mas faltam algumas melhorias. Quando o conteúdo é exibido, ele surge de repente na tela, sem nenhuma animação. Vamos fazer um pop-up mais estiloso, e talvez dispensar a necessidade de Javascript:


.pop {
  position: fixed;
  top: 120%;
  left: 120%;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.3);
  opacity: 0;
  -webkit-transition: opacity 0.3s ease-in-out;
  transition: opacity 0.3s ease-in-out;
  display: -webkit-flex;
  display: flex;
  -webkit-align-items: center;
  align-items: center;
}

.pop:target, .pop.up {
  top: 0;
  left: 0;
  opacity: 1;
}

.pop-content {
  position: relative;
  overflow: auto;
  max-width: 800px;
  margin: auto;
  background-color: #fdfdfd;
  border-radius: 4px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
}

.pop .close {
  position: absolute;
  top: 0;
  right: 0;
  margin: 0;
  padding: 0 15px;
  line-height: 50px;
}

O pop-up agora tem várias melhorias:

Outro problema do exemplo anterior é que os scripts não podem ser reaproveitados. Como as funções estão sempre chamando o mesmo elemento, baseando-se no atributo id, não podemos usar as mesmas funções aqui. Vamos fazer uma função que resolva isso, e de quebra permita reutilizarmos o componente com mais flexibilidade:


function modal(modal) {

  if (typeof modal === 'string') modal = document.querySelector(modal);

  return {
      abrir: function() {
        modal.classList.add('up');
      },
      fechar: function() {
        modal.classList.remove('up');
      }
  };

};

A função recebe um parâmetro para especificar qual elemento representa o nosso componente. Podemos passar o próprio elemento ou uma string que busca o elemento na página, no estilo da jQuery:


var popupElement = document.querySelector('#pop-up-1');

var primeiroPopUp = modal(popupElement);

var segundoPopUp = modal('#pop-up-2');

A função retorna um objeto com os métodos abrir e fechar, que permitem realizar as ações que eles sugerem. Agora podemos usar o componente assim:


<div id="pop-up-1" class="pop">
  <section class="pop-content">
    <a href="#" class="close">&times;</a>
    <header>
      <h4>Título do modal</h4>
    </header>
    <p>
      Lorem ipsum dolor, sit amet consectetur 
      adipisicing elit. Voluptas at, dolores 
      accusamus autem perspiciatis dolorem adipisci! 
      Inventore officiis porro dolores quod 
      provident, ipsa maiores similique voluptas 
      molestias corrupti eaque error.
    </p>
  </section>
</div>

E podemos disparar a exibição do modal com o método do CSS ou com a função do javascript:


<a href="#pop-up-1">Abrir sem Javascript</a>

<a href="javascript: modal('#pop-up-1').abrir();">Abrir com Javascript</a>