Scrolling yang terkontrol dengan baik dengan CSS Scroll Snap

Buat pengalaman scroll yang terkontrol dengan baik dengan mendeklarasikan posisi pengepasan scroll.

Robert Flack
Robert Flack
Majid Valipour
Majid Valipour

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

Latar belakang

Kasus untuk pengepasan scroll

Men-scroll adalah cara populer dan alami untuk berinteraksi dengan konten di web. Fitur ini adalah sarana native platform untuk memberikan akses ke lebih banyak informasi daripada yang terlihat di layar sekaligus, yang 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 dibandingkan hierarki dalam.

Kelemahan utama scroll adalah kurangnya presisi. Scroll jarang kali disejajarkan dengan paragraf atau kalimat. Hal ini bahkan lebih jelas untuk konten yang diberi nomor halaman atau item baris dengan batas yang bermakna saat scroll selesai di tengah halaman atau gambar, sehingga membuatnya terlihat sebagian. Kasus penggunaan ini mendapatkan manfaat dari 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. CSS Scroll Snap memastikan solusi yang cepat, fidelitas tinggi, dan mudah digunakan yang berfungsi secara konsisten di seluruh browser.

Snap Scroll CSS memungkinkan penulis web menandai setiap penampung 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 lancar. Kembali ke contoh sebelumnya, saat pengguna selesai men-scroll carousel, gambar yang terlihat akan langsung muncul. Tidak ada penyesuaian scroll yang diperlukan oleh JavaScript.

Contoh penggunaan snap scroll css dengan carousel gambar.
Contoh penggunaan snap scroll css dengan carousel gambar. Di sini, pengepasan scroll memastikan di akhir scroll, tengah horizontal gambar sejajar dengan bagian tengah horizontal container scroll.

CSS Scroll Snap

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

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

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

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

Contoh berbagai perataan pada sumbu scroll horizontal.

Contoh berikut mengilustrasikan cara menggunakan konsep ini.

Kasus penggunaan umum untuk pengepasan scroll adalah carousel gambar. Misalnya, untuk membuat carousel gambar horizontal yang dipaskan ke setiap gambar saat Anda men-scroll, kita dapat menentukan container scroll agar memiliki scroll-snap-type wajib pada sumbu horizontal. tetapkan setiap gambar ke scroll-snap-align: center untuk memastikan bahwa pengepasan 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 elemen, algoritma snap dapat menentukan kapan dan bagaimana snap dilakukan dengan mempertimbangkan elemen dan ukuran penampung scroll. Misalnya, pertimbangkan kasus saat satu gambar lebih besar dari carousel. Algoritma pengepasan yang naif dapat mencegah pengguna menggeser untuk melihat gambar penuh. Namun, spesifikasi memerlukan implementasi untuk mendeteksi kasus ini dan memungkinkan pengguna men-scroll secara bebas dalam gambar tersebut hanya dengan menggeser di tepinya.

Lihat demo | Sumber

Contoh: halaman produk perjalanan

Kasus umum lain yang dapat memanfaatkan pengepasan scroll adalah halaman dengan beberapa bagian logis untuk 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 mengepaskan dan mengarahkan perhatian ke bagian baru saat men-scroll cukup dekat.

Berikut 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 untuk tetap terlihat saat penampung scroll di-snap untuk memberikan isyarat desain kepada pengguna tentang konten di atas.

Properti scroll-padding adalah properti css baru yang dapat digunakan untuk menyesuaikan area terlihat yang efektif dari container scroll, atau snapport, yang digunakan saat menghitung perataan scroll. Properti ini menentukan inset terhadap kotak padding penampung scroll. Dalam contoh kami, inset tambahan 15vh ditambahkan ke atas, yang menginstruksikan browser untuk mempertimbangkan posisi yang lebih rendah, 15vh di bawah tepi atas container scroll, sebagai tepi awal vertikalnya untuk pengepasan scroll. Saat mengikat, tepi awal elemen target snap akan dipasok dengan posisi baru ini, sehingga menyisakan ruang di atas.

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

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

Lihat demo | Sumber

Interaksi dengan API scroll lainnya

DOM Scrolling API

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

Scroll lancar

Scroll halus mengontrol perilaku operasi scroll terprogram, sedangkan snap scroll menentukan tujuannya. Karena kontrol 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 saling berjauhan. Hal ini dapat menyebabkan konten yang berada 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 bagi 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 secara 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 telah terganggu karena alasan lain, tetapi terutama terjadi dengan snap scroll.

Pekerjaan di masa depan

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. Pekerjaan mendatang akan berfokus pada scroll-snap, termasuk:

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