Efeito Parallax apenas com CSS

Olá, Web Developers!

Hoje veremos como criar um efeito Parallax de maneira bem simples e sem usar JavaScript conforme o usuário for rolando a página.

O que é Parallax?

Parallax é o nome dado ao efeito de diferentes objetos parecerem estar em diferentes posições ou direções quando observados em diferentes posições.

Isso é muito comum em nosso cotidiano, e amplamente usado em jogos 2D para dar uma ideia de profundidade.

Parallax Game Scrolling

Veja na imagem acima que o fundo se move mais lentamente em relação aos objetos que estão mais “próximos” do jogador, dando a ilusão de profundidade.

Esse efeito também é usado no desenvolvimento web para dar ideia de profundidade. É comum vermos bibliotecas JavaScript que fazem este trabalho, mas nós veremos como é simples de se fazer com apenas CSS sem muito esforço.

Para já ver o resultado, clique aqui.

A Estrutura

A nossa estrutura será bem simples:

<main class="wrapper">
  <section class="section">
    <p class="text" >TreinaWeb</p>
  </section>
  <section class="section">
    <p class="text" >Parallax</p>
  </section>
  <section class="section">
    <p class="text" >CSS</p>
  </section>
</main>

Primeiro precisamos de um elemento que será o container de tudo, e vamos dar a ele a classe wrapper.

Os sites que normalmente fazem uso desse efeito possuem uma seção embaixo da outra. Então vamos criar três <section> com a classe section.

Dentro de cada seção você coloca o conteúdo que quiser. Aqui iremos colocar um simples parágrafo com um texto, e daremos a classe text. Esse elemento é só o conteúdo, então você pode colocar qualquer coisa e estilizar como quiser.

A Estilização

Como vimos, a ideia do Parallax é ter camadas diferentes que se movimentam em diferentes velocidades.

Para esse efeito, faremos uso da propriedade transform e perspective.

/* Esse código é só para tirar as margens */
body,html{margin:0;padding:0;}

.wrapper {
  /* O elemento precisa ter uma altura definida para o efeito
  funcionar.
     100vh significa 100% da altura da view.
  */
  height: 100vh;

  /* O tamanho das imagens irá criar uma barra de rolagem 
  horizontal. Iremos desativar isso */
  overflow-x: hidden;

  /* A propriedade perspective indica a "distância" entre o 
  usuário e o plano Z.
  Quanto maior o valor, mais perto o elemento estará do usuário.
  Se for um valor negativo,
  mais distante esse elemento estará.
  */
  perspective: 2px;

  /* O transform-style indica se os elementos filhos devem ser 
  transformados em um plano 2D ou 3D.
  O valor preserve-3d indica que os elementos devem seguir o 
  espaço 3D indicado.
  */
  transform-style: preserve-3d;
}

.section {
  /* Indicamos "relative" para depois podermos
  posicionar os elementos filhos com "absolute" */
  position: relative;

  /* Indicamos uma altura para a nossa seção. O valor não 
  importa muito.
  Para garantir um bom efeito, coloquei também uma altura 
  mínima de 700px;
  */
  height: 100vh;
  min-height: 700px;

  /* Para manter a transformação em espaço 3D, indicamos o mesmo 
  valor do elemento pai (preserve-3d).
  Para não precisar repetir o valor "preserve-3d", você pode usar 
  o valor "inherit", que fará
  com que ele pegue o valor do elemento pai.
  */
  transform-style: inherit; 
}

.section::before {
  /* Aqui nós iremos configurar a imagem que irá aparecer no fundo
  da seção.
  Como vimos, o Parallax precisa de elementos diferentes, então 
  não daria certo se colocássemos o fundo diretamente na 
  <section>. Então criaremos um pseudo-elemento para isso.
  */

  /* Isso servirá para que o pseudo-elemento possua as mesmas
  dimensões do elemento <section> */
  content: " ";
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;

  /* O z-index negativo irá garantir que a imagem não fique por 
  cima de outros elementos */ 
  z-index: -1;

  /* Aqui estamos fazendo com que a imagem de fundo cubra todo o
  elemento */
  background-size: cover;
  background-repeat: no-repeat;
  background-position: center center;

  /* Aqui está a brincadeira. Lembra que o nosso "wrapper" está
  mais próximo do usuário?
  Aqui nós faremos com que o nosso pseudo-elemento, que está com
  a imagem de fundo, fique mais longe do usuário. Para isso, 
  basta passar um valor negativo para "translateZ()".

  Como a imagem irá para longe do usuário, ela parecerá menor. 
  Então usamos o "scale()" para aumentar o tamanho da imagem.

  Como o elemento estará mais longe do usuário, ele irá se mover
  mais lentamente do que os elementos mais próximos conforme 
  a gente role a página.
  */
  transform: translateZ(-1px) scale(1.5);
}

.text{
  /* Essa classe, como dito antes, é só para o nosso conteúdo.
  Sinta-se livre para criar o que quiser.
  */
  position: absolute;
  top: 25%;
  width: 100%;
  padding: 20px 0;
  background-color: rgba(255, 255, 255,0.5);

  color: white;
  text-shadow: 0 0 5px #000;
  font-size: 20px;
  text-align: center;
}

/* Em nosso pseudo-elemento, configuramos a imagem de fundo,
mas não indicamos qual será a imagem.
  Isso nos permite poder criar outras classes para indicar 
  uma imagem diferente para cada <section>.
*/
.bg1::before {
  background-image: url('https://i.imgur.com/6yuYHKv.jpg');
}

.bg2::before {
  background-image: url('https://i.imgur.com/W0Wot0k.jpg');
}

.bg3::before {
  background-image: url('https://i.imgur.com/DAerHqR.jpg');
}

Agora basta colocar as classes .bg1, .bg2 e .bg3 em nossas sections:

<main class="wrapper">
  <section class="section bg1">
    <p class="text" >TreinaWeb</p>
  </section>
  <section class="section bg2">
    <p class="text" >Parallax</p>
  </section>
  <section class="section bg3">
    <p class="text" >CSS</p>
  </section>
</main>

Para ver todo o código em ação, acesse: clique aqui.

Deixe seu comentário

Graduado em Análise e Desenvolvimento de Sistemas, Pós-graduado em Projetos e Desenvolvimento de Aplicações Web e MBA em Machine Learning. Especializado em Front End e curte desenvolvimento de jogos.