Ilustrasi blok-blok tersusun dengan satu blok melayang dan pin lokasi

Episode lalu kamu belajar mengukur kotak. Sekarang kita belajar mengatur perilaku kotak: apakah dia turun ke baris baru atau tetap sebaris, apakah dia bisa diatur ukurannya, dan di mana tepatnya dia ditempatkan. Dua properti mengendalikan semua ini: display dan position. Ini episode keempat dari seri CSS Basic, dan materinya adalah prasyarat untuk memahami Flexbox dan Grid di dua episode berikutnya.

Dua persepsi salah yang perlu diluruskan. Pertama, banyak pemula mengira semua elemen "bisa diatur seenaknya" dan heran kenapa width tidak mempan di span atau kenapa dua div tidak mau sebaris. Padahal tiap elemen punya perilaku bawaan (display) yang menentukan apa yang bisa dan tidak bisa dilakukan padanya. Kedua, banyak yang memakai position: absolute untuk semua kebutuhan tata letak karena terlihat "bebas menaruh di mana saja", lalu layoutnya hancur total di layar berukuran beda. Position absolut adalah alat presisi untuk kasus khusus, bukan alat tata letak umum.

Display, Perilaku Dasar Elemen

Properti display menentukan bagaimana kotak elemen berpartisipasi dalam alur halaman. Empat nilai yang wajib dikuasai:

  • block: selalu mulai di baris baru dan mengambil lebar penuh yang tersedia. width, height, margin dan padding semua sisi berfungsi penuh. Contoh bawaan: div, p, h1, section.
  • inline: tetap sebaris dengan teks di sekitarnya, lebarnya selebar isinya. width dan height diabaikan, margin dan padding vertikal tidak mendorong baris. Contoh bawaan: span, a, strong.
  • inline-block: hibrida. Di luar berperilaku inline (tetap sebaris), di dalam berperilaku block (bisa diatur width, height, dan padding semua sisi). Favorit untuk tombol dan menu horizontal di era sebelum Flexbox.
  • none: elemen dihapus dari render. Tidak terlihat DAN tidak mengambil ruang sama sekali. Beda dengan visibility: hidden yang tidak terlihat tapi ruangnya tetap dipesan.

Analogi antrean: elemen block seperti orang yang selalu minta baris antrean sendiri. Elemen inline seperti orang yang berdesakan dalam satu baris. Inline-block seperti orang yang tetap dalam barisan tapi membawa koper besar yang ukurannya bisa diatur.

Berhenti dan tebak dulu! Kamu menulis CSS ini untuk sebuah <span>. Apa yang terjadi?

span {
  display: inline;
  width: 200px;
  height: 100px;
  margin-top: 50px;
}
Jawaban: width, height, dan margin-top semuanya diabaikan. Elemen inline tidak menerima pengaturan ukuran, dan margin vertikalnya tidak berpengaruh ke layout (padding vertikal digambar tapi menimpa baris tetangga tanpa mendorongnya). Kalau kamu butuh span yang bisa diatur ukurannya tapi tetap sebaris, ganti menjadi display: inline-block. Ini salah satu sumber frustrasi terbesar pemula, dan solusinya cuma satu kata.

Position, Lima Cara Menempatkan Elemen

Kalau display mengatur perilaku dalam alur, position mengatur di mana elemen ditempatkan. Ada lima nilai:

  • static: bawaan semua elemen. Mengikuti alur normal dokumen. Properti top, left, right, bottom tidak berpengaruh sama sekali.
  • relative: bergeser dari posisi normalnya sejauh top/left yang diberikan, TAPI ruang aslinya tetap dipesan. Elemen tetangga tidak bergeser mengisi kekosongannya.
  • absolute: dicabut dari alur normal (ruangnya tidak dipesan lagi) dan ditempatkan relatif terhadap leluhur terdekat yang posisinya bukan static. Kalau tidak ada, relatif terhadap halaman.
  • fixed: dicabut dari alur dan ditempatkan relatif terhadap layar (viewport). Tidak ikut bergeser saat halaman di-scroll. Cocok untuk tombol chat melayang atau tombol kembali ke atas.
  • sticky: hibrida relative dan fixed. Berperilaku normal sampai posisi scroll mencapai batas yang ditentukan, lalu "menempel". Pola klasik untuk menu navigasi yang nempel di atas saat di-scroll.

Pola yang paling sering dipakai di dunia nyata adalah pasangan relative + absolute: induk diberi position: relative (tanpa digeser, hanya supaya menjadi "jangkar"), anak diberi position: absolute dengan top/right tertentu. Contoh klasik: badge angka notifikasi di pojok ikon.

.ikon {
  position: relative;   /* menjadi jangkar, tidak digeser */
  width: 48px;
  height: 48px;
}
.badge {
  position: absolute;
  top: -8px;
  right: -8px;
  background: red;
  color: white;
  border-radius: 50%;
  padding: 2px 6px;
}

Berhenti dan tebak dulu! Kamu menulis ini tapi badge-nya malah nempel di pojok halaman, bukan di pojok ikon. Apa yang kurang?

.badge {
  position: absolute;
  top: 0;
  right: 0;
}
Jawaban: induknya (.ikon) tidak diberi position: relative. Elemen absolute mencari leluhur terdekat yang "terposisi" (relative, absolute, fixed, atau sticky) untuk dijadikan acuan. Kalau tidak ada, acuannya adalah halaman, sehingga top: 0; right: 0 artinya pojok halaman. Polanya selalu berpasangan: anak absolute, induk relative. Lupa separuhnya adalah bug paling umum di materi ini.

Kapan Memakai yang Mana

Supaya tidak salah alat, ini panduan memilihnya:

  • Butuh elemen turun baris dan full lebar? Itu sudah bawaan display: block, tidak perlu diapa-apakan.
  • Butuh beberapa tombol sebaris yang bisa diatur ukurannya? display: inline-block, atau lebih modern: Flexbox (episode berikutnya).
  • Butuh menyembunyikan elemen sementara dan memunculkannya lagi dengan JavaScript? display: none.
  • Butuh menggeser elemen sedikit dari posisi normalnya tanpa mengacaukan tetangganya? position: relative dengan top/left kecil.
  • Butuh menempelkan sesuatu di sudut elemen lain (badge, label diskon, tombol close)? Pasangan relative (induk) + absolute (anak).
  • Butuh elemen yang selalu terlihat walau di-scroll (menu, tombol chat)? position: fixed atau sticky.

Dan peringatan pentingnya: jangan memakai position: absolute untuk menyusun layout halaman secara umum. Elemen absolute keluar dari alur, tidak mengenal ukuran layar, dan tidak responsif dengan sendirinya. Untuk layout, pakai alur normal, Flexbox, atau Grid. Absolute hanya untuk dekorasi presisi di dalam konteks yang sudah jelas.

Kuis cepat: Apa beda display: none dan visibility: hidden?

Z-index, Siapa di Depan Siapa

Ketika elemen-elemen bertumpuk karena position, muncul pertanyaan baru: siapa yang di depan? Jawabannya diatur z-index: angka lebih besar berarti lebih depan. Elemen dengan z-index: 10 menutupi elemen dengan z-index: 5.

.modal {
  position: fixed;
  z-index: 1000;   /* paling depan, menutupi segalanya */
}
.menu {
  position: sticky;
  z-index: 100;
}

Syaratnya: z-index hanya berlaku pada elemen yang terposisi (bukan static). Nilai besar seperti 1000 untuk modal adalah konvensi umum supaya tidak tertutup apapun. Satu jebakan: elemen induk yang punya z-index menciptakan "konteks tumpukan" sendiri, sehingga anak dengan z-index raksasa pun tidak bisa keluar menutupi elemen di luar induknya. Kalau suatu hari elemenmu "tidak mau ke depan" padahal z-index-nya besar, periksa induknya.

Berhenti dan tebak dulu! Dua kotak absolute bertumpuk. Mana yang terlihat di depan?

.a { position: absolute; z-index: 5; background: red; }
.b { position: absolute; z-index: 3; background: blue; }
Jawaban: kotak A (merah). Angka z-index lebih besar selalu di depan, tidak peduli urutan penulisannya di HTML. Tanpa z-index, yang ditulis terakhir di HTML yang di depan. Aturan praktisnya: beri z-index hanya saat benar-benar butuh mengatur tumpukan, dan pakai rentang angka yang masuk akal (10, 100, 1000) supaya mudah disisipi nilai di antaranya nanti.

Latihan: Badge dan Menu Nempel

Dua latihan kecil di halaman profilmu:

  1. Badge "Baru": di salah satu kartu proyek, tambahkan <span class="badge">Baru</span>. Beri kartu position: relative dan badge position: absolute; top: 10px; right: 10px; dengan background oranye. Lalu coba hapus position: relative dari kartu dan lihat ke mana badge-nya pergi. Kembalikan lagi setelah paham.
  2. Menu nempel: buat nav halamanmu position: sticky; top: 0; dengan background solid. Scroll halaman dan perhatikan menunya menempel di atas. Bandingkan dengan fixed: apa bedanya? (Petunjuk: fixed butuh margin tambahan supaya konten tidak tertutup.)
  3. Ubah perilaku: buat tiga div yang awalnya bertumpuk ke bawah. Ubah semuanya menjadi display: inline-block dengan width 30 persen dan amati apa yang terjadi. Lalu kembalikan. Tulis satu kalimat di catatanmu tentang kapan kamu akan memakai inline-block.

Di episode berikutnya, Flexbox dari Nol Sampai Bisa, kita masuk ke senjata layout modern pertama. Kamu akan belajar menengahkan apapun dalam tiga baris, membuat navbar rapi tanpa hack, dan menyusun kartu yang tingginya selalu sama. Ini salah satu materi CSS yang paling memuaskan untuk dipelajari.