Postado dia

E ae pessoas! Há algumas décadas, quando os video games ainda não tinham capacidade para rodar imagens em 3D, os games eram criados com cenários pixelados e bem detalhados. Os desenvolvedores desses games construíam cenários 2D compostos por camadas. Enquanto o personagem se movia pela tela, partes do cenários se moviam, aonde cada camada se movia em uma velocidade específica. O nome desse efeito é chamado de parallax.

Efeito parallax em ação no fundo do cenário do jogo Sonic The Hedgehog

Efeito parallax em ação no fundo do cenário do jogo Sonic The Hedgehog

Anos atrás, o efeito virou tendência na internet e foi aplicado em diversos sites. Hoje em dia diminuiu a quantidade de sites que usam isso, mas ainda é um efeito sendo usado com uma certa frequência.

Então que tal aprendermos a criar esse efeito de duas formas diferentes? Uma forma usa jQuery, e a outra usa somente CSS3.

Antes de começar…

Precisamos de uma estrutura HTML para começarmos o tutorial. Abaixo segue o html de uma estrutura simples formada por várias tags <section> e um <footer>. Sem muitos segredos. Use-a para montar seu html para poder seguir este tutorial:

<section class="parallax">
  <h1>O inverno</h1>
</section>
<section class="cont">
  <h2>Lorem Ipsumm</h2>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris in tortor rutrum, rhoncus elit eu, consequat purus. Vivamus a feugiat magna. Suspendisse facilisis tellus quis lacus varius aliquet. Ut imperdiet, urna ac cursus pharetra, felis ante blandit arcu, vel porttitor risus erat in turpis. Nam nec orci massa. Phasellus id venenatis lacus, ac auctor libero. Sed odio velit, finibus eu sapien finibus, posuere dignissim libero. Sed lacinia interdum velit vel gravida. Duis sed lacus et purus convallis eleifend. Pellentesque a egestas elit, tristique dignissim lectus. Sed eu mi non purus ornare cursus varius non tellus. Cras porttitor nunc non orci euismod vulputate. Duis volutpat odio ac convallis malesuada.</p>
</section>
<section class="parado">
</section>
<section class="cont dark">
  <h2>Dolor Sit Amet</h2>
  <p>nteger consequat leo elit, sed hendrerit dui suscipit vitae. Maecenas imperdiet convallis purus, a sollicitudin tellus congue id. Mauris luctus lorem arcu, nec egestas lectus egestas at. Cras lacinia elit id enim laoreet dapibus. Donec id tellus eu justo volutpat rhoncus. Aenean elementum bibendum lectus, at tincidunt nisi iaculis eget. Pellentesque rhoncus scelerisque turpis, dapibus pulvinar ligula convallis vitae. Quisque sed nulla metus. Etiam convallis suscipit sapien, a commodo mi porttitor nec. Maecenas sem mi, maximus eu nunc et, euismod pretium nisi. Donec ultricies nisi ligula, at varius urna consectetur ac. Fusce molestie, lectus a elementum facilisis, nisi ligula commodo urna, ac vulputate lacus lectus id nisi. Donec id pulvinar nibh. Duis ullamcorper libero eget blandit pulvinar. Morbi suscipit imperdiet libero nec scelerisque. Morbi facilisis, augue id vulputate facilisis, lectus felis ultricies dui, a suscipit tortor ligula vitae tortor.</p>
</section>
<section class="parallax">
</section>
<section class="cont">
  <h2>Lorem Ipsum</h2>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris in tortor rutrum, rhoncus elit eu, consequat purus. Vivamus a feugiat magna. Suspendisse facilisis tellus quis lacus varius aliquet. Ut imperdiet, urna ac cursus pharetra, felis ante blandit arcu, vel porttitor risus erat in turpis. Nam nec orci massa. Phasellus id venenatis lacus, ac auctor libero. Sed odio velit, finibus eu sapien finibus, posuere dignissim libero. Sed lacinia interdum velit vel gravida. Duis sed lacus et purus convallis eleifend. Pellentesque a egestas elit, tristique dignissim lectus. Sed eu mi non purus ornare cursus varius non tellus. Cras porttitor nunc non orci euismod vulputate. Duis volutpat odio ac convallis malesuada.</p>
</section>
<footer class="cont">
  Criado por DSA
</footer>

Perceba que existe algumas classes nos <section>. Vou explicar para que usaremos cada classe:

  • parallax: terá o clássico efeito parallax, aonde a imagem de fundo desliza a uma velocidade diferente da velocidade do scroll;
  • cont: define um padding para centralizar o conteúdo que estiver na <section>;
  • parado: terá um outro tipo de efeito parallax, aonde a imagem não se move, como se houvesse um buraco na página que revelasse a imagem que há dentro;
  • dark: adiciona um estilo escuro ao <section>

A partir daqui, vou dividir este tutorial em duas partes: JQuery e CSS3. E ae, qual você vai escolher???

Parallax com jQuery

1. Organizando a estrutura

Em seu CSS, adicione as seguintes linhas:

body{margin: 0; font-size: 14px;}
*{box-sizing: border-box;}
footer,section{padding: 80px 0; background-repeat: no-repeat; background-size: cover; background-position: center center;}
section{background-color: #FFF;}
section.parallax, section.parado{height: 100vh;}

Agora vamos linha por linha:

body{margin: 0; font-size: 14px;}

Nesta linha, zeramos a margem da tag <body> e definimos um tamanho de fonte base para a página para valor base da unidade “em”. Se quiser, pode definir uma família de fonte padrão para a página aqui.

*{box-sizing: border-box;}

Para cada elemento da página, a definição das dimensões será alterada para o modo “border-box”, ou seja, além do tamanho do conteúdo, ele irá incluir padding e border. Então se aplicar 500px de largura em um elemento, e depois aplicar 5px de padding em todos os lados e ainda uma borda de 2px de espessura, o elemento ainda manterá a largura total de 500px, mas a área do conteúdo diminuirá para que o padding e o border caibam, ficando com 486px de largura somente para o conteúdo.

footer,section{padding: 80px 0; background-repeat: no-repeat; background-size: cover; background-position: center center;}

Para todos os <section> e o <footer>, será adicionado um espaçamento entre o conteúdo e o limite do elemento de 80px verticalmente, ou seja, 80px acima e 80px abaixo. Horizontalmente, ficará zerado. E também definimos as configurações para a imagem de fundo: background-repeat: no-repeat; faz com que a imagem não se repita várias vezes, background-size: cover; faz com que a imagem cubra toda a área do elemento, e background-position: center center; faz com que a imagem seja alinhada tanto na vertical quanto na horizontal.

section{background-color: #FFF;}

Aqui definimos um fundo branco para todas as tags <section>.

section.parallax, section.parado{height: 100vh;}

Nesta última linha, apontamos para todas as tags <section> que tenham a classe “parallax” e/ou a classe “parado” aplicada e define uma altura de 100vh, ou seja, pega 100% da altura do viewport, área de visualização da página no navegador.

2. Estilizando os textos

Agora adicione mais essas linhas ao seu CSS:

h1,h2,h3,h4,h5,h6{margin: 0; padding: 0; color: #7294A1;}
h1{position: absolute; top: 20%; right: 1em; font-size: 6vw;}
h2{font-size: 4em;}
p{font-size: 1.2em; line-height: 1.5em;}

Agora, linha por linha:

h1,h2,h3,h4,h5,h6{margin: 0; padding: 0; color: #7294A1;}

Estilizamos todas as tags de títulos, adicionando um tom de azul, mas resetamos a margem e padding dos títulos também. Aqui você pode definir uma família de fonte para os títulos também se não quiser que os títulos usem a fonte padrão.

h1{position: absolute; top: 20%; right: 1em; font-size: 6vw;}

Para a tag <h1>, tag de título principal, vamos definir uma posição personalizada, então vamos definir position: absolute; para conseguirmos posicioná-la aonde quiser. Depois definimos o top: 20%; para que ele considere uma posição que pega 20% da altura do elemento a partir de seu topo. E para que o título redimensione de acordo com a largura do navegador, definimos uma medida usando unidade “vw”. Aqui defina um valor baixo. 6vw está excelente.

h2{font-size: 4em;}

Para a tag <h2>, definimos um tamanho de fonte que é 4 vezes maior que o tamanho de fonte padrão. No caso 4em equivale a 56px (14px * 4em = 56px).

p{font-size: 1.2em; line-height: 1.5em;}

E para as tags de parágrafos, definimos um tamanho de 1.2em, o que dará 16,8px (14px * 1,2em = 16,8px). Também ajustamos a altura das linhas para 1.5em (21px), para que o texto fique com uma aparência mais agradável e a leitura seja fácil.

3. Definindo o objetivo das classes

Ainda no CSS, adicione mais essas linhas:

.cont{padding: 80px calc((100% - 1200px) / 2);}
.cont *{margin-left: 10px; margin-right: 10px;}
section.parado{background-attachment: fixed;}
section.dark{background-color: #7294A1;}
section.dark *{color: #FFF;}

E, linha por linha:

.cont{padding: 80px calc((100% - 1200px) / 2);}

A classe “cont” define o alinhamento do conteúdo através do ajuste dinâmico da propriedade “padding”. Aqui iremos fazer uma gambiarra, para manter o HTML limpo e ainda assim atingirmos o objetivo da classe “cont”. Inicialmente, definimos um valor de 80px para os paddings verticais. Já para os paddings horizontais, usaremos a função calc().

A função calc() permite usar contas para chegar a um valor, mas somente contas básicas, usando os operadores de soma (+), subtração (-), multiplicação (*) e divisão (/). Pode ser usado parênteses para definir uma ordem prioritária alta de cálculos. Depois disso, priorizasse multiplicações, depois divisões, depois soma e por fim, subtração. Os números podem ser escritos usando qualquer unidade válida para o CSS, e é importante definir espaço entre os números e os operadores.

No caso acima, pedimos para que o padding pegue 100% da largura do elemento e subtraia por 1200px, que será a largura máxima do conteúdo. Depois mandamos ele dividir por 2, já que queremos que cada metade fique em cada lado do elemento, centralizando assim o conteúdo.

.cont *{margin-left: 10px; margin-right: 10px;}

Aqui é apontado todos os elementos dentro da classe “cont”, aplicando uma margem de 10px dos dois lados dos elementos, somente para que eles não fiquem grudados nos limites da página ao redimensionar o navegador.

section.parado{background-attachment: fixed;}

A classe “parado” serve para realizar o parallax aonde a imagem fica parada enquanto o resto segue o scroll da página. Esta classe deverá ser usada somente com tags <section>. Para o parallax funcionar, usamos a propriedade <background-attachment> com o valor "fixed". E só.

section.dark{background-color: #7294A1;}

A classe “dark” define um estilo com um esquema de cores mais escura para o <section>. No caso, definimos um tom de azul mais escuro para o elemento.

section.dark *{color: #FFF;}

E para todos os elementos do <section> com a classe “dark”, definimos a cor branca para o seu conteúdo. Poderíamos ter definido isso na linha anterior, mas isso não seria aplicado aos títulos pois eles já têm uma cor definida.

Você deve estar se perguntado: “e a classe ‘parallax’? Não vai definir nada para ela além de uma altura?”. Chegaremos lá em breve.

4. As imagens e o rodapé

Agora, vamos para as linhas finais. Adicione as linhas abaixo no seu CSS:

section:nth-child(1){background-image: url("https://blog.dsaportfolio.com.br/tutoriais-demo/parallax-simples/winter-landscape-2571788_1920.jpg");}
section:nth-child(3){background-image: url("https://blog.dsaportfolio.com.br/tutoriais-demo/parallax-simples/snowflakes-1236245_1920.jpg");}
section:nth-child(5){background-image: url("https://blog.dsaportfolio.com.br/tutoriais-demo/parallax-simples/yellowstone-national-park-1581879_1920.jpg");}

footer{background-color: #7B969A; font-size: 2.5em; font-weight: bold; color: #9EC1C6; text-align: center; font-style: italic;}

Agora, vamos às linhas:

section:nth-child(1){background-image: url("https://blog.dsaportfolio.com.br/tutoriais-demo/parallax-simples/winter-landscape-2571788_1920.jpg");}
section:nth-child(3){background-image: url("https://blog.dsaportfolio.com.br/tutoriais-demo/parallax-simples/snowflakes-1236245_1920.jpg");}
section:nth-child(5){background-image: url("https://blog.dsaportfolio.com.br/tutoriais-demo/parallax-simples/yellowstone-national-park-1581879_1920.jpg");}

Aqui apontamos em cada linha para um elemento <section> na ordem que está no HTML usando o seletor :nth-child(). Como sabemos a posição certinha de cada elemento na estrutura (e no caso temos certeza que a página não sofrerá nenhuma alteração manual ou dinâmica na estrutura), podemos indicar a posição exata de cada elemento.

No caso, o seletor começa a contar do 1 (ele não considera o valor 0), então vamos apontar para o primeiro, terceiro e quinto seletores, cada um na sua linha. E para cada um, usamos a propriedade background-image com a função url(), indicando o endereço da imagem de fundo.

footer{background-color: #7B969A; font-size: 2.5em; font-weight: bold; color: #9EC1C6; text-align: center; font-style: italic;}

Aqui definimos um estilo para o rodapé semelhante ao da classe “dark”. Definimos um tamanho próprio de fonte de 2.5em (font-size: 2.5em; = 35px), um peso em negrito (font-weight: bold;), cores de fundo (background-color: #7B969A;) e de cor (color: #9EC1C6;) azulados, alinhamos o texto centralizado (text-align: center;) e deixamos o texto itálico (font-style: italic;). Simples!

5. Vai que é tua, jQuery!

Agora vamos mexer no jQuery. Para que o parallax tradicional funcione nos elementos com a classe “parallax”, precisamos que o scroll da página seja calculado toda vez que a página realize o scroll. Para isso, primeiro vamos criar uma função no javascript que vamos nomear como “parallax” (AH VÁ!).

No seu javascript, adicione a seguinte função:

function parallax(elem,intensity){

  intensity = typeof intensity === "undefined" ? 2 : intensity;
  
  ws = (window.pageYOffset || document.documentElement.scrollTop) - (document.documentElement.clientTop || 0);
  wsPos = ws/intensity;

  if($(elem).length > 1){ 
    $(elem).each(function(){
      elemPos = $(this).position().top/intensity;
      $(this).css({backgroundPosition: "0px "+(wsPos - elemPos)+"px"})
    })
  } else {
    elemPos = $(elem).position().top/intensity;
    $(elem).css({backgroundPosition: "0px "+(elem == "body" ? wsPos : wsPos - elemPos)+"px"})
  }
}

Está função foi definida com dois parâmetros: “elem” e “intensity”.

  • “elem” armazenará uma string (texto) de seleção que aponta para o elemento que terá o efeito parallax aplicado;
  • “intensity” define a intensidade do efeito parallax. Quanto menor for o nível de intensidade, mais rápido a imagem de fundo irá seguir o scroll da página. Se definirmos 1, a imagem simplesmente se moverá junto com o scroll, sem ter efeito visível. Então considere um valor de 2 para cima para um efeito bom.

Agora vamos analisar linha por linha do código da função:

intensity = typeof intensity === "undefined" ? 2 : intensity;

Esta linha define um valor padrão para o parâmetro “intensity” igual a 2 caso um valor não tenha sido definido para ele ao chamar a função.

ws = (window.pageYOffset || document.documentElement.scrollTop) - (document.documentElement.clientTop || 0);
wsPos = ws/intensity;

Na variável “ws” pegamos a posição do scroll na página, sendo que a posição do scroll seria a parte superior do viewport do navegador. Aqui tentamos pegar este valor de tal forma que seja compatível com a maioria dos navegadores atuais:

  • window.pageYOffset || document.documentElement.scrollTop: tanto a propriedade pageYOffset quanto a propriedade scrollTop pegam a posição Y do scroll na página. O operador || significa “OU”. Essa condicional é usada para conseguir pegar o scroll Y na maioria dos navegadores.
  • document.documentElement.clientTop || 0: caso o elemento raiz da página (<html>) tenha uma borda, ele pega esse valor para subtrair pela posição Y do scroll. Se não tiver, ele usa o valor 0.

A linha seguinte define a variável “wsPos” e divide pelo valor de “intensity” para definir a posição scroll Y da página para o efeito parallax.

if($(elem).length > 1){ 
 $(elem).each(function(){
   elemPos = $(this).position().top/intensity;
   $(this).css({backgroundPosition: "0px "+(wsPos - elemPos)+"px"})
 })

Aqui abrimos uma condicional aonde é analisado se existe mais de um elemento indicado na página. Se tiver, ele gera um loop jQuery usando o método each(). O loop roda uma função aonde ele calcula o valor parallax do fundo para o elemento específico baseado na posição dele na página.

Para isso, ele cria uma variável chamada “elemPos” para pegar a posição Y do elemento na página e divide pela variável “intensity” para sabermos sua posição dentro do efeito parallax.

Na linha seguinte, ele aplica a posição do fundo ao elemento na propriedade CSS "background-position", que usa dois valores para isso. O primeiro valor indica a posição X, que ficará 0. A segunda é a posição Y. Para esta posição, pegamos o valor da variável “wsPos” e subtraímos pelo valor da variável “elemPos” para adaptar a posição do fundo no efeito parallax.

  } else {
    elemPos = $(elem).position().top/intensity;
    $(elem).css({backgroundPosition: "0px "+(elem == "body" ? wsPos : wsPos - elemPos)+"px"})
  }
}

Caso a condicional aberta não retornar verdadeiro, ou seja, só há um elemento indicado na página toda, ele vai definir a variável “elemPos” (a mesma variável do loop each()) e depois vai definir a posição do fundo ao elemento indicado. Mas ao definir a posição Y, ele verifica se o elemento indicado é a tag <body>.

Se for, ele não vai precisar fazer uma subtração por “elemPos” pois afinal, <body> é o elemento que mantém a estrutura visível da página inteira. Se não for, ele faz a subtração pelo valor da variável “elemPos”.

6. Invocando o parallax

Agora que criamos a função responsável por definir o efeito parallax, precisamos aplicar ele aos elementos para que o parallax funcione como esperamos. Então precisamos invocá-lo no javascript nos momentos esperados.

Defina as seguintes linhas no seu javascript depois da função:

$(document).ready(function(){
  parallax("section.parallax:nth-child(1)");
  parallax("section.parallax:nth-child(5)", 10);
});

$(window).scroll(function(){
  parallax("section.parallax:nth-child(1)");
  parallax("section.parallax:nth-child(5)", 10);
});

Aqui é simples. A parte $(document).ready(function(){ ... }); é executada assim que a página termina de carregar o DOM da página (como o navegador executa a estrutura HTML). Aqui a posição inicial do efeito parallax é definida. Já a parte $(window).scroll(function(){ ... }); é executada quando o visitante realiza o scroll na página, então aqui o parallax é realmente executado.

Dentro desses métodos invocamos a função parallax() que acabamos de criar duas vezes. Na primeira, apontamos para a primeira tag <section> que tenha a classe “parallax” (sua posição seria a de número 1 no nível da hierarquia do HTML em que o elemento se encontra). Já na segunda, apontamos para a mesma tag, mas a que se encontra na posição 5.

Repare que na primeira função parallax(), não foi indicado o valor para o parâmetro “intensity”. Como definimos o valor padrão 2 para este parâmetro, é este que ele usará. Na segunda função, definimos o valor 10, ou seja, quando a função calcular a velocidade do efeito parallax, o valor 10 deixará a velocidade mais devagar, se movendo menos que o valor padrão, 2.

7. Efeito criado com sucesso!

Abaixo você verá o efeito em ação usando jQuery. Repare na velocidade do movimento da primeira e da terceira imagem:

Uhn, mas pode ser que você não tenha gostado da ideia de usar jQuery, não é? Se for o caso, continue lendo que ensinarei agora como fazer usando somente CSS3 (note que explicarei os CSS do zero novamente, então pule para as partes novas, se quiser).

Parallax com CSS3

1. Organizando a estrutura

Em seu CSS, adicione as seguintes linhas:

html{height: 100%; overflow: hidden;}
body{margin: 0; font-size: 14px; perspective: 1px; overflow-x: hidden; overflow-y: scroll; height: 100%;}
*{box-sizing: border-box;}
footer,section{padding: 80px 0; position: relative; transform-style: preserve-3d;}
section, section::before{background-size: cover; background-repeat: no-repeat; background-position: center center;}
section:not(.parallax){background-color: #FFF;}
section.parallax, section.parado{height: 100vh;}
section.parado, section.cont{z-index: 1;}

Agora vamos linha por linha:

html{height: 100%; overflow: hidden;}

Primeiramente, precisamos definir uma altura de 100% (pode ser 100vh) e a propriedade “overflow”, que controla o vazamento do seu conteúdo além dos seus limites, precisa estar com o valor “hidden”, ou seja, não mostra o que vai além dele. Essa linha vai fazer a tag <html> ficar sempre com a altura do viewport, praticamente virando uma moldura para o efeito parallax. Sem isso, o efeito não funcionará.

Mas você deve estar se perguntando: “como o usuário vai fazer o scroll na página se o overflow está definido como hidden?” Resolveremos isso a seguir.

body{margin: 0; font-size: 14px; perspective: 1px; overflow-x: hidden; overflow-y: scroll; height: 100%;}

Nesta linha, zeramos a margem da tag <body> e definimos um tamanho de fonte base para a página para valor base da unidade “em”. Se quiser, pode definir uma família de fonte padrão para a página aqui.

Também precisaremos definir a propriedade "perspective", que permite definir uma perspectiva para qualquer elemento que usa posicionamento 3D dentro dele. Então se algum elemento dentro de <body> sofrer alguma alteração através da propriedade "transform", por exemplo, definindo um posicionamento Z, ou uma rotação, o “perspective” influenciará o quão longe o elemento ficará da visão do usuário. Em valores pequenos de perspectiva, uma transformação no elemento causará uma diferença bem notável em pequenas alterações de transformação, causando um efeito 3D bem intenso. Já valores altos não surtirão tanta diferença nas transformações 3D.

Agora, para resolver a questão do overflow da tag <html>, definiremos as propriedades "overflow-x" e "overflow-y" na tag <body>. Enquanto o “overflow” define o controle de vazamento do conteúdo em ambos os eixos, o “overflow-x” e “overflow-y” permitem controlar isso separadamente. O “overflow-x” ficará com o valor “hidden”, já que queremos evitar qualquer scroll horizontal na página. Já o “overflow-y” ficará com o valor “scroll”, já que queremos que o efeito parallax aconteça.

Para finalizar com esta linha, definimos uma altura de 100%, para ele pegar a altura igual ao da tag <html>. Sem isso, o site não terá altura para que o scroll funcione, já que não podemos mais depender da tag <html> para isso.

*{box-sizing: border-box;}

Para cada elemento da página, a definição das dimensões será alterada para o modo “border-box”, ou seja, além do tamanho do conteúdo, ele irá incluir padding e border. Então se aplicar 500px de largura em um elemento, e depois aplicar 5px de padding em todos os lados e ainda uma borda de 2px de espessura, o elemento ainda manterá a largura total de 500px, mas a área do conteúdo diminuirá para que o padding e o border caibam, ficando com 486px de largura somente para o conteúdo.

footer,section{padding: 80px 0; position: relative; transform-style: preserve-3d;}

Para todos os <section> e o <footer>, será adicionado um espaçamento entre o conteúdo e o limite do elemento de 80px verticalmente, ou seja, 80px acima e 80px abaixo. Horizontalmente, ficará zerado. Depois definiremos uma posição relativa para o elemento (position: relative;), pois precisaremos de uma referência de posição para as imagens de fundo.

Também definiremos um estilo de transformação que preservará os aspectos 3D dos elementos que usarem transformação 3D (transform-style: preserve-3d;). Essa propriedade define como serão renderizados os elementos 3D dentro do seu espaço. O valor “preserve-3D” faz com a posição Z seja respeitada, independente de qual transformação o elemento sofrer. E claro, sem transformações, essa propriedade se torna desnecessária, mas não será o caso. Então o “transform-style” deve estar acompanhado da propriedade “transform” quando necessário.

NOTA: defini o “transform-style” aqui para economizar no tanto de linhas dentro do CSS, e como o <footer> não sofrerá transformações, não há problemas.

section, section::before{background-size: cover; background-repeat: no-repeat; background-position: center center;}

Aqui definimos como os fundos serão renderizados nas tags <section>. O fundo deve cobrir toda a área em que ele aparecerá (background-size: cover;), não deverá se repetir (background-repeat: no-repeat;), e tem que ficar posicionada no centro do elemento (background-position: center center;).

Perceba que essas propriedades foram definidas não só para a tag <section>, mas também para seu pseudo-elemento ::before. É nele aonde as imagens aparecerão.

section:not(.parallax){background-color: #FFF;}

Aqui definimos um fundo branco para todas as tags <section> que não contenha a classe “parallax”, ou caso contrário, isso cobriria a imagem com um fundo branco.

section.parallax, section.parado{height: 100vh;}

Nesta linha, apontamos para todas as tags <section> que tenham a classe “parallax” e/ou a classe “parado” aplicada e define uma altura de 100vh, ou seja, pega 100% da altura do viewport, área de visualização da página no navegador.

section.parado, section.cont{z-index: 1;}

Nesta última linha, definimos a propriedade “z-index” igual a 1 para que as <section> que tenham algum conteúdo ou efeito parallax parado ficam na frente das <section> que tenham o efeito parallax normal. Sem isso, as imagens do parallax passarão na frente dos conteúdos durante o scroll.

2. Estilizando os textos

Agora adicione mais essas linhas ao seu CSS:

h1,h2,h3,h4,h5,h6{margin: 0; padding: 0; color: #7294A1;}
h1{position: absolute; top: 20%; right: 1em; font-size: 6vw;}
h2{font-size: 4em;}
p{font-size: 1.2em; line-height: 1.5em;}

Agora, linha por linha:

h1,h2,h3,h4,h5,h6{margin: 0; padding: 0; color: #7294A1;}

Estilizamos todas as tags de títulos, adicionando um tom de azul, mas resetamos a margem e padding dos títulos também. Aqui você pode definir uma família de fonte para os títulos também se não quiser que os títulos usem a fonte padrão.

h1{position: absolute; top: 20%; right: 1em; font-size: 6vw;}

Para a tag <h1>, tag de título principal, vamos definir uma posição personalizada, então vamos definir position: absolute; para conseguirmos posicioná-la aonde quiser. Depois definimos o top: 20%; para que ele considere uma posição que pega 20% da altura do elemento a partir de seu topo. E para que o título redimensione de acordo com a largura do navegador, definimos uma medida usando unidade “vw”. Aqui defina um valor baixo. 6vw está excelente.

h2{font-size: 4em;}

Para a tag <h2>, definimos um tamanho de fonte que é 4 vezes maior que o tamanho de fonte padrão. No caso 4em equivale a 56px (14px * 4em = 56px).

p{font-size: 1.2em; line-height: 1.5em;}

E para as tags de parágrafos, definimos um tamanho de 1.2em, o que dará 16,8px (14px * 1,2em = 16,8px). Também ajustamos a altura das linhas para 1.5em (21px), para que o texto fique com uma aparência mais agradável e a leitura seja fácil.

3. Definindo o objetivo das classes

Ainda no CSS, adicione mais essas linhas:

.cont{padding: 80px calc((100% - 1200px) / 2);}
.cont *{margin-left: 10px; margin-right: 10px;}

section.parado{background-attachment: fixed;}
section.dark{background-color: #7294A1;}
section.dark *{color: #FFF;}
section.parallax::before{content: ""; display: block; position: absolute; top: 0; left: 0; right: 0; bottom: 0; transform-origin: center center 0; transform: translateZ(-1px) translateX(-10px) scale(2); z-index: -1;}

E, linha por linha:

.cont{padding: 80px calc((100% - 1200px) / 2);}

A classe “cont” define o alinhamento do conteúdo através do ajuste dinâmico da propriedade “padding”. Aqui iremos fazer uma gambiarra, para manter o HTML limpo e ainda assim atingirmos o objetivo da classe “cont”. Inicialmente, definimos um valor de 80px para os paddings verticais. Já para os paddings horizontais, usaremos a função calc().

A função calc() permite usar contas para chegar a um valor, mas somente contas básicas, usando os operadores de soma (+), subtração (-), multiplicação (*) e divisão (/). Pode ser usado parênteses para definir uma ordem prioritária alta de cálculos. Depois disso, priorizasse multiplicações, depois divisões, depois soma e por fim, subtração. Os números podem ser escritos usando qualquer unidade válida para o CSS, e é importante definir espaço entre os números e os operadores.

No caso acima, pedimos para que o padding pegue 100% da largura do elemento e subtraia por 1200px, que será a largura máxima do conteúdo. Depois mandamos ele dividir por 2, já que queremos que cada metade fique em cada lado do elemento, centralizando assim o conteúdo.

.cont *{margin-left: 10px; margin-right: 10px;}

Aqui é apontado todos os elementos dentro da classe “cont”, aplicando uma margem de 10px dos dois lados dos elementos, somente para que eles não fiquem grudados nos limites da página ao redimensionar o navegador.

section.parado{background-attachment: fixed;}

A classe “parado” serve para realizar o parallax aonde a imagem fica parada enquanto o resto segue o scroll da página. Esta classe deverá ser usada somente com tags <section>. Para o parallax funcionar, usamos a propriedade <background-attachment> com o valor "fixed". E só.

section.dark{background-color: #7294A1;}

A classe “dark” define um estilo com um esquema de cores mais escura para o <section>. No caso, definimos um tom de azul mais escuro para o elemento.

section.dark *{color: #FFF;}

E para todos os elementos do <section> com a classe “dark”, definimos a cor branca para o seu conteúdo. Poderíamos ter definido isso na linha anterior, mas isso não seria aplicado aos títulos pois eles já têm uma cor definida.

section.parallax::before{content: ""; display: block; position: absolute; top: 0; left: 0; right: 0; bottom: 0; transform-origin: center center 0; transform: translateZ(-1px) translateX(-10px) scale(2); z-index: -1;}

Aqui definiremos o CSS para as imagens que só aparecerão nas <section> com a classe “parallax”. Como dito antes, é nos pseudo-elementos ::before que as imagens aparecerão para que o efeito parallax funcione. Sendo um pseudo-elemento tratado como um bloco, é necessário então definir o content: ""; e o display: block;.

E como precisamos que o elemento tenha sempre 100% de largura e altura, podemos optar por uma caminho diferente. Por ser um elemento que definimos com posicionamento absoluto (position: absolute;) para ter seu <section> como referência, podemos definir todas as propriedades de posicionamento absoluto com o valor 0, assim ele se estica para adotar a largura e altura total de espaço disponível para ele (top: 0; left: 0; right: 0; bottom: 0;).

Outro caminho seria definir a altura e largura mínima igual ao viewport (min-width: 100vw; min-height: 100vh;), ou se preferir, nem precisaria ser valores mínimos (width: 100vw; height: 100vh;). Aqui seria necessário deixar somente o top: 0; pois como já definimos uma altura e largura, somente o “top” será necessário para que o elemento sempre tenha a parte superior como referência de posição inicial. De qualquer forma, o posicionamento via transformação fica livre para uso.

Agora, lembra que definimos o transform-style: preserve-3d; em todos os <section>? Aqui vamos definir as transformações que os pseudo-elementos sofrerão através da propriedade "transform". Primeiramente, vamos definir um ponto de origem para as transformações terem isso como referência (o que seria como o ponto zero de referência). Queremos que isso seja no centro tanto na horizontal quanto na vertical e também na profundidade. Para isso, definimos transform-origin: center center 0; que define respectivamente os eixos X, Y e Z no exato centro do elemento. Note que o valor “center” não funciona para o eixo Z pois ele não é um valor relativo (percebe que ele não usa unidades), já que é tratado como se fosse uma ordenação de camadas. Então 0 seria a posição padrão de qualquer elemento que tenha posicionamento 3D.

Agora quanto as transformações, vamos definir uma posição do eixo Z igual a -1px (translateZ(-1px)) para que ele fique atrás de qualquer conteúdo que a <section> possa ter. Como também havíamos definido o perspective: 1px; na tag <body>, a posição Z fará o pseudo-elemento dar uns passos consideráveis para trás, ficando um pouco longe. Para arrumar isso, também alteramos a escala do pseudo-elemento para ser o dobro do tamanho original (scale(2)), ficando praticamente com o tamanho real. Pode acontecer de dar algum bug e sobrar um espaço a ser coberto a sua esquerda, então definimos um posicionamento X negativo para arrumar isso (translateX(-10px)). Essa transformação toda irá causar o efeito parallax nas imagens.

Se quiser mudar a velocidade do efeito, então teria que mudar a posição Z para um valor menor ainda e ajustar a escala para um valor maior. Lembre que para a escala, você pode usar valores com casas decimais (2.15, 2.457, 5.02, etc). Você só terá que testar os valores até descobrir um que fique certinho.

E para finalizar, definimos um z-index: -1; para termos certeza que a imagem nunca irá invadir o espaço de outros elementos fora do parallax.

4. As imagens e o rodapé

Agora, vamos para as linhas finais. Adicione as linhas abaixo no seu CSS:

section:nth-child(1)::before{background-image: url("https://blog.dsaportfolio.com.br/tutoriais-demo/parallax-simples/winter-landscape-2571788_1920.jpg");}
section:nth-child(3){background-image: url("https://blog.dsaportfolio.com.br/tutoriais-demo/parallax-simples/snowflakes-1236245_1920.jpg");}
section:nth-child(5)::before{background-image: url("https://blog.dsaportfolio.com.br/tutoriais-demo/parallax-simples/yellowstone-national-park-1581879_1920.jpg");}

footer{background-color: #7B969A; font-size: 2.5em; font-weight: bold; color: #9EC1C6; text-align: center; font-style: italic;}

Agora, vamos às linhas:

section:nth-child(1)::before{background-image: url("https://blog.dsaportfolio.com.br/tutoriais-demo/parallax-simples/winter-landscape-2571788_1920.jpg");}
section:nth-child(3){background-image: url("https://blog.dsaportfolio.com.br/tutoriais-demo/parallax-simples/snowflakes-1236245_1920.jpg");}
section:nth-child(5)::before{background-image: url("https://blog.dsaportfolio.com.br/tutoriais-demo/parallax-simples/yellowstone-national-park-1581879_1920.jpg");}

Aqui apontamos em cada linha para um elemento <section> na ordem que está no HTML usando o seletor :nth-child(). Como sabemos a posição certinha de cada elemento na estrutura (e no caso temos certeza que a página não sofrerá nenhuma alteração manual ou dinâmica na estrutura), podemos indicar a posição exata de cada elemento.

No caso, o seletor começa a contar do 1 (ele não considera o valor 0), então vamos apontar para o primeiro, terceiro e quinto seletores, cada um na sua linha. E para cada um, usamos a propriedade background-image com a função url(), indicando o endereço da imagem de fundo.

Como o parallax ocorre em pseudo-elementos ::before, não devemos esquecer de defini-los nas linhas das imagens que estarão no efeito.

footer{background-color: #7B969A; font-size: 2.5em; font-weight: bold; color: #9EC1C6; text-align: center; font-style: italic;}

Aqui definimos um estilo para o rodapé semelhante ao da classe “dark”. Definimos um tamanho próprio de fonte de 2.5em (font-size: 2.5em; = 35px), um peso em negrito (font-weight: bold;), cores de fundo (background-color: #7B969A;) e de cor (color: #9EC1C6;) azulados, alinhamos o texto centralizado (text-align: center;) e deixamos o texto itálico (font-style: italic;). Simples!

5. Efeito CSS3 pronto!

Abaixo você verá o efeito em ação usando CSS3:

E agora, qual caminho para o efeito eu escolho?

O efeito com jQuery permite controlar melhor a velocidade do efeito em relação ao scroll, já com o CSS3, fazer isso ser torna um pouquinho mais chato, mas é bem possível também. A parte boa de fazer isso com CSS3 é que o peso total de arquivos do site será menor, já que não terá a parte em javascript, economizando bytes.

Sinceramente, eu indicaria fazer com jQuery se seu site tiver muitos efeitos parallax e se você ter certeza que a maioria do seu público-alvo usa uma internet com velocidade entre razoável e boa, apesar de que o código jQuery é pequeno. Se não for o caso, então te encorajo a usar o efeito com CSS3, por ser uma opção mais moderna também.

Espero que tenha gostado deste tutorial! Até a próxima!

Manda sua palavra ae! Deixe um comentário: