Efekt parallax wykonany w czystym CSS

Front-end 9 października 2021

Pewnie kojarzysz efekt, w którym konkretna część strony internetowej przesuwa się w innej szybkości niż reszta. Niestety zwykle bazuje on na dodatkowych skryptach JavaScript, które w tym przypadku są zbędne i mogą tylko niepotrzebnie spowalniać naszą stronę.

Zbędne, bo właśnie - ten efekt możemy wdrożyć znacznie przyjemniej, tylko stylizując nasz element w CSS. Szczególnie w obecnych czasach, gdy właściwości CSSa, o których opowiem, są w pełni dostępne w aktualnych przeglądarkach!

Pierwsza wersja tego artykułu powstała w roku 2017, gdzie o rzeczach, które pokażę, mówiłem bardziej jako o "ciekawostce". Cudnie jest widzieć, że obecnie mogę mówić o tym, jako o czymś, co po prostu można wdrożyć 🥳

Dobra, już pokazuję jak to zrobić!

Aaaaaalbo, zanim jeszcze zaczniemy, tutaj znajdziesz działający przykład, który prezentuje ten efekt:

See the Pen Efekt parallax w samym CSS by Robert Orliński (@ROrlilnski) on CodePen.

Jeśli tylko chcesz, to podrzucony wyżej snippet możesz swobodnie edytować ✨ Lećmy!

Trochę kodu HTML

Na początku nie mogło go zabraknąć. Stworzę prostą stronę, z trzema sekcjami (w tym jedna będzie miała zastosowany efekt parallax).

Oto nasz kod HTML:

<main class="wrapper">
  
  <section class="row row--static"></section>

  <section class="row row--with-parallax"></section>

  <section class="row row--static"></section>
  
</main>

Jeśli nie do końca wiesz, dlaczego klasy zapisałem w taki sposób, jak tu widać, możesz sprawdzić mój artykuł na temat metodologii BEM, który przybliży Ci ten temat (którego swoją drogą zapewne w przyszłości i tak przyjdzie Ci się nauczyć, bo metodologii tej używa się baaardzo często).

Kod (S)CSS, składający się na nasz efekt parallax

Może na początku pokażę, jak wygląda on w pełnej pełnej okazałości:

body {
  margin: 0;
}

.wrapper {
  height: 100vh;
  overflow-x: hidden;
  
  perspective: 2px;
}

.row {
  position: relative;
  height: 70vh;
  
  &::after {
    content: '';
    
    position: absolute;
    inset: 0;
  }
  
  &--static {
    z-index: 1;
    background-color: #303030;
  }

  &--with-parallax {
    transform-style: preserve-3d;
    
    &::after {
      background: url('https://robertorlinski.pl/wp-content/uploads/2021/10/forest.jpg') center;

      transform: translateZ(-1px) scale(2);
    }
  }
}

Całość jest napisana w SCSSie, ponieważ:

  1. SCSS jest ekstremalnie przyjemny i chyba nikt z nas, kto tworzy już trochę strony i aplikacje internetowe, nie może powiedzieć, że nie zna jego składni.
  2. Bardzo przyjaźnie można w nim pisać w ramch metodologii BEM, o której już wspominałem przy okazji HTMLa.

Okej, przeanalizujmy go krok po kroku:

body {
  margin: 0;
}

Tu nie ma zbyt dużo do tłumaczenia, eliminujemy domyślny margines. Tak naprawdę dodałem to tylko po to, aby strona z przykładem wyglądała lepiej 😌

.wrapper {
  height: 100vh;
  overflow-x: hidden;
  
  perspective: 2px;
}

Na początku wysokość kontenera. 100vh oznacza, że jest ona równa wysokości okna przeglądarki, co jest potrzebne, aby perspektywa zadziałała (więcej o niej za chwilkę), a tym samym cały efekt.

Overflow-x: hidden odpowiada za ukrycie przepełnienia strony w poziomie. Aby nasz efekt zadziałał, musimy powiększać późniejsze elementy, a gdy tak zrobimy, to wyjdą poza widok przeglądarki, a tym samym utworzą poziomy scroll-bar.

Na końcu używamy właściwości perspective z wartością 2px, która to odpowiada za ułożenie perspektywy, z której patrzy użytkownik, względem powierzchni naszej strony internetowej oraz symuluje trójwymiarowość obszaru roboczego (viewportu).

Dzięki temu, możemy zasymulować sytuację, w której jedne elementy są bliżej użytkownika, a inne dalej i to w sposób, który jest widoczny na pierwszy rzut oka (nie tak jak to działa w przypadku z-indexów, gdzie dane elementy przykrywają inne, nie zmieniając swojego zachowania).

.row {
  position: relative;
  height: 70vh;
  
  &::after {
    content: '';
    
    position: absolute;
    inset: 0;
  }
  
  &--static {
    z-index: 1;
    background-color: #303030;
  }

  /* ... */
}

Celowo pominąłem ostatni blok kodu, bo o nim powiemy sobie później najwięcej. Powyżej z kolei, ustawiamy tylko położenie szarych sekcji, ich kolor, rozmiary każdej sekcji i rozmiary pseudoelementów.

Tym ostatnim nadajemy wielkość elementu .row za sprawą właściwości inset.

.row {
  /* ... */

  &--with-parallax {
    transform-style: preserve-3d;
    
    &::after {
      background: url('https://robertorlinski.pl/wp-content/uploads/2021/10/forest.jpg') center;

      transform: translateZ(-1px) scale(2);
    }
  }
}

I ostatnia część naszego kodu. Skupmy się na pierwszej i ostatniej właściwości.

Dzięki zastosowaniu transform-style: preserve-3d, nasze rzędy stają się de facto trójwymiarowe, dzięki czemu ich elementy możemy przesuwać, obracać itp., nie tylko na jednej płaszczyźnie (płaszczyźnie samej strony internetowej), ale również na płaszczyźnie przecinającą ją.

Świetnie o tej właściwości opowiada dokumentacja MDN, gdzie również możesz zobaczyć przyjemne demo, prezentujące różnicę między elementami, których ta właściwość została zastosowana, a tymi bez niej.

Z kolei za pomocą ostatniej linijki (właściwości transform) na początku oddalamy element względem viewportu za pomocą wartości translateZ (staje się on optycznie mniejszy, przez pozorne jego oddalenie), po czym go powiększamy dzięki wartości scale.

Dzięki temu to co jest dalej, porusza się pozornie wolniej - tak jak w prawdziwym życiu.

Podsumowanie

Jak widać dzięki paru właściwościom w kodzie CSS, możemy stworzyć bardzo prosty oraz funkcjonalny efekt paralaksy na każdej stronie internetowej!

Jeszcze raz podrzucam działające demo, które możesz swobodnie edytować:

See the Pen Efekt parallax w samym CSS by Robert Orliński (@ROrlilnski) on CodePen.

Do następnego razu 🎉

Komentarze

Może dodasz coś od siebie?