1. Membuat Karusel & Galeri Geser Murni CSS dengan scroll-snap
Dulu, membuat deretan kartu horizontal yang ketika digeser dengan jari di layar ponsel otomatis berhenti tepat di tengah atau di tepi kartu (carousel / slider) mengharuskan kita memuat pustaka JavaScript berat yang menyadap event touchmove dan scroll.
Kini, CSS Scroll Snap (status Baseline Widely Available) menangani seluruh fisika kelembaman dan penguncian posisi gulir tersebut langsung di tingkat compositor thread peramban dengan sangat mulus!
Hanya butuh dua langkah:
- **Pada Wadah Pembungkus yang Bisa Digulir (Scroll Container): Pasang
overflow-x: autodanscroll-snap-type: x mandatory** (atauy proximityuntuk arah vertikal). - Pada Setiap Anak Kartu di Dalamnya: Pasang
scroll-snap-align: start(ataucenter/end).
/* 1. Wadah Galeri Horizontal */
.rel-kartu {
display: grid;
grid-auto-flow: column;
/* Setiap kartu memiliki lebar 85% layar di ponsel, atau maksimal 320px di layar lebar */
grid-auto-columns: min(85%, 320px);
gap: 1rem;
overflow-x: auto;
padding-block-end: 1rem;
/* Mengaktifkan penguncian gulir horizontal secara wajib (mandatory) */
scroll-snap-type: x mandatory;
/* Memberi jarak aman di kiri agar kartu pertama tidak terlalu mepet ke tepi layar */
scroll-padding-inline-start: 1rem;
}
/* 2. Setiap Item Kartu di Dalam Rel */
.rel-kartu > article {
scroll-snap-align: start;
/* Mencegah pengguna melompati banyak kartu sekaligus saat menggeser terlalu cepat di ponsel */
scroll-snap-stop: always;
}
Perbedaan mandatory vs proximity pada scroll-snap-type
mandatory: Peramban wajib selalu mengunci posisi berhenti tepat pada salah satu titik kartu begitu pengguna selesai menggulir. Sangat cocok untuk galeri foto atau deretan kartu horizontal (overflow-x: auto).proximity: Peramban hanya mengunci posisi jika guliran pengguna kebetulan berhenti di dekat titik snap (jika berhenti di tengah-tengah paragraf panjang, pengguna tidak dipaksa melompat). Jauh lebih aman untuk pengguliran halaman utama secara vertikal (y)!
2. Mengatur Jarak Tautan Jangkar (scroll-margin) dan Mengunci Bocoran Gulir (overscroll-behavior)
A. scroll-margin-top (atau scroll-margin-block-start)
Saat pengguna mengeklik tautan daftar isi <a href="#bab-3">, peramban menggulir #bab-3 hingga menempel persis di bibir atas layar (0px). Jika situs Anda memiliki <header> yang position: sticky setinggi 4rem, maka judul #bab-3 akan tertutup oleh header tersebut!
Solusinya: berikan scroll-margin-block-start: 5rem; pada semua elemen yang memiliki atribut id:
[id] {
scroll-margin-block-start: 5rem;
}
B. overscroll-behavior: contain
Pernahkah Anda menggulir daftar panjang di dalam sebuah kotak <dialog> atau panel menu samping (sidebar), lalu ketika gulirannya sudah mencapai ujung paling bawah daftar, tiba-tiba **halaman utama di belakangnya ikut bergerak tergulir (scroll chaining)**?
Satu baris properti overscroll-behavior: contain (nilai contain didukung semua peramban utama: Chrome 63, Firefox 59, Safari 16; halaman MDN menandai properti ini Limited availability hanya karena nilai chain yang baru) menghentikan rantai guliran tersebut agar tetap terkurung di dalam panel/dialog tanpa membocorkannya ke halaman belakang!
.panel-notifikasi,
dialog {
overflow-y: auto;
overscroll-behavior: contain;
}
3. Animasi yang Dikendalikan oleh Posisi Gulir (Scroll-Driven Animations)
Di masa lalu, membuat **Bilah Kemajuan Baca (Reading Progress Bar)** di bagian paling atas artikel yang memanjang dari 0% ke 100% seiring pengguna menggulir halaman ke bawah mengharuskan kita menjalankan window.addEventListener("scroll", ...) di utas utama JavaScript pada setiap piksel guliran.
CSS modern memperkenalkan Scroll-Driven Animations melalui properti animation-timeline (didukung di Chrome/Edge sejak versi 115 dan Safari 26; di Firefox baru tersedia mulai versi 159, yang saat ini masih beta, sehingga gunakan secara progresif dengan @supports):
scroll(): Mengikat kemajuan@keyframes(0%hingga100%) langsung ke posisi gulir sebuah scroll container (seperti halamanroot), bukan ke waktu detik!view(): Mengikat kemajuan@keyframeske posisi sebuah elemen saat elemen tersebut mulai masuk hingga keluar dari jendela pandang (viewport, miripIntersectionObservertetapi untuk animasi CSS murni!).
@keyframes rentangkan-progres {
from { scale: 0 1; }
to { scale: 1 1; }
}
/* Bilah kemajuan baca artikel di bagian paling atas layar — 0 baris JavaScript! */
@supports (animation-timeline: scroll()) {
.bilah-kemajuan-baca {
position: fixed;
inset-block-start: 0;
inset-inline: 0;
block-size: 4px;
background-color: #2563eb;
transform-origin: 0% 50%;
animation: rentangkan-progres linear;
/* Mengikat timeline animasi ke guliran vertikal dokumen root! */
animation-timeline: scroll(root block);
}
}
Latihan Praktik: Membangun Rel Katalog Geser dan Bilah Kemajuan Baca
Buatlah berkas scroll-modern.html dan scroll.css:
- Buat komponen
.rel-kataloghorizontal yang berisi 6 kartu kelas menggunakanscroll-snap-type: x mandatorydanscroll-snap-align: start. - Pasang
scroll-margin-block-start: 5rempada setiap<section id="...">di artikel. - Tambahkan
.bilah-kemajuan-bacadengan@supports (animation-timeline: scroll())dan pastikan tetap menghormati@media (prefers-reduced-motion: reduce).