Properti box-sizing menentukan area mana yang diukur oleh width dan height pada sebuah kotak. Topik ini membandingkan nilai bawaan content-box dengan border-box, menghitung ulang ukurannya, dan memaparkan alasan reset universal dianjurkan pada hampir setiap proyek. Setelah membacanya, penentuan nilai width tidak lagi memerlukan penyesuaian padding dan border secara manual.
Perbedaan content-box dan border-box#
Pada nilai content-box, width dan height hanya mengukur area content, sehingga padding dan border ditambahkan di luarnya. Pada nilai border-box, width dan height mengukur keseluruhan kotak sampai tepi luar border, sehingga padding dan border memakan area content dari dalam. Kedua nilai menghasilkan kotak yang terlihat berbeda meskipun deklarasinya sama persis.
| Aspek | content-box | border-box |
|---|---|---|
Area yang diukur width | content saja | content, padding, dan border |
Kotak width: 200px, padding 20px, border 4px | 248 piksel | 200 piksel |
| Nilai bawaan CSS | ya | bukan |
Selisihnya dapat dihitung langsung. Ambil dua kotak dengan width: 200px, padding: 20px, dan border: 4px. Kotak content-box terlihat selebar piksel, sedangkan kotak border-box tetap selebar 200 piksel karena area content-nya menyusut menjadi 152 piksel. Seluruh selisih berasal dari perpindahan batas pengukuran, bukan dari perubahan nilai.
Properti height berperilaku dengan pola yang sama, yaitu ditambah padding vertikal dan border vertikal pada content-box. Selisih model ukuran paling terasa pada komponen yang disusun berdampingan, misalnya kartu jadwal piket dalam satu baris. Tanpa model yang seragam, dua kartu dengan width yang sama dapat memiliki lebar terlihat yang berbeda hanya karena paddingnya berbeda.
Reset universal#
Cara paling umum menerapkan border-box adalah reset universal, yaitu satu aturan yang menjangkau seluruh elemen sekaligus. Selector * menyasar setiap elemen, sedangkan *::before dan *::after menjangkau pseudo-element yang dibuat oleh CSS. Pseudo-element ikut dijangkau karena elemen semacam itu juga memiliki box model sendiri.
*, *::before, *::after {
box-sizing: border-box;
}Aturan tersebut biasanya diletakkan di bagian paling atas berkas stylesheet utama, sebelum aturan komponen ditulis. Selector * memiliki specificity terendah, yaitu nol, sehingga komponen yang memang memerlukan perilaku lain masih dapat menetapkan box-sizing-nya sendiri dengan selector yang lebih spesifik. Dengan susunan seperti ini, seluruh perhitungan ukuran pada berkas yang sama mengikuti satu model yang konsisten.
Beberapa proyek menuliskannya sedikit berbeda, misalnya hanya * { box-sizing: border-box; } tanpa pseudo-element. Bentuk itu lebih pendek, tetapi pseudo-element yang dibuat melalui ::before dan ::after tetap mengikuti nilai bawaan, sehingga kotak hasil content: "" dapat berukuran tak terduga. Bentuk lengkap dengan ketiga selector menutup celah tersebut.
Alasan reset dianjurkan#
Alasan utamanya adalah kesetaraan antara ukuran yang dideklarasikan dan ukuran yang terlihat. Elemen dengan width: 300px benar-benar selebar 300 piksel berapa pun padding dan border-nya, sehingga komponen dapat dirancang secara terpisah tanpa menghitung ulang. Perilaku ini menghilangkan salah satu sumber error layout yang paling sering terjadi, yaitu elemen yang meluber dari induknya karena tambahan padding.
Reset juga membuat satuan persen lebih aman dipakai. Meskipun diberi padding tetap, elemen dengan width: 50% tetap mengisi separuh lebar induk pada model border-box, sedangkan pada content-box ukurannya melebihi separuh tersebut. Karena alasan inilah hampir seluruh framework dan panduan praktik modern memuat reset serupa sebagai langkah awal. Pengecualian tetap dapat dibuat secara lokal, sehingga reset tidak mengunci seluruh proyek pada satu perilaku.
Ukuran yang prediktabel juga menyederhanakan komunikasi tim. Desain yang menyebut lebar 320 piksel dapat diterjemahkan langsung menjadi width: 320px tanpa diskusi tambahan tentang padding, dan pemeriksaan tampilan cukup membandingkan angka yang sama.
Warisan dan pengecualian#
Properti box-sizing tidak diwariskan dari induk ke anak. Reset universal tetap menjangkau semua elemen karena * menyasar setiap elemen secara langsung, tetapi ada proyek yang menginginkan nilai ini menular agar komponen eksternal dapat menentukan model ukurannya sendiri. Untuk keperluan itu, nilai pada reset dapat diganti menjadi inherit.
Pada praktiknya, reset universal dengan nilai border-box tetap menjadi titik awal yang paling aman. Pola inherit dipakai ketika proyek memuat widget eksternal yang membawa model ukurannya sendiri, misalnya widget jadwal piket pihak ketiga yang memang dirancang untuk content-box. Aturan * memiliki bobot paling rendah, sehingga aturan milik widget yang menetapkan box-sizing sendiri tetap menang.
Perlu dicatat bahwa pola inherit mengubah makna reset: nilainya tidak lagi tetap, melainkan mengikuti keputusan elemen di atasnya. Kebebasan itu berguna, tetapi menuntut kedisiplinan menetapkan nilai pada akar setiap pohon komponen.
Demo perbandingan#
Demo berikut menampilkan dua kotak dengan deklarasi yang sama, yaitu width: 200px, padding: 20px, dan border: 4px. Garis putus-putus di atasnya menandai lebar 200 piksel sebagai acuan. Kotak content-box meluber melewati acuan karena ukuran totalnya 248 piksel, sedangkan kotak border-box tepat mengisi lebar acuan tersebut. Bedah kodenya pada panel samping demo, lalu perhatikan satu-satunya perbedaan yang memisahkan keduanya, yaitu nilai box-sizing.
Kode sumber demo
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<title>content-box dan border-box</title>
<link rel="stylesheet" href="index.css">
</head>
<body>
<h1>Dua kotak, sama-sama width: 200px</h1>
<div class="acuan">acuan 200px</div>
<div class="kotak content-box">content-box: terlihat 248px</div>
<div class="kotak border-box">border-box: terlihat 200px</div>
<style>
/* Demo perbandingan content-box dan border-box */
body {
margin: 0;
padding: 20px;
font-family: sans-serif;
}
h1 {
font-size: 18px;
margin: 0 0 12px;
}
.acuan {
width: 200px;
box-sizing: border-box; /* garis putus-putus tepat 200px lebar terlihat */
border: 2px dashed #64748b;
padding: 4px;
font-size: 14px;
margin-bottom: 16px;
}
.kotak {
width: 200px;
padding: 20px;
border: 4px solid;
margin-bottom: 16px;
}
.content-box {
box-sizing: content-box; /* nilai bawaan: width hanya untuk content */
border-color: #1d4ed8;
background: #dbeafe;
}
.border-box {
box-sizing: border-box; /* width mencakup padding dan border */
border-color: #15803d;
background: #bbf7d0;
}
</style>
<style>
/* Demo perbandingan content-box dan border-box */
body {
margin: 0;
padding: 20px;
font-family: sans-serif;
}
h1 {
font-size: 18px;
margin: 0 0 12px;
}
.acuan {
width: 200px;
box-sizing: border-box; /* garis putus-putus tepat 200px lebar terlihat */
border: 2px dashed #64748b;
padding: 4px;
font-size: 14px;
margin-bottom: 16px;
}
.kotak {
width: 200px;
padding: 20px;
border: 4px solid;
margin-bottom: 16px;
}
.content-box {
box-sizing: content-box; /* nilai bawaan: width hanya untuk content */
border-color: #1d4ed8;
background: #dbeafe;
}
.border-box {
box-sizing: border-box; /* width mencakup padding dan border */
border-color: #15803d;
background: #bbf7d0;
}
</style></body>
</html>Perilaku kotak yang meluber itulah yang membuat layout rusak ketika padding ditambahkan pada komponen berlebar tetap. Selama proyek masih memakai nilai bawaan, setiap penambahan padding wajib diikuti pengurangan width agar lebar totalnya tetap. Setelah reset dipasang, penambahan padding tidak perlu lagi diikuti pengurangan width. Coba ubah nilai padding demo menjadi 40px, lalu perhatikan kotak content-box meluber lebih jauh, sedangkan kotak border-box tidak bergeser sama sekali.
Kesalahan umum#
Kesalahan yang lazim adalah memasang reset pada selector html saja dengan harapan nilainya menular ke seluruh halaman. Karena box-sizing tidak diwariskan, elemen-elemen di dalamnya tetap mengikuti nilai bawaan content-box dan hasil layout-nya tetap tidak terduga. Perbaikannya adalah menjangkau seluruh elemen sekaligus dengan *, *::before, dan *::after sebagaimana blok reset universal.
Kasus kedua adalah komponen pihak ketiga yang bentuknya berubah setelah reset dipasang. Komponen semacam itu sering dirancang dengan asumsi content-box, sehingga padding yang sebelumnya menambah ukurannya kini memakan area content. Solusinya bukan membuang reset, melainkan menetapkan box-sizing: content-box pada elemen pembungkus komponen tersebut, idealnya melalui pola inherit yang dijelaskan di atas.
Kasus ketiga adalah lupa bahwa height mengikuti model yang sama. Angka tinggi komponen yang dihitung pada masa content-box berubah setelah reset dipasang, karena padding vertikal kini termasuk dalam height. Pemeriksaan visual pada komponen bertinggi tetap perlu dilakukan ulang setelah reset pertama kali diterapkan.
Ringkasan#
- Nilai
content-boxmengukurwidthpada area content, sedangkanborder-boxmengukur sampai tepi luar border. - Reset universal
*, *::before, *::aftermenerapkanborder-boxpada setiap elemen sejak awal berkas stylesheet. - Dengan
border-box, ukuran yang dideklarasikan sama dengan ukuran yang terlihat, sehingga komponen dapat dirancang tanpa mengurangiwidthuntuk padding dan border. box-sizingtidak diwariskan, dan polabox-sizing: inherittersedia bila perilaku menular memang diinginkan.
Referensi#
- box-sizing — MDN Web Docs
— Dokumentasi resmi nilai
content-boxdanborder-boxbeserta contoh penggunaannya. - Sizing items in CSS — web.dev
— Materi Learn CSS tentang penentuan ukuran elemen, termasuk peran
box-sizing.