Sidebar sticky dibuat dengan memberi position: sticky pada elemen sidebar dan menetapkan nilai top, misalnya top: 24px. Elemen mengikuti scroll sampai jaraknya menyentuh batas atas, lalu berhenti di sana. Tidak perlu event listener atau library tambahan.
Masalahnya, properti ini cukup sering gagal tanpa pesan error. Sidebar tetap diam karena induknya punya overflow: hidden, atau karena tidak ada ruang scroll di dalam induknya. Bagian berikut membahas penyebab itu satu per satu.
Struktur HTML dan CSS dasar
Mulai dari dua kolom: konten utama dan sidebar. Keduanya dibungkus satu container yang menjadi acuan perhitungan sticky.
<div class="layout">
<main class="content">
<p>Isi artikel yang panjang...</p>
</main>
<aside class="sidebar">
<div class="sidebar-inner">
<h2>Daftar Isi</h2>
<ul>
<li><a href="#satu">Bagian satu</a></li>
<li><a href="#dua">Bagian dua</a></li>
</ul>
</div>
</aside>
</div>
Container memakai flexbox dua kolom. Sidebar diberi align-self: start supaya tingginya tidak dipaksa setinggi konten utama, karena elemen yang tingginya sama dengan induk tidak punya ruang untuk bergerak.
.layout {
display: flex;
gap: 2rem;
align-items: flex-start;
}
.content {
flex: 1 1 auto;
min-width: 0;
}
.sidebar {
flex: 0 0 280px;
align-self: start;
position: sticky;
top: 24px;
}
Nilai top: 24px berarti sidebar berhenti 24 piksel dari tepi atas viewport. Angka ini biasanya disesuaikan dengan tinggi header tetap. Kalau kamu memakai header yang menempel, lihat cara mengatur sticky header dengan CSS dan sedikit JavaScript agar jarak keduanya tidak bertabrakan.
Kenapa sticky tidak berfungsi
Ada tiga penyebab yang paling sering muncul saat position: sticky tidak bereaksi.
- Induk punya overflow tersembunyi.
overflow: hidden,auto, atauscrollpada elemen induk membuat sticky menempel ke area scroll induk itu, bukan ke viewport. Banyak utility class menambahkanoverflow: hiddenuntuk membersihkan float tanpa disadari. - Induk tidak lebih tinggi dari sidebar. Sticky hanya bergerak selama ada sisa ruang di dalam induk. Kalau sidebar setinggi induk, ia langsung berhenti di posisi awal.
- Tidak ada nilai top, bottom, left, atau right. Tanpa salah satu nilai offset, sticky berperilaku seperti
relativedan tidak menempel ke mana pun.
Cara mengeceknya cepat: buka DevTools, pilih elemen sidebar, lalu telusuri panel Computed untuk melihat properti overflow di setiap leluhur. Satu leluhur dengan nilai selain visible sudah cukup merusak perilakunya.
Membatasi tinggi sidebar agar tidak terpotong
Sidebar yang isinya panjang bisa melebihi tinggi layar. Kalau dibiarkan, bagian bawahnya tidak akan pernah terlihat karena elemen berhenti menempel sementara isinya tetap memanjang ke bawah.
Solusinya memberi batas tinggi pada elemen dalam sidebar, lalu membuat isinya bisa digulir sendiri.
.sidebar-inner {
max-height: calc(100vh - 48px);
overflow-y: auto;
overscroll-behavior: contain;
}
Angka 48px berasal dari dua kali jarak 24px di atas dan bawah. overscroll-behavior: contain mencegah scroll sidebar ikut menggeser halaman saat sudah mentok, yang sering terasa mengganggu di layar sentuh.
Perhatikan bahwa overflow-y: auto di sini dipasang pada anak sidebar, bukan pada induknya. Ini penting. Kalau dipasang pada induk, sticky kembali mati.
Menonaktifkan sticky di layar kecil
Di ponsel, kolom samping biasanya turun ke bawah konten. Sticky yang tetap aktif justru membuat sidebar menempel di layar dan menutupi bacaan. Matikan lewat media query.
@media (max-width: 768px) {
.layout {
flex-direction: column;
}
.sidebar {
flex: 1 1 auto;
width: 100%;
position: static;
}
.sidebar-inner {
max-height: none;
overflow-y: visible;
}
}
Untuk tata letak dua dimensi yang lebih kompleks, misalnya sidebar yang harus sejajar dengan grid kartu di area konten, pendekatan grid lebih tepat dibanding flexbox. Perbandingan keduanya dibahas di CSS Grid vs Flexbox untuk layout dua dimensi.
Menambahkan efek visual saat menempel
CSS tidak menyediakan selector khusus untuk keadaan “sedang sticky”. Kalau kamu ingin sidebar berubah bayangan ketika menempel, gunakan IntersectionObserver untuk memantau elemen penanda di atas sidebar.
const sentinel = document.querySelector('.sidebar-sentinel');
const sidebar = document.querySelector('.sidebar');
const observer = new IntersectionObserver(
([entry]) => {
sidebar.classList.toggle('is-stuck', !entry.isIntersecting);
},
{ threshold: 0 }
);
observer.observe(sentinel);
Elemen .sidebar-sentinel adalah div kosong setinggi beberapa piksel yang diletakkan tepat di atas sidebar. Ketika penanda itu keluar dari viewport, kelas is-stuck ditambahkan dan kamu bisa mengatur bayangan atau border lewat CSS.
Pola observer yang sama juga dipakai pada header sticky, jadi kamu bisa memakai satu pendekatan untuk keduanya.
Hal yang perlu diperiksa sebelum deploy
- Pastikan tidak ada leluhur dengan
overflowselainvisible. - Beri
align-self: startpada sidebar agar tingginya tidak mengikuti konten utama. - Uji dengan konten pendek. Kalau artikelnya hanya dua paragraf, sticky memang tidak akan terlihat bergerak.
- Cek di zoom 150% dan 200%. Sidebar dengan lebar tetap bisa memakan ruang berlebihan.
- Matikan sticky di breakpoint ponsel lewat media query.
Kalau situsmu memuat aset dari domain lain atau memakai subdomain terpisah, masalah tampilan bisa berasal dari resolusi DNS yang lambat. Perbandingan penyedia DNS publik seperti Cloudflare, Google, dan Quad9 bisa jadi bahan pertimbangan saat memilih resolver.
Ringkasan
Sidebar sticky cukup dibuat dengan position: sticky dan satu nilai top. Kegagalan biasanya datang dari induk ber-overflow, tinggi induk yang tidak mencukupi, atau sidebar yang lupa diberi align-self: start. Batasi tinggi isi sidebar dengan calc(100vh - ...), matikan di layar kecil, dan tambahkan IntersectionObserver hanya jika perlu perubahan gaya saat menempel.
Pertanyaan yang Sering Diajukan
Apakah position: sticky butuh JavaScript?
Tidak. Sticky sepenuhnya berjalan di CSS. JavaScript hanya diperlukan kalau kamu ingin mengubah tampilan berdasarkan keadaan menempel, misalnya menambah bayangan atau mengubah warna latar.
Kenapa sidebar sticky saya diam saja?
Periksa tiga hal: apakah ada leluhur dengan overflow: hidden atau auto, apakah induknya lebih tinggi dari sidebar, dan apakah kamu sudah menetapkan nilai top. Ketiganya wajib terpenuhi agar sticky bekerja.
Bisakah sticky dipakai di dalam container yang bisa di-scroll sendiri?
Bisa, tetapi acuan menempelnya adalah container tersebut, bukan viewport. Elemen akan berhenti di dalam area scroll container itu. Pastikan container punya tinggi terbatas dan isi yang cukup panjang, kalau tidak sticky tidak akan terlihat efeknya.