Position CSS: Perbedaan Static, Relative, Absolute, Fixed, dan Sticky
Position CSS menentukan cara elemen ditempatkan. Pahami perbedaan absolute dan relative, cara kerja position sticky, fixed, dan dasar CSS positioning.
Pembuat Hyper Sheets & BelajarWeb.dev
Properti position di CSS menentukan bagaimana sebuah elemen ditempatkan di halaman, dan apakah properti top, right, bottom, dan left berlaku atau tidak. Secara default setiap elemen bernilai position: static, yang artinya ia mengikuti aliran normal dokumen dan mengabaikan keempat properti offset itu. Begitu kamu mengubah nilainya menjadi relative, absolute, fixed, atau sticky, elemen “terbuka kuncinya”: ia mulai mendengarkan top/left dan bisa kamu geser ke posisi yang kamu mau.
Kelima nilai itulah yang jadi sumber kebingungan terbesar pemula CSS. Kenapa elemen dengan top: 20px kadang bergerak, kadang tidak? Kenapa position: absolute malah lari ke pojok layar? Kenapa sticky yang katanya bisa “menempel” justru diam saja? Artikel ini membedah kelima nilai satu per satu dengan contoh kode, membandingkan absolute vs relative secara khusus (bagian yang paling sering ditanyakan), dan menutupnya dengan kesalahan umum plus FAQ. Ada juga playground interaktif supaya kamu bisa langsung melihat perbedaannya.
Position CSS Adalah… (Pengertian dan Cara Kerjanya)
Properti position mengontrol metode penempatan elemen: apakah ia ikut mengalir bersama elemen lain, atau dikeluarkan dari aliran dan diposisikan secara manual lewat top/right/bottom/left. Nilai position juga menentukan “titik acuan”, relatif terhadap apa elemen itu digeser: posisi normalnya sendiri, elemen leluhur (ancestor), atau viewport (jendela browser).
Ada lima nilai yang perlu kamu kuasai:
.contoh {
position: static; /* default, ikut aliran, offset diabaikan */
position: relative; /* digeser dari posisi normal, ruang tetap dipesan */
position: absolute; /* keluar aliran, acuan ke ancestor non-static */
position: fixed; /* keluar aliran, acuan ke viewport, diam saat scroll */
position: sticky; /* hybrid relative + fixed berdasarkan scroll */
}
Satu hal yang perlu kamu pegang sejak awal: top, right, bottom, dan left sama sekali tidak berpengaruh selama position masih static. Banyak pemula menulis top: 50px lalu bingung kenapa tidak terjadi apa-apa, jawabannya karena mereka lupa mengubah position lebih dulu. Offset itu ibarat pedal gas yang hanya berfungsi setelah mesinnya (position non-static) dinyalakan.
static, Nilai Default yang Mengikuti Aliran
position: static adalah nilai bawaan setiap elemen HTML: ia ditempatkan mengikuti aliran normal dokumen, satu demi satu sesuai urutan di markup, dan mengabaikan top/right/bottom/left sepenuhnya. Kamu jarang menulis position: static secara eksplisit, ia sudah aktif tanpa kamu minta. Nilai ini biasanya baru muncul saat kamu perlu mengembalikan elemen ke perilaku normal setelah sebelumnya diberi posisi lain.
.kotak {
position: static;
top: 50px; /* diabaikan, kotak tidak bergerak sedikit pun */
left: 50px; /* diabaikan juga */
}
Kotak di atas tetap diam di posisi normalnya meski diberi top dan left, karena static tidak mendengarkan offset. Inilah “titik nol” dari semua positioning, memahami bahwa default-nya adalah “diam dan patuh pada aliran” membuat empat nilai berikutnya jauh lebih mudah dicerna.
relative, Digeser, Tapi Ruangnya Tetap Dipesan
position: relative menggeser elemen dari posisi normalnya sesuai nilai top/left, TAPI ruang asli elemen tetap dipesan di aliran dokumen, seolah elemen itu masih ada di tempat semula. Ini poin kunci yang membedakannya dari absolute: menggeser elemen relative akan meninggalkan “celah kosong” di posisi aslinya, dan elemen lain tidak akan mengisi celah itu.
.kotak {
position: relative;
top: 20px; /* turun 20px dari posisi normal */
left: 30px; /* geser 30px ke kanan dari posisi normal */
}
Kotak di atas bergeser 20px ke bawah dan 30px ke kanan, tapi tempat aslinya tetap “dibooking”, elemen di bawahnya tidak naik mengisi celah. Karena itu relative terasa aman: kamu bisa menggeser sesuatu sedikit tanpa mengacaukan susunan elemen di sekitarnya.
Ada fungsi kedua relative yang justru lebih sering dipakai daripada menggeser: menjadikan elemen sebagai “titik acuan” (anchor) untuk anak ber-position: absolute. Sering kali kamu menulis position: relative tanpa top/left sama sekali, tujuannya bukan menggeser elemen itu, melainkan menyiapkannya sebagai kerangka acuan bagi anak absolute di dalamnya. Konsep ini akan langsung masuk akal setelah kita bahas absolute berikutnya.
absolute, Keluar dari Aliran, Menempel ke Ancestor
position: absolute mengeluarkan elemen sepenuhnya dari aliran dokumen dan memposisikannya relatif terhadap ancestor (elemen leluhur) ber-position non-static yang terdekat. Karena keluar dari aliran, elemen saudara di sekitarnya akan “menutup celah”, mereka bersikap seolah elemen absolute itu tidak ada. Dan karena acuannya adalah ancestor non-static terdekat, penempatannya sepenuhnya bergantung pada siapa parent-nya.
Perhatikan kata kunci “ancestor non-static terdekat”. Browser akan menaiki pohon DOM dari elemen absolute ke atas, mencari leluhur pertama yang punya position selain static (relative, absolute, fixed, atau sticky). Elemen pertama yang ditemukan itulah yang jadi acuan. Kalau tidak ada satu pun ancestor non-static, acuannya jatuh ke viewport / elemen <html>, dan di sinilah pemula sering kaget karena badge-nya tiba-tiba nyangkut di pojok halaman.
/* Parent JADI acuan karena diberi position: relative */
.kartu {
position: relative; /* kerangka acuan untuk anak absolute */
}
.badge {
position: absolute;
top: 8px;
right: 8px; /* 8px dari sudut kanan-atas .kartu */
}
Pada contoh di atas, .badge menempel 8px dari sudut kanan-atas .kartu, persis pola “badge notifikasi di pojok kartu” yang ada di mana-mana. Rahasianya cuma dua baris: parent diberi position: relative, anak diberi position: absolute plus offset. Kalau .kartu tidak diberi position: relative, .badge akan mencari ancestor non-static berikutnya ke atas, dan kalau tak ada, ia terbang ke pojok viewport.
Coba Sendiri: Playground Position
Teori jauh lebih cepat menempel kalau kamu bisa memainkannya. Pilih nilai position, lalu geser slider Atas dan Kiri untuk melihat ke mana kotak target bergerak, dan perhatikan bagaimana kotak saudara di sekitarnya bereaksi (menutup celah pada absolute, atau tetap memesan ruang pada relative).
Coba Sendiri
position playgroundDigeser dari posisi normalnya, tapi ruang aslinya (kotak putus-putus) tetap dipesan.
position: relative;
top: 24px;
left: 32px;Coba urutan ini: mulai dari static (offset diabaikan), lalu relative (kotak bergeser tapi ruang aslinya tetap dipesan, lihat kotak putus-putusnya), lalu absolute (kotak keluar dari aliran dan saudara di bawahnya naik menutup celah). Perbedaan relative vs absolute akan langsung terasa begitu kamu bolak-balik menekan dua tombol itu.
fixed, Menempel ke Viewport, Diam Saat Scroll
position: fixed mengeluarkan elemen dari aliran dan memposisikannya relatif terhadap viewport (jendela browser), sehingga elemen tetap diam di layar meski halaman di-scroll. Berbeda dari absolute yang acuannya bisa parent mana pun, acuan fixed selalu viewport (dengan sedikit pengecualian jika ada ancestor ber-transform). Inilah nilai yang kamu pakai untuk navbar yang selalu terlihat, tombol “kembali ke atas”, atau tombol chat mengambang.
/* Navbar yang selalu menempel di atas layar */
.navbar {
position: fixed;
top: 0;
left: 0;
right: 0; /* membentang selebar viewport */
}
/* Tombol "kembali ke atas" di pojok kanan-bawah */
.tombol-atas {
position: fixed;
bottom: 24px;
right: 24px;
}
Karena fixed keluar dari aliran, ia tidak lagi memakan ruang di dokumen, konten di belakangnya bisa tersembunyi di baliknya. Untuk navbar fixed setinggi 64px, biasakan memberi padding-top atau margin-top yang setara pada konten di bawahnya supaya baris pertama tidak tertutup. Kalau kamu masih ragu soal ruang di dalam vs di luar elemen, artikel padding adalah membahas dasar itu dengan tuntas.
sticky, Hybrid antara relative dan fixed
position: sticky adalah gabungan relative dan fixed: elemen berperilaku seperti relative (ikut mengalir) sampai posisi scroll mencapai ambang yang kamu tentukan lewat top/bottom, lalu “menempel” seperti fixed selama parent-nya masih terlihat di layar. Ini nilai favorit untuk header tabel yang menempel saat di-scroll, atau judul section yang mengikuti sampai section berikutnya mendorongnya keluar.
/* Header section yang menempel 0px dari atas saat di-scroll */
.judul-sticky {
position: sticky;
top: 0; /* WAJIB, tanpa ambang ini, sticky tidak menempel */
}
Dua syarat mutlak agar sticky berfungsi. Pertama, kamu wajib memberi minimal satu ambang (top, bottom, left, atau right), tanpa top: 0 misalnya, browser tidak tahu kapan harus mulai menempel, dan elemen hanya berperilaku seperti relative biasa. Kedua, parent elemen harus punya ruang scroll dan tidak boleh memiliki overflow: hidden/auto/scroll yang memotong; elemen sticky hanya menempel selama kotak parent-nya masih ada di viewport. Dua syarat inilah biang kerok nomor satu keluhan “position sticky tidak berfungsi”.
Perbedaan absolute vs relative (Bagian yang Paling Sering Ditanya)
Perbedaan intinya: relative tetap berada di aliran dokumen dan hanya digeser dari posisi normalnya (ruang aslinya tetap dipesan), sedangkan absolute dikeluarkan sepenuhnya dari aliran dan diposisikan relatif terhadap ancestor non-static (ruang aslinya hilang, diisi elemen lain). Keduanya sama-sama mengaktifkan top/left, tapi titik acuan dan dampaknya ke elemen sekitar bertolak belakang.
| Aspek | relative |
absolute |
|---|---|---|
| Aliran dokumen | Tetap di aliran | Dikeluarkan dari aliran |
| Ruang asli elemen | Tetap dipesan (menyisakan celah) | Hilang, saudara mengisinya |
| Acuan offset | Posisi normal elemen itu sendiri | Ancestor non-static terdekat (atau viewport) |
| Efek ke elemen lain | Tidak mengubah posisi elemen lain | Saudara “menutup” ruang bekasnya |
| Pemakaian khas | Geser tipis + jadi anchor anak absolute | Badge, dropdown, overlay, tooltip |
Cara paling gampang mengingatnya: relative bergeser “dari dirinya sendiri”, absolute menempel “ke orang tuanya”. Dan keduanya sering dipakai berpasangan, parent relative sebagai kerangka acuan, anak absolute yang ditempel presisi di dalamnya. Pola inilah yang jadi fondasi hampir semua komponen bertumpuk di web.
Hubungan Position dengan z-index
Properti z-index, yang mengatur elemen mana menumpuk di atas elemen lain, hanya berlaku pada elemen dengan position non-static. Selama elemen masih position: static, menulis z-index: 999 tidak akan berpengaruh sama sekali. Begitu kamu mengubahnya ke relative, absolute, fixed, atau sticky, elemen itu mengaktifkan konteks penumpukan (stacking context) dan z-index mulai bekerja.
.modal {
position: fixed; /* mengaktifkan z-index */
z-index: 100; /* kini berfungsi, modal di atas konten lain */
}
Inilah kenapa saat membuat modal, dropdown, atau overlay yang harus tampil di atas elemen lain, kamu hampir selalu memasangkan position non-static dengan z-index. Kalau z-index-mu “tidak mempan”, cek dulu apakah elemennya sudah punya position non-static. Aturan penumpukan ini punya banyak detail lain, urutan sumber, nilai negatif, stacking context bersarang, yang kami bedah tuntas di z-index CSS.
Kesalahan Umum Saat Menggunakan Position
Mayoritas masalah positioning berasal dari tiga sumber: lupa memberi parent position: relative untuk anak absolute, syarat sticky yang tidak terpenuhi, dan elemen fixed yang menutupi konten. Berikut daftar lengkapnya beserta cara memperbaikinya.
1. Absolute Kabur ke Pojok karena Parent-nya static
Ini kesalahan nomor satu. Kamu ingin badge menempel di pojok kartu, tapi ia malah muncul di pojok layar. Penyebabnya: parent kartu masih position: static (default), jadi anak absolute menaiki DOM sampai ke viewport. Solusinya satu baris, beri parent position: relative:
/* Salah: .kartu static, .badge kabur ke pojok viewport */
.kartu { /* tidak ada position */ }
.badge { position: absolute; top: 0; right: 0; }
/* Benar: .kartu jadi acuan */
.kartu { position: relative; }
.badge { position: absolute; top: 0; right: 0; }
2. Sticky Tidak Menempel
Dua penyebab tersering: (a) kamu lupa memberi ambang seperti top: 0, sehingga browser tidak tahu kapan harus menempel; atau (b) salah satu parent punya overflow: hidden/auto/scroll yang memotong konteks scroll, atau parent-nya tidak cukup tinggi untuk memberi ruang menempel. Cek keduanya sebelum menyerah:
.header {
position: sticky;
top: 0; /* tanpa baris ini, sticky diam seperti relative */
}
3. Fixed Menutupi Konten
Navbar fixed keluar dari aliran, jadi ia tidak lagi “mendorong” konten di bawahnya, akibatnya baris pertama halaman tersembunyi di balik navbar. Solusinya, beri konten ruang setara tinggi navbar:
.navbar { position: fixed; top: 0; height: 64px; }
body { padding-top: 64px; } /* sisakan ruang untuk navbar */
4. Menulis top/left di Elemen static
Menulis top: 20px pada elemen yang masih static sama sekali tidak berefek, offset baru aktif setelah position diubah ke non-static. Kalau elemenmu “tidak mau bergerak”, periksa dulu nilai position-nya.
Sebuah elemen diberi `position: absolute`. Ia akan diposisikan relatif terhadap...?
FAQ Seputar Position CSS
Position CSS adalah apa?
position adalah properti CSS yang menentukan bagaimana sebuah elemen ditempatkan di halaman dan apakah properti offset top/right/bottom/left berlaku. Ada lima nilai: static (default), relative, absolute, fixed, dan sticky. Masing-masing punya titik acuan dan perilaku aliran yang berbeda.
Apa perbedaan absolute dan relative?
relative tetap berada di aliran dokumen, elemen hanya digeser dari posisi normalnya dan ruang aslinya tetap dipesan. absolute dikeluarkan dari aliran dan diposisikan relatif terhadap ancestor non-static terdekat, sehingga ruang aslinya hilang dan diisi elemen lain. Keduanya sering dipakai berpasangan: parent relative sebagai acuan, anak absolute yang ditempel di dalamnya.
Kenapa position sticky tidak berfungsi?
Dua penyebab paling umum. Pertama, kamu belum memberi ambang seperti top: 0, tanpa itu sticky tidak tahu kapan harus menempel dan hanya berperilaku seperti relative. Kedua, ada parent dengan overflow: hidden/auto/scroll, atau parent-nya tidak cukup tinggi untuk menyediakan ruang scroll. Perbaiki keduanya sebelum menyimpulkan sticky-nya rusak.
Position absolute relatif ke apa?
Relatif ke ancestor (leluhur) terdekat yang punya position non-static, yaitu relative, absolute, fixed, atau sticky. Browser menaiki pohon DOM sampai menemukan yang pertama. Kalau tidak ada satu pun ancestor non-static, elemen absolute diposisikan relatif terhadap viewport / elemen <html>.
Position default CSS apa?
Default position setiap elemen HTML adalah static. Pada nilai ini elemen mengikuti aliran normal dokumen dan mengabaikan top/right/bottom/left. Kamu perlu mengubahnya ke nilai non-static agar offset dan z-index mulai berfungsi.
Kenapa top dan left saya tidak berpengaruh?
Kemungkinan besar elemennya masih position: static (default). Properti top, right, bottom, dan left hanya aktif pada elemen ber-position non-static. Ubah dulu position ke relative, absolute, fixed, atau sticky, baru offset-nya akan bekerja.
Langkah Selanjutnya
Sekarang kamu punya peta lengkapnya: static sebagai titik nol yang mengabaikan offset, relative yang menggeser tapi memesan ruang, absolute yang menempel ke ancestor non-static, fixed yang mengunci ke viewport, dan sticky yang hybrid berdasarkan scroll. Yang membedakan orang yang “tahu position” dan yang “jago layout” tinggal jam terbang, kebiasaan memilih nilai yang tepat tanpa perlu berpikir lagi.
Cara tercepat membentuk kebiasaan itu adalah latihan langsung. Mantapkan dasarnya lewat lesson interaktif position di Hyper Sheets, kamu ubah nilai position dan offset-nya, lalu melihat kotaknya bergerak saat itu juga. Setelah itu, langkah logis berikutnya adalah menguasai penumpukan lapisan yang tadi kita singgung: lanjut ke z-index CSS supaya modal, dropdown, dan overlay-mu selalu tampil di lapisan yang benar. Selamat ngoding!