Scrolling yang terkontrol dengan baik dengan CSS Scroll Snap

Buat pengalaman scroll yang terkontrol secara baik dengan mendeklarasikan posisi snap scroll.

Robert Flack
Robert Flack
Majid Valipour
Majid Valipour

Fitur Snap Scroll CSS memungkinkan developer web membuat pengalaman scroll yang terkontrol secara baik dengan mendeklarasikan posisi pengepasan scroll. Artikel dan carousel gambar dengan penomoran halaman adalah dua contoh yang umum digunakan untuk hal ini. Snap Scroll CSS menyediakan API yang mudah digunakan dan konsisten untuk membangun pola UX yang populer ini.

Latar belakang

Kasus untuk pengepasan scroll

Scrolling adalah cara yang populer dan alami untuk berinteraksi dengan konten di web. Cara ini adalah cara native platform untuk memberikan akses ke lebih banyak informasi daripada yang terlihat di layar sekaligus, sehingga menjadi sangat penting pada platform seluler dengan ruang layar yang terbatas. Jadi, tidak mengherankan bahwa penulis web semakin memilih untuk mengatur konten ke dalam daftar datar yang dapat di-scroll daripada hierarki dalam.

Kelemahan utama scroll adalah kurangnya presisi. Scroll yang berakhir jarang yang sejajar dengan paragraf atau kalimat. Hal ini bahkan lebih jelas untuk konten yang dipaginasi atau item dengan batas yang bermakna ketika scroll selesai di tengah halaman atau gambar, yang membuat terlihat sebagian. Kasus penggunaan ini memanfaatkan pengalaman scroll yang dikontrol dengan baik.

Developer web telah lama mengandalkan solusi berbasis JavaScript untuk mengontrol scroll guna membantu mengatasi kekurangan ini. Namun, solusi berbasis JavaScript gagal memberikan solusi fidelitas penuh karena kurangnya primitif penyesuaian scroll atau akses ke scroll gabungan. Snap Scroll CSS memastikan solusi yang cepat, andal, dan mudah digunakan yang berfungsi secara konsisten di seluruh browser.

Scroll Snap CSS memungkinkan penulis web menandai setiap container scroll dengan batas untuk operasi scroll yang akan diselesaikan. Selanjutnya, browser memilih posisi akhir yang paling sesuai, bergantung pada detail operasi scroll, tata letak dan visibilitas container scroll, serta detail posisi snap, lalu menganimasikannya dengan mulus. Kembali ke contoh sebelumnya, saat pengguna selesai men-scroll korsel, gambar yang terlihat akan langsung masuk ke tempatnya. Tidak perlu penyesuaian scroll oleh JavaScript.

Contoh penggunaan snap scroll CSS dengan carousel gambar.
Contoh penggunaan snap scroll CSS dengan carousel gambar. Di sini pengepasan scroll memastikan pada akhir scroll, pusat horizontal gambar sejajar dengan pusat horizontal container scroll.

Snap Scroll CSS

Pengepasan scroll adalah tindakan menyesuaikan offset scroll container scroll agar berada pada posisi snap yang diinginkan setelah operasi scroll selesai.

Penampung scroll dapat diikutsertakan dalam pengepasan scroll dengan menggunakan properti scroll-snap-type. Ini akan memberi tahu browser bahwa browser harus mempertimbangkan untuk mengikat container scroll ini ke posisi snap yang dihasilkan oleh turunannya. scroll-snap-type menentukan sumbu tempat scroll terjadi: x, y, atau both, dan keketatan snap: mandatory, proximity. Selengkapnya tentang hal ini akan dibahas nanti.

Posisi snap dapat dihasilkan dengan mendeklarasikan perataan yang diinginkan pada sebuah elemen. Posisi ini adalah offset scroll di mana penampung scroll ancestor terdekat dan elemen disejajarkan seperti yang ditentukan untuk sumbu yang diberikan. Perataan berikut dapat dilakukan di setiap sumbu: start, end, center.

Perataan start berarti tepi awal snapport container scroll harus diratakan dengan tepi awal area snap elemen. Demikian pula, perataan end dan center berarti tepi atau tengah snapport container scroll harus di-flush dengan tepi akhir atau tengah area snap elemen.

Contoh berbagai perataan pada sumbu scroll horizontal.

Contoh berikut mengilustrasikan cara menggunakan konsep ini.

Kasus penggunaan umum untuk pengepasan scroll adalah korsel gambar. Misalnya, untuk membuat carousel gambar horizontal yang pas dengan setiap gambar saat Anda men-scroll, kita dapat menentukan penampung scroll agar memiliki scroll-snap-type wajib pada sumbu horizontal. tetapkan setiap gambar ke scroll-snap-align: center untuk memastikan bahwa pengikatan tersebut menempatkan gambar di tengah dalam carousel.

#gallery {
  scroll-snap-type: x mandatory;
  overflow-x: scroll;
  display: flex;
}

#gallery img {
   scroll-snap-align: center;
}
<div id="gallery">
  <img src="cat.jpg">
  <img src="dog.jpg">
  <img src="another_cute_animal.jpg">
</div>

Karena posisi snap dikaitkan dengan suatu elemen, algoritme snap dapat cerdas dalam hal kapan dan bagaimana snap, berdasarkan elemen dan ukuran container scroll. Misalnya, perhatikan kasus saat satu gambar lebih besar daripada carousel. Algoritma snapping yang naif dapat mencegah pengguna menggeser pengguna untuk melihat gambar penuh. Namun, spesifikasi memerlukan implementasi untuk mendeteksi kasus ini dan memungkinkan pengguna untuk bebas men-scroll dalam gambar tersebut yang hanya langsung dipaskan ke tepinya.

Lihat demo | Sumber

Contoh: halaman produk perjalanan

Kasus umum lainnya yang dapat memanfaatkan pengepasan scroll adalah halaman dengan beberapa bagian logis yang dapat di-scroll secara vertikal, misalnya, halaman produk standar. scroll-snap-type: y proximity; lebih cocok untuk kasus seperti ini. Hal ini tidak mengganggu saat pengguna men-scroll ke tengah bagian tertentu, tetapi juga men-scroll dan menarik perhatian ke bagian baru saat mereka men-scroll cukup dekat.

Berikut adalah cara melakukannya:

article {
  scroll-snap-type: y proximity;
  /* Reserve space for header plus some extra space for sneak peeking. */
  scroll-padding-top: 15vh;
  overflow-y: scroll;
}
section {
  /* Snap align start. */
  scroll-snap-align: start;
}
header {
  position: fixed;
  height: 10vh;
}
<article>
  <header> Header </header>
  <section> Section One </section>
  <section> Section Two </section>
  <section> Section Three </section>
</article>

Padding dan margin scroll

Halaman produk memiliki header atas posisi tetap. Desain ini juga meminta beberapa bagian atas agar tetap terlihat saat container scroll diikat untuk memberikan tanda desain kepada pengguna tentang konten di atas.

Properti scroll-padding adalah properti CSS baru yang dapat digunakan untuk menyesuaikan area tampilan yang efektif dari container scroll, atau snapport, yang digunakan saat menghitung perataan scroll scroll. Properti ini menentukan inset pada kotak padding container scroll. Dalam contoh kita, inset tambahan 15vh ditambahkan ke bagian atas, yang menginstruksikan browser untuk mempertimbangkan posisi yang lebih rendah, 15vh di bawah tepi atas container scroll, sebagai tepi awal vertikalnya untuk snap scroll. Saat mengepaskan, tepi awal elemen target snap akan dibersihkan dengan posisi baru ini, sehingga menyisakan ruang di atasnya.

Properti scroll-margin menentukan jumlah awal yang digunakan untuk menyesuaikan kotak efektif target snap, mirip dengan cara scroll-padding berfungsi pada penampung scroll snap.

Anda mungkin telah melihat bahwa kedua properti ini tidak memiliki kata "snap" di dalamnya. Hal ini disengaja karena benar-benar memodifikasi kotak untuk semua operasi scroll yang relevan dan bukan hanya snap scroll. Misalnya, Chrome mempertimbangkannya saat menghitung ukuran halaman untuk operasi scroll paging seperti PageDown dan PageUp, serta saat menghitung jumlah scroll untuk operasi Element.scrollIntoView().

Lihat demo | Sumber

Interaksi dengan API scroll lainnya

API Scroll DOM

Pengepasan scroll setelah semua operasi scroll, termasuk yang dimulai oleh skrip. Saat Anda menggunakan API seperti Element.scrollTo, browser akan menghitung posisi scroll yang diinginkan dari operasi, lalu menerapkan logika snap yang sesuai untuk menemukan lokasi akhir yang diikat. Dengan demikian, skrip pengguna tidak perlu melakukan penghitungan manual untuk snap.

Scroll mulus

Scrolling halus mengontrol perilaku operasi scroll terprogram saat snap scroll menentukan tujuannya. Karena keduanya mengontrol aspek ortogonal scroll, keduanya dapat digunakan bersama dan saling melengkapi.

Perilaku overscroll

API perilaku overscroll mengontrol cara scroll dirantai di beberapa elemen dan tidak terpengaruh oleh snap scroll.

Peringatan dan praktik terbaik

Hindari penggunaan snap wajib saat elemen target berjarak luas. Hal ini dapat menyebabkan konten di antara posisi snap menjadi tidak dapat diakses.

Dalam banyak kasus, scroll-snap dapat ditambahkan sebagai peningkatan tanpa perlu deteksi fitur. Jika diperlukan, gunakan @supports atau CSS.supports untuk mendeteksi dukungan untuk Snap Scroll CSS. Hindari penggunaan scroll-snap-type yang juga ada dalam spesifikasi yang tidak digunakan lagi.

Deteksi fitur di CSS

@supports (scroll-snap-align: start) {
  article {
    scroll-snap-type: y proximity;
    scroll-padding-top: 15vh;
    overflow-y: scroll;
  }
}

Deteksi fitur di JavaScript

if (CSS.supports('scroll-snap-align: start')) {
  // use css scroll snap
} else {
  // use fallback
}

Jangan berasumsi bahwa API scroll terprogram seperti Element.scrollTo selalu selesai pada offset scroll yang diminta. Pengepasan scroll dapat menyesuaikan offset scroll setelah scroll terprogram selesai. Perhatikan bahwa ini bukan asumsi yang baik bahkan sebelum snap scroll karena scroll mungkin terganggu karena alasan lain, tetapi terutama terjadi pada snap scroll.

Pekerjaan mendatang

Pengalaman scroll adalah fokus dari survei terbaru oleh tim Chrome. Hasil survei mengidentifikasi beberapa area yang memerlukan upaya tambahan untuk mengurangi kesenjangan antara library plugin dan CSS. Tugas mendatang akan berfokus pada scroll-snap, termasuk:

  1. Ketersediaan dan kompatibilitas API di berbagai browser.
  2. Bekerja di API CSS baru seperti scroll-start.
  3. Kerjakan peristiwa JS baru seperti snapChanged().