Positioning Lanjut: Fixed, Sticky, dan z-index
Navbar yang nempel saat scroll, elemen fixed, dan cara kerja z-index plus stacking context yang sering bikin pusing.
position: fixed
Elemen fixed diposisikan relatif terhadap viewport (jendela browser) dan tidak ikut scroll.
.tombol-chat {
position: fixed;
bottom: 24px;
right: 24px;
}Tombol chat melayang di kanan bawah dan tetap di sana walau halaman di-scroll. Cocok buat tombol "kembali ke atas", chat widget, atau banner cookie.
position: sticky
Sticky adalah gabungan relative + fixed: elemen berperilaku normal sampai mencapai batas yang ditentukan, lalu "menempel".
.navbar {
position: sticky;
top: 0;
}Navbar akan ikut scroll ke atas, tapi begitu menyentuh puncak viewport dia menempel di sana. Syarat penting: induknya harus lebih tinggi dari elemen sticky (kalau induknya cuma setinggi elemennya, tidak ada ruang buat menempel) dan tidak boleh ada overflow: hidden pada leluhur yang memotongnya.
Sticky juga keren buat header tabel atau judul section yang menempel saat daftar panjang di-scroll.
z-index: siapa di depan?
Ketika elemen bertumpuk, z-index menentukan urutan tampil. Angka lebih besar = lebih depan.
.modal {
position: fixed;
z-index: 100;
}
.dropdown {
position: absolute;
z-index: 10;
}Syarat: z-index hanya berlaku pada elemen yang position-nya bukan static (atau elemen flex/grid item).
Jebakan: stacking context
Ini yang bikin pusing: z-index: 9999 kadang tetap kalah dari z-index: 1. Penyebabnya adalah stacking context: grup tumpukan yang terisolasi.
Sebuah elemen membentuk stacking context baru kalau punya kombinasi tertentu, misalnya position: relative + z-index (selain auto), opacity kurang dari 1, transform, atau filter. Anak di dalam stacking context tidak bisa keluar mengalahkan elemen di luar grupnya, seberapa besar pun z-index-nya.
<div class="kartu"> <!-- z-index: 1, membentuk stacking context -->
<div class="tooltip" style="z-index: 9999"></div> <!-- tetap di bawah modal -->
</div>
<div class="modal" style="z-index: 2"></div> <!-- menang karena 2 > 1 di level yang sama -->Solusinya: naikkan z-index si induk (.kartu), bukan anaknya. Atau keluarkan elemen yang harus paling depan (seperti modal) ke level root body.
Catatan teknis: hindari perang angka z-index (999, 9999, 99999). Pakai skala yang masuk akal dan dokumentasikan: misal dropdown 10, navbar 50, modal 100, toast 200. Lebih gampang dirawat dan tidak ada yang "kalah misterius".
Contoh: navbar sticky + modal
.navbar {
position: sticky;
top: 0;
z-index: 50;
background: white;
}
.modal-backdrop {
position: fixed;
inset: 0; /* shorthand top/right/bottom/left: 0 */
z-index: 100;
background: rgba(0, 0, 0, 0.5);
}inset: 0 adalah shorthand modern buat keempat sisi sekaligus. Modal (100) tampil di atas navbar (50), sesuai harapan.
Rangkuman
Fixed menempel ke viewport, sticky menempel setelah batas scroll tercapai. z-index mengatur tumpukan tapi hanya dalam stacking context yang sama. Kalau z-index besarmu "tidak mempan", hampir pasti masalahnya stacking context di level induk.