Sebagian besar waktu, elemen muncul di halaman persis di tempat yang ditentukan oleh alur dokumen normal — satu demi satu, dari atas ke bawah, kiri ke kanan. Perilaku bawaan ini sebenarnya bagus, dan kamu sebaiknya memanfaatkannya. Tapi sesekali kamu butuh keluar dari alur itu: menempelkan banner di puncak layar, menaruh badge kecil di sudut sebuah kartu, atau membuat judul sidebar tetap terlihat saat halaman digulir. Nah, untuk itulah property position ada.
Banyak orang tersandung di topik positioning karena nilai-nilainya terdengar mirip padahal perilakunya jauh berbeda, dan karena semuanya bergantung pada satu ide — konteks positioning — yang jarang dijelaskan dengan gamblang. Begitu bagian ini nyantol, semuanya jadi terasa masuk akal. Yuk kita bahas kelima nilainya satu per satu, beserta aturan yang mengikat mereka.
Property position dan lima nilainya
Setiap elemen punya position, dan nilainya salah satu dari lima ini:
.element {
position: static; /* bawaan */
/* position: relative; */
/* position: absolute; */
/* position: fixed; */
/* position: sticky; */
}
Nilai yang kamu pilih mengubah dua hal sekaligus: apakah elemen tetap berada di alur normal, dan apa efek dari property offset top, right, bottom, serta left. Keempat offset itu ibarat setir kemudi dalam positioning — tapi mereka baru berfungsi setelah kamu beranjak dari static.
top/right/bottom/left tidak berefek pada elemen static
Ini kebingungan nomor satu para pemula: kamu memasang top: 20px ke sebuah elemen, tidak terjadi apa-apa, lalu kamu mengira CSS-nya rusak. Padahal bukan. Property offset itu memang diabaikan selama position: static (nilai bawaan). Mereka baru aktif begitu kamu ganti ke relative, absolute, fixed, atau sticky. Jadi kalau offset-mu tidak bekerja, cek dulu nilai position-nya.
static — alur bawaan
position: static adalah kondisi awal setiap elemen. Elemen duduk di mana pun alur dokumen normal menempatkannya, dan top/left/dan kawan-kawan diabaikan. Kamu jarang menulis position: static sendiri — gunanya lebih ke mengembalikan elemen ke kondisi normal setelah ia mewarisi atau diberi nilai lain.
.box {
position: static; /* duduk di alur normal; offset diabaikan */
}
Cuma itu saja. Static adalah titik tenang yang jadi pijakan semua nilai lainnya.
relative — geser dari posisi awalnya
position: relative membuat elemen tetap berada di alur normal, tapi memungkinkanmu menggesernya dari posisi aslinya. Ruang yang semula ia tempati tetap dipesan, jadi elemen tetangga tidak ikut bergeser mengisi celah — elemennya cuma bergeser secara visual.
.box {
position: relative;
top: 10px; /* turun 10px dari posisi semula */
left: 20px; /* geser kanan 20px dari posisi semula */
}
Baca offset itu baik-baik: top: 10px mendorong elemen ke bawah (menjauh dari atas), dan left: 20px mendorongnya ke kanan (menjauh dari kiri). Elemen bergeser relatif terhadap dirinya sendiri, meninggalkan celah seukuran bentuknya yang lama.
Kalau berdiri sendiri, relative cuma sedikit berguna untuk menggeser-geser elemen. Kekuatan aslinya justru di hal lain: ia menciptakan konteks positioning bagi anak-anak yang ber-position absolute. Ingat-ingat hal ini — inilah kunci ke bagian berikutnya.
absolute — dicabut dari alur, ditempelkan ke leluhur
position: absolute adalah yang paling penting. Ia mencabut elemen dari alur normal sepenuhnya (tetangganya merapat seolah elemen itu tak pernah ada) lalu memosisikannya pakai offset — tapi relatif terhadap leluhur terdekat yang ber-position, bukan terhadap dirinya sendiri.
“Leluhur yang ber-position” maksudnya induk terdekat (atau kakek, dan seterusnya) yang punya position selain static — biasanya relative. Kalau tidak ada leluhur semacam itu, elemen akan diposisikan terhadap halaman itu sendiri (initial containing block).
.card {
position: relative; /* jadi konteks positioning */
}
.badge {
position: absolute;
top: 8px;
right: 8px; /* tempel di sudut kanan-atas .card */
}
<div class="card">
<span class="badge">Baru</span>
<p>Isi kartu ada di sini.</p>
</div>
Karena .card ber-relative, si .badge yang absolute mengukur top dan right-nya dari tepi .card — sehingga mendarat rapi di sudut kanan-atas. Pasangan induk relative + anak absolute ini termasuk pola paling berguna di seluruh CSS: badge, menu dropdown, tooltip, tombol close, overlay gambar. Pelajari sekali, dan kamu bakal memakainya terus-menerus.
Aturan emas: induk relative, anak absolute
Kalau kamu ingin menaruh sesuatu secara presisi di dalam sebuah kotak, beri kotak itu position: relative dan elemen di dalamnya position: absolute. Si induk relative menjadi jangkar bagi anak absolute. Lupa memasang relative di induk, dan “badge sudut”-mu malah terbang ke sudut seluruh halaman — itulah bug klasiknya, dan sekarang kamu tahu cara memperbaikinya.
Kalau kamu memasang keempat offset sekaligus pada elemen absolute, ia akan meregang memenuhi konteks positioning-nya:
.overlay {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0; /* menutupi seluruh leluhur yang ber-position */
}
Itu cara rapi untuk membentangkan overlay setengah transparan di atas sebuah kartu atau gambar hero.
fixed — dipaku ke viewport
position: fixed juga mencabut elemen dari alur, tapi ia memaku elemen ke viewport — jendela browser yang terlihat — alih-alih ke leluhur mana pun. Akibatnya, elemen tetap diam di tempat meski halaman digulir.
.back-to-top {
position: fixed;
bottom: 24px;
right: 24px; /* selalu 24px dari sudut kanan-bawah layar */
}
Begitulah persis cara membuat tombol “kembali ke atas” yang mengambang, banner cookie, atau header yang tak pernah ikut bergeser. Karena diukur terhadap viewport, menggulir halaman tidak berpengaruh apa-apa — elemennya seperti dilem di titik itu pada layar.
Fixed di mobile, dan jebakan transform
Ada dua hal yang perlu diwaspadai dengan fixed. Pertama, di mobile, bilah fixed bisa menumpuk konten atau berebut tempat dengan keyboard layar, jadi uji di perangkat asli dan sisakan ruang dengan padding. Kedua — dan ini mengejutkan semua orang — kalau ada leluhur yang punya transform, filter, atau perspective, elemen fixed-mu malah jadi fixed terhadap leluhur itu, bukan viewport. Kalau elemen fixed tiba-tiba ikut tergulir, cari transform di salah satu induknya.
sticky — relative sampai akhirnya nempel
position: sticky adalah hibrida yang cerdik, dan yang paling baru di antara semuanya. Elemen berperilaku seperti relative (tetap di alur) sampai ia tergulir ke ambang batas yang kamu tentukan, lalu ia “menempel” dan berperilaku seperti fixed — tapi hanya selama container-nya masih ada di layar.
.section-heading {
position: sticky;
top: 0; /* menempel begitu mencapai puncak viewport */
}
Saat kamu menggulir, judulnya ikut tergulir seperti biasa sampai menyentuh tepi atas, lalu ia membeku di sana sementara sisa bagian itu lewat di bawahnya. Begitu bagian tersebut habis, judulnya ikut tergulir pergi bersamanya. Beginilah cara header kategori yang “lengket” pada daftar panjang, header tabel, dan navigasi antar-bagian bekerja.
Dua hal wajib agar sticky berfungsi: kamu harus menentukan ambang batas (misalnya top: 0), dan elemen butuh leluhur yang bisa digulir dengan ruang yang cukup. Kegagalan diam-diam yang umum adalah leluhur dengan overflow: hidden, yang tanpa suara mematikan sifat lengketnya.
Perbandingan singkat
Ini seluruh keluarganya disandingkan, cara tercepat agar tidak tertukar:
| Nilai | Di alur normal? | Offset diukur dari | Ikut tergulir? |
|---|---|---|---|
static |
Ya | (offset diabaikan) | Ya |
relative |
Ya (ruang tetap) | Posisi aslinya sendiri | Ya |
absolute |
Tidak | Leluhur terdekat yang ber-position | Ya (bersama leluhur itu) |
fixed |
Tidak | Viewport | Tidak (diam di tempat) |
sticky |
Ya, lalu nempel | Container penggulir terdekat | Sampai ambang, lalu nempel |
Kalau kamu cuma mau mengingat satu baris konteks: absolute diukur terhadap leluhur, fixed terhadap viewport. Satu perbedaan itu saja sudah menjelaskan sebagian besar pusing-pusing “kenapa elemenku salah tempat”.
Contoh praktis: kartu dengan badge di sudut
Sekarang kita bangun pola positioning yang paling sering benar-benar kamu pakai — kartu produk dengan badge “Diskon” yang dipaku di sudutnya:
.product {
position: relative; /* si jangkar */
width: 240px;
padding: 16px;
border: 1px solid #ddd;
border-radius: 8px;
}
.product .badge {
position: absolute;
top: 12px;
right: 12px;
background: #00b8e6;
color: #fff;
padding: 4px 10px;
border-radius: 999px;
font-size: 12px;
}
<div class="product">
<span class="badge">Diskon</span>
<h3>Paket ACY Partner Indonesia</h3>
<p>Semua yang kamu butuhkan untuk memulai.</p>
</div>
Kartunya relative supaya menjadi kerangka acuan; badge-nya absolute dan duduk 12px dari sudut kanan-atas kartu itu, sebesar apa pun kartunya tumbuh. Ubah ukuran, tambah teks, ganti tata letak — badge-nya tetap menempel di sudutnya. Ketangguhan seperti inilah inti dari pasangan relative/absolute.
Praktik terbaik dan kesalahan umum
Beberapa kebiasaan ini akan menghematmu banyak waktu debugging:
- Andalkan alur normal dan Flexbox/Grid lebih dulu. Positioning itu untuk menumpangkan dan memaku, bukan untuk tata letak umum. Kalau kamu memakai
absoluteuntuk membangun seluruh struktur halaman, mundur sejenak — Flexbox dan Grid adalah alat yang tepat, dan jauh lebih kokoh. - Selalu pasang
position: relativedi induk sebelum menaruh anakabsolute. Inilah bug positioning yang paling sering terjadi. - Jangan lupa offset pada sticky.
position: stickytanpa nilaitop(ataubottom/left/right) sama sekali tidak melakukan apa-apa. - Ingat bahwa
absolutedanfixedmencabut elemen dari alur. Konten di sekitarnya merapat seolah elemennya menghilang, yang bisa menyebabkan tumpang tindih. Sisakan ruang dengan padding atau margin pada tetangganya bila perlu. - Perhatikan urutan tumpukan. Saat elemen-elemen ber-position saling menumpuk, siapa yang menang diatur oleh
z-index, yang hanya berlaku untuk elemen ber-position — itu topik tersendiri, dan langkah lanjutan yang wajar dari sini.
Positioning juga mengandaikan kamu sudah paham bagaimana ukuran sebuah elemen tersusun dari konten, padding, border, dan margin. Kalau bagian itu masih terasa goyah, ada baiknya menengok lagi box model CSS sebelum melangkah lebih jauh — setiap offset yang kamu pasang berinteraksi dengannya.
Penutup
Property position adalah cara kamu mengeluarkan elemen dari alur biasa dan menempatkannya dengan sengaja. Ini gambaran utuhnya dalam beberapa baris:
staticadalah bawaan — alur normal, offset diabaikan.relativemenggeser elemen dari posisinya sendiri sekaligus menciptakan konteks positioning untuk anak absolute.absolutemencabut elemen dari alur dan memosisikannya terhadap leluhur terdekat yang ber-position (pola klasik induk relative, anak absolute).fixedmemaku elemen ke viewport, jadi ia mengabaikan pengguliran.stickyberperilaku sepertirelativesampai ambang pengguliran, lalu menempel sepertifixeddi dalam container-nya.
Akrablah dengan ide konteks positioning — pertanyaan “ini diukur terhadap apa?” — dan positioning CSS bakal jadi salah satu alat paling bisa ditebak sekaligus berguna di gudang senjatamu. Berikutnya, saat elemen-elemen ber-position mulai saling menumpuk, kamu bakal ingin mengatur mana yang tampil di atas. Itulah z-index, dan ke sanalah kita melangkah selanjutnya.