- Bab 6 dari 10
- 30 menit
- 1 latihan kode
- 4 soal kuis
Box Model, Display, dan Position
Di bab ini (9 bagian)
Tujuan bab ini
- Memahami empat lapisan box model dan menghitung ukuran total sebuah elemen.
- Memakai
box-sizing: border-boxdan mengenali margin collapse. - Membedakan
displayblock, inline, inline-block, dan none. - Mengatur posisi elemen dengan
positiondan menumpuknya denganz-index.
Semua elemen adalah kotak
Buka DevTools di browser mana pun, arahkan kursor ke sebuah elemen, dan kamu akan melihat kotak berwarna-warni. Itu box model: setiap elemen HTML digambar sebagai kotak dengan empat lapisan, dari dalam ke luar.
| Lapisan | Isinya | Properti |
|---|---|---|
| content | teks, gambar, anak elemen | width, height |
| padding | ruang antara content dan border, ikut warna background | padding |
| border | garis pembatas | border |
| margin | jarak ke elemen lain, selalu transparan | margin |
Analoginya seperti kado: content adalah barangnya, padding adalah bubble wrap, border adalah kardus, dan margin adalah jarak antar kardus di rak.
Shorthand padding dan margin mengikuti arah jarum jam: padding: 10px 20px 30px 40px berarti atas, kanan, bawah, kiri. Dua nilai (10px 20px) berarti atas-bawah lalu kiri-kanan.
Hitung lebarnya: content-box vs border-box
Secara default browser memakai box-sizing: content-box. Artinya width hanya untuk area content, lalu padding dan border ditambahkan di luarnya. Lebar .kartu di atas yang terlihat di layar:
Margin tidak dihitung dalam lebar kotak, tetapi tetap memakan ruang di sekitarnya. Inilah sumber banyak kebingungan: kamu menulis 300px, tapi kotaknya 344px dan tiba-tiba layout meluber.
Solusinya border-box: width sudah termasuk padding dan border, sehingga content yang menyusut.
Dengan aturan ini, .kartu di atas tepat 300px lebarnya, dan area content-nya 300 - 40 - 4 = 256px. Hampir semua proyek modern menaruh tiga baris ini di paling atas file CSS.
Margin collapse singkat
Ada satu perilaku aneh yang perlu kamu tahu: margin vertikal dua elemen block yang bertetangga bisa menyatu. Kalau paragraf pertama punya margin-bottom: 20px dan paragraf kedua punya margin-top: 30px, jaraknya bukan 50px, melainkan 30px (diambil yang terbesar).
Margin collapse hanya terjadi pada margin atas-bawah di alur normal. Margin kiri-kanan tidak pernah menyatu, dan item di dalam flex atau grid container juga tidak mengalaminya. Kalau jarak terasa "hilang", kemungkinan besar ini penyebabnya.
display: bagaimana elemen mengalir
Properti display menentukan cara elemen ikut dalam alur halaman.
| Nilai | Perilaku | Contoh bawaan |
|---|---|---|
block | mulai di baris baru, melebar penuh, width/height berlaku | div, p, h1, section |
inline | mengalir dalam teks, width/height diabaikan | span, a, strong |
inline-block | mengalir seperti inline, tapi ukuran bisa diatur | button, input |
none | dihapus dari layout, tidak memakan ruang | dipakai untuk menyembunyikan |
Dengan inline-block, label tetap berada di tengah kalimat tetapi lebarnya benar-benar 80px. Kalau diganti inline, width diabaikan dan padding atas-bawahnya tidak mendorong baris lain. Kalau diganti block, label pindah ke baris sendiri dan memecah kalimat.
Bedakan display: none dengan visibility: hidden. Yang pertama menghapus ruang elemen, yang kedua hanya membuatnya tak terlihat tetapi ruangnya tetap ada, jadi akan ada lubang kosong.
display: flex dan display: grid juga nilai display. Keduanya membuat elemen tetap berperilaku seperti block bagi tetangganya, sekaligus menjadi container untuk anak-anaknya. Itu bab berikutnya.
position: memindahkan elemen
| Nilai | Masih di alur normal? | Patokan top/left |
|---|---|---|
static | ya (default) | tidak berpengaruh |
relative | ya, ruang aslinya tetap dipesan | posisi aslinya sendiri |
absolute | tidak | ancestor terdekat yang positioned |
fixed | tidak | viewport, diam saat scroll |
sticky | ya, sampai ambang tercapai | menempel saat scroll melewati ambang |
"Positioned" berarti punya position selain static. Pola paling umum adalah relative pada induk, absolute pada anak:
Badge diskon akan menempel di pojok kanan atas foto. Tanpa position: relative pada .foto, badge mencari ancestor positioned berikutnya, dan kalau tidak ada, ia menempel ke pojok halaman.
Dua lainnya:
Navbar fixed selalu di atas layar walau halaman di-scroll, jadi beri konten di bawahnya padding-top agar tidak tertutup. sticky berperilaku normal sampai jaraknya ke atas layar mencapai top: 0, lalu menempel. sticky wajib punya minimal satu nilai top/bottom/left/right, dan berhenti menempel saat induknya habis di-scroll.
z-index: siapa di atas
Saat elemen saling tumpuk, z-index menentukan urutannya. Nilai lebih besar tampil di depan.
Aturan pentingnya: z-index hanya bekerja pada elemen positioned (atau item flex/grid). Selain itu, elemen positioned dengan z-index selain auto membentuk stacking context baru. Anak di dalamnya hanya bisa bertarung dengan saudara di konteks yang sama, jadi z-index: 9999 pada anak tidak bisa menembus induk yang ber-z-index: 1 di bawah elemen lain ber-z-index: 2.
Kesalahan umum
- Lupa padding dan border menambah lebar pada
content-box, lalu kolom tidak muat. - Memberi
widthpadaspanlalu heran tidak berubah. Ubah keinline-blockataublock. - Memakai
absolutetanpa indukrelative, sehingga elemen terbang ke pojok halaman. - Menulis
z-indexpada elemenstaticdan berharap ia naik ke depan. - Memakai
display: nonepadahal ingin ruangnya tetap ada.
Rangkuman
- Box model: content, padding, border, margin, dari dalam ke luar.
box-sizing: border-boxmembuatwidthsudah termasuk padding dan border.- Margin vertikal antar block bisa menyatu, diambil yang terbesar.
displaymengatur alur: block, inline, inline-block, none.positionrelative, absolute, fixed, dan sticky memindahkan elemen dengan patokan berbeda.z-indexmengatur tumpukan elemen positioned di dalam stacking context-nya.
Slide 12 sampai 14 dari deck HTML5 dan CSS3. Penjelasan lengkapnya ada di mode Baca.

Selesaikan bab ini
- 1. Baca materi
- 2. Latihan kode (1)
- 3. Kuis (4 soal)
Latihan kode: Kartu produk dengan badge diskon
HTML-nya sudah jadi, jangan diubah. Lengkapi CSS-nya:
- Pasang
box-sizing: border-boxuntuk semua elemen dengan selector*. .kartulebarnya240pxdenganpadding: 16pxdanborder: 2px solid #111. Lebar yang terlihat harus tepat 240px.- Badge
.badgemenempel di pojok kanan atas kartu:position: absolute,top: 8px,right: 8px,z-index: 2. Jangan lupa kartu harus jadi patokannya. .hargatetap sebaris tapi lebarnya bisa diatur:display: inline-blockdanwidth: 120px.
Cek pemahaman
1Dengan box-sizing bawaan (content-box), berapa lebar kotak yang terlihat, tanpa menghitung margin?
.kotak { width: 200px; padding: 10px; border: 5px solid black; margin: 20px; }2Elemen dengan `position: absolute` diposisikan terhadap apa?
3Dengan `box-sizing: border-box`, nilai `width` sudah termasuk padding dan border.
4Berapa jarak vertikal antara kedua paragraf?
<style> .a { margin-bottom: 20px; } .b { margin-top: 30px; } </style> <p class="a">Satu</p> <p class="b">Dua</p>