DEV Community

Cover image for Smooth Scrolling - JavaScript & CSS
boibolang
boibolang

Posted on • Updated on

Smooth Scrolling - JavaScript & CSS

Kali ini kita akan mendemokan smooth scrolling, yaitu efek beerganti posisi secara smooth/halus. Smooth scrolling sendiri bisa dibilang merupakan fitur wajib dalam sebuah halaman web, tentunya supaya efek smooth scroling terlihat, setting animation effect (pada Window 11) harus aktif, untuk versi window lain silahkan diaktifkan. Untuk Mac saya tidak tahu settingnya dimana sebab belum pernah pegang Macbook, yang jelas meskipun efek smooth scrolling pada browser sudah aktif namun jika animation effect pada sistem operasi tidak aktif maka percuma saja. Pada demo kali kita akan mencoba 3 jenis metode scrolling yaitu :

  • Scrolling biasa
  • Smooth scrolling cara lama
  • Smooth scrolling cara baru

Pertama-tama buatlah file html, css dan js. Untuk template kode file html dan css sebagai berikut.

index.html



<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="styles.css" />
    <title>Document</title>
  </head>
  <body>
    <header>
      <ul>
        <li><button class="btnScroll1">Section 1</button></li>
        <li><button class="btnScroll2">Section 2</button></li>
        <li><button class="btnScroll3">Section 3</button></li>
      </ul>
    </header>
    <section class="section" id="section-1">
      <p>This is section 1</p>
    </section>
    <section class="section" id="section-2">
      <p>This is section 2</p>
    </section>
    <section class="section" id="section-3">
      <p>This is section 3</p>
    </section>
    <script src="smooth.js"></script>
  </body>
</html>


Enter fullscreen mode Exit fullscreen mode

styles.css



:root {
  --color-primary: #fd424b;
}

* {
  margin: 0;
  padding: 0;
  border: 0;
}

header {
  color: var(--color-primary);
  font-size: 30px;
  font-weight: bold;
  background-color: rgb(239, 245, 58);
  margin-top: 0px;
  top: 0;
  width: 100%;
  position: sticky;
  /* position: fixed; */
}

ul {
  list-style: none;
  display: flex;
}

li {
  margin: 0 20px;
}

button {
  background-color: rgb(239, 245, 58);
  font-size: 20px;
  font-weight: bold;
}

button:hover {
  color: #fd424b;
  cursor: pointer;
}

.section {
  height: 1000px;
}

#section-1 {
  background-color: rgb(243, 125, 52);
}

#section-2 {
  background-color: rgb(173, 243, 52);
}

#section-3 {
  background-color: rgb(66, 150, 246);
}

p {
  font-weight: bold;
  font-size: 100px;
  padding-top: 34.667px;
}


Enter fullscreen mode Exit fullscreen mode

Scrolling biasa
Scrolling dengan metode ini agak rumit, meskipun sudah jarang sekali dipakai (karena ada metode baru yang lebih sederhana) tapi saya pikir perlu sebagai dasar pemahaman. Metode scrolling ini membutuhkan koordinat (X dan Y, atau left dan top) posisi tujuan. Darimana kita bisa mendapatkan koordinat tersebut ? Dengan metode getBoundingClientRect(); kita bisa mengambil koordinat posisi yang kita inginkan. Berikut kode JavaScript-nya.



'use strict';

// Smooth scrolling
const btnScroll1 = document.querySelector('.btnScroll1');
const btnScroll2 = document.querySelector('.btnScroll2');
const btnScroll3 = document.querySelector('.btnScroll3');
const section1 = document.querySelector('#section-1');
const section2 = document.querySelector('#section-2');
const section3 = document.querySelector('#section-3');

btnScroll1.addEventListener('click', function (e) {
  const sect1coord = section1.getBoundingClientRect();
  console.log(sect1coord);
  console.log('left/top:', sect1coord.left, sect1coord.top);
});


Enter fullscreen mode Exit fullscreen mode

Halaman web belum saya manipulasi, artinya posisi <section class="section" id="section-1> adalah pada posisi default, jika kita klik menu Section 1 hasilnya sebagai berikut.

result
Koordinat x/left bernilai 0 sedangkan koordinat y/top bernilai 34.6666 (dalam satuan pixel). Kenapa kita harus mengetahui kordinat tersebut ? Sebab koordinat itulah nanti yang akan menjadi posisi tujuan scrolling kita, kalau kita set koorniat x/y = 0/0 kan sama saja ? Benar jika posisi yang kita tuju berada pada posisi teratas, namun dengan semakin kompleksnya halaman web posisi scrolling tidak mesti menuju halaman paling atas. Sekarang mari kita implementasikan scrolling pada event handler diatas.



btnScroll1.addEventListener('click', function (e) {
  const sect1coord = section1.getBoundingClientRect();
  console.log(sect1coord);
  console.log('left/top:', sect1coord.left, sect1coord.top);

  // Scrolling
  window.scrollTo(sect1coord.left, sect1coord.top);
});


Enter fullscreen mode Exit fullscreen mode

result

Apa yang terjadi ? Scrooling kita berfungsi tapi kenapa lompat-lompat ? Itu dikarenakan metode getBoundingClientRect(); bersifat relatif terhadap viewport, artinya koordinat x/y atau letf/top posisinya akan berubah sesuai dengan halaman web yang terlihat. Untuk mengatasinya bisa kita lakukan beberapa hal, yang pertama adalah mengubah posisi header pada file css dari sticky menjadi fixed, silahkan dicoba. Yang kedua adalah menyertakan posisi window scroll pada tujuan sebagai berikut.



btnScroll1.addEventListener('click', function (e) {
  const sect1coord = section1.getBoundingClientRect();
  console.log(sect1coord);
  console.log('left/top:', sect1coord.left, sect1coord.top);

  // Scrolling
  window.scrollTo(sect1coord.left + window.scrollX, sect1coord.top + window.scrollY);
});


Enter fullscreen mode Exit fullscreen mode

Untuk smooth scrolling cara lama dan cara baru kita implementasikan ke Section 2 dan Section 3, kode programnya sebagai berikut.



btnScroll2.addEventListener('click', function (e) {
  const sect2coord = section2.getBoundingClientRect();

  // Smooth scrolling cara lama
  window.scrollTo({
    left: sect2coord.left + window.scrollX,
    top: sect2coord.top + window.scrollY,
    behavior: 'smooth',
  });
});

btnScroll3.addEventListener('click', function (e) {
  // Smooth scrolling cara baru
  section3.scrollIntoView({ behavior: 'smooth' });
});


Enter fullscreen mode Exit fullscreen mode

Hasilnya adalah sebagai berikut.

result

Top comments (0)