box-sizing, bir öğeye verdiğiniz width ve height değerlerinin kutunun hangi kısmını ölçtüğünü belirleyen CSS özelliğidir. Varsayılan değer content-box olup bu ayarda genişlik yalnızca içerik alanını kapsar, padding ve kenarlık üzerine eklenir. border-box değerinde ise genişlik içeriği, padding'i ve kenarlığı birlikte kapsar; böylece yazdığınız sayı ekranda gördüğünüz kutunun boyutuna eşit olur.

Bu yazıda iki değerin hesap farkını MDN örnekleri üzerinden adım adım gösteriyor, tarayıcıların hangi form öğelerinde zaten border-box kullandığını, sayfa genelinde border-box ayarlamanın yaygın desenini ve content-box değerinin hâlâ işe yaradığı durumları anlatıyoruz. Kutunun katmanlarını henüz tanımıyorsanız önce CSS kutu modeli yazısını okumanızı öneririz.

İki değer, iki farklı hesap

İki değer, iki farklı hesap: content-box, border-box

box-sizing yalnızca iki anahtar kelime alır (genel değerler inherit, initial, revert, revert-layer ve unset dışında):

  • content-box: CSS standardının belirlediği başlangıç değeridir. width ve height yalnızca içeriği kapsar; padding, kenarlık ve margin dahil değildir. Görünen genişlik = içerik genişliği + padding + kenarlık.
  • border-box: width ve height içeriği, padding'i ve kenarlığı kapsar; margin yine dahil değildir. Padding ve kenarlık kutunun içine sığdırılır, içerik alanı bu yüzden küçülür. İçerik genişliği = width - padding - kenarlık.

MDN bu farkı tek satırlık bir örnekle özetler: .box {width: 350px; border: 10px solid black;} kuralı content-box ile 350 + 10 + 10 = 370 piksel genişliğinde bir kutu çizer. Aynı kural border-box ile tam 350 piksel genişliğinde bir kutu çizer ve içerik alanı 350 - 20 = 330 piksel olur.

Adım adım hesap: MDN'nin karşılaştırma örneği

MDN'nin box-sizing sayfasındaki örnekte iki kutu aynı boyut, padding ve kenarlık değerlerine sahiptir; tek fark box-sizing değeridir. Hesapları yorum satırlarında gösteriyoruz.

css
div {
  width: 160px;
  height: 80px;
  padding: 20px;
  border: 8px solid red;
  background: yellow;
}

.content-box {
  box-sizing: content-box;
  /* toplam genişlik: 160 + (2 * 20) + (2 * 8) = 216px
     toplam yükseklik: 80 + (2 * 20) + (2 * 8) = 136px
     içerik alanı: 160px x 80px */
}

.border-box {
  box-sizing: border-box;
  /* toplam genişlik: 160px
     toplam yükseklik: 80px
     içerik genişliği: 160 - (2 * 20) - (2 * 8) = 104px
     içerik yüksekliği: 80 - (2 * 20) - (2 * 8) = 24px */
}
html
<div class="content-box">Content box</div>
<div class="border-box">Border box</div>

Sonuçta iki kutu aynı kurallarla yazılmış olsa da content-box kutusu 216 x 136 piksel, border-box kutusu 160 x 80 piksel yer kaplar. İkinci kutuda metnin sığacağı alan 104 x 24 piksele düşer. Bu yüzden border-box kullanırken büyük padding değerleri verdiğinizde içerik alanının çok daralabileceğini unutmayın.

Ölçücontent-boxborder-box
width neyi ölçerYalnızca içerikİçerik + padding + kenarlık
Görünen genişlik (örnek)216px160px
İçerik genişliği (örnek)160px104px
Margin dahil miHayırHayır
Başlangıç değeri miEvetHayır

İçerik alanı sıfırın altına inemez

border-box ile ilgili MDN'nin özellikle belirttiği bir sınır var: İçerik kutusu negatif olamaz, en küçük değeri sıfırdır. Örneğin width: 30px verip iki yana 20'şer piksel padding eklediğinizde hesap 30 - 40 = -10 piksel çıkar, ama içerik alanı -10 değil 0 olur. Bu durumda kutu yazdığınız 30 pikselde kalamaz, padding ve kenarlık kadar yer kaplamaya devam eder. MDN bunu "border-box ile bir öğeyi yok edemezsiniz" şeklinde açıklar: Padding ve kenarlık her zaman çizilir.

css
.dar {
  box-sizing: border-box;
  width: 30px;
  padding: 0 20px;
  /* içerik: 30 - 40 = -10 olurdu, ama 0'a sabitlenir
     kutu en az 20 + 20 = 40px yer kaplar */
}

Neden border-box tercih ediliyor?

Neden border-box tercih ediliyor?

MDN, content-box davranışının pratikte doğurduğu sorunu yüzde genişliklerle anlatır: Dört kutuya width: 25% verdiğinizde, bunlardan herhangi birinin sol ya da sağ padding'i veya kenarlığı varsa dört kutu varsayılan ayarda ebeveynin tek satırına sığmaz. Sayısal bir örnekle görelim.

css
.satir {
  width: 800px;
}

.satir .hucre {
  display: inline-block;
  width: 25%;
  /* 800px * 0.25 = 200px içerik genişliği */
  padding: 0 10px;
  /* content-box ile her hücre: 200 + 10 + 10 = 220px
     dört hücre: 4 * 220 = 880px, 800px'e sığmaz */
}

.satir .hucre.duzgun {
  box-sizing: border-box;
  /* her hücre tam 200px, dört hücre 800px */
}

content-box ile her hücre 220 piksel yer kapladığı için dördü toplam 880 piksel ister ve son hücre alt satıra kayar. border-box ile padding 200 pikselin içine alınır, içerik genişliği 180 piksele düşer ve dört hücre 800 piksele tam sığar. Sütunlu düzenleri kurmak için flexbox ve grid daha esnek araçlar sunar, fakat orada da padding ve kenarlığın genişliğe nasıl eklendiği aynı box-sizing kuralına bağlıdır.

MDN'nin notunda da belirtildiği gibi border-box, öğelerin boyutlandırılmasını genel olarak kolaylaştırır ve düzen kurarken karşılaşılan birçok tuzağı ortadan kaldırır. Bir kutunun kaç piksel olacağını bildiğinizde, padding ya da kenarlık eklediğinizde bu değeri yeniden hesaplamanız gerekmez. Bu özellikle yüzde ve sabit birimlerin karıştığı durumlarda önemlidir: Genişlik yüzdeyle, padding piksel ya da rem ile verildiğinde content-box toplamı ancak ekran genişliği bilindiğinde hesaplanabilir. border-box ile toplam, ekran ne olursa olsun yazdığınız yüzdeye eşit kalır. Birimlerin nasıl hesaplandığını CSS birimleri yazısında bulabilirsiniz.

Bir modelden diğerine dönüştürmek

Var olan bir tasarımı bir modelden diğerine taşırken aynı görünen boyutu korumak için basit bir dönüşüm yeterlidir. Görünen genişliği G, sol ve sağ padding toplamını P, sol ve sağ kenarlık toplamını K ile gösterelim. content-box ile yazılan genişlik G - P - K olmalıdır; border-box ile doğrudan G yazılır. Yükseklik için aynı hesap üst ve alt değerlerle yapılır.

css
/* hedef: görünen genişlik 300px, padding 24px, kenarlık 2px */

.kutu-a {
  box-sizing: content-box;
  width: 248px;
  /* 300 - (2 * 24) - (2 * 2) = 300 - 48 - 4 = 248px */
  padding: 24px;
  border: 2px solid;
}

.kutu-b {
  box-sizing: border-box;
  width: 300px;
  /* içerik: 300 - 48 - 4 = 248px, iki kutu aynı görünür */
  padding: 24px;
  border: 2px solid;
}

İki kural ekranda birebir aynı kutuyu üretir; fark yalnızca hangi sayının yazıldığıdır. border-box tarafında padding'i 24 pikselden 32 piksele çıkardığınızda kutu yine 300 pikselde kalır, içerik 232 piksele düşer. content-box tarafında ise aynı değişiklik kutuyu 316 piksele genişletir ve width değerini elle 232 piksele indirmeniz gerekir.

min-width ve max-width ile birlikte kullanım

MDN'nin kutu modeli girişine göre border-box ayarında yalnızca width ve height değil, min-width, max-width, min-height ve max-height de border alanının boyutunu belirler. Yani sınır değerleri de kenarlık ve padding dahil ölçülür. Okunabilir bir metin sütunu için sık kullanılan şu kuralda bu fark açıkça görülür.

css
.metin-sutunu {
  max-width: 640px;
  padding: 0 20px;
}
/* content-box: içerik en fazla 640px, görünen kutu 640 + 40 = 680px
   border-box:  görünen kutu en fazla 640px, içerik 640 - 40 = 600px */

Tasarım dosyasında "sütun en fazla 640 piksel" yazıyorsa border-box bu ölçüyü doğrudan karşılar. content-box ile aynı sonucu almak için max-width değerini 600 piksel yapmanız gerekir.

Uygulamalı mini örnek: taşan form alanı

Bu modelin en çok fark edildiği yer formlardır. 320 piksel genişliğindeki bir kapsayıcıda metin kutusuna width: 100% verdiğinizi düşünün.

css
.form {
  width: 320px;
}

.form input[type="text"] {
  width: 100%;
  /* içerik genişliği: 320px */
  padding: 8px;
  border: 1px solid gray;
  /* content-box ile görünen genişlik: 320 + 16 + 2 = 338px
     kapsayıcıdan 338 - 320 = 18px taşar */
}

.form input[type="text"].duzeltildi {
  box-sizing: border-box;
  /* görünen genişlik 320px, içerik 320 - 16 - 2 = 302px */
}

İlk kuralda alan, kapsayıcının sağ kenarından 18 piksel dışarı taşar; kapsayıcıda overflow ayarı varsa yatay kaydırma çubuğu da çıkabilir. İkinci kuralda alan kapsayıcıya tam oturur. Taşan içeriğin nasıl kırpıldığını ya da kaydırıldığını overflow yazısında anlatıyoruz. Geliştirici araçlarının kutu modeli paneli de öğenin box-sizing değerini gösterir; bir alanın neden taştığını anlamak için önce oraya bakmak zaman kazandırır.

Tarayıcıların zaten border-box kullandığı öğeler

Bazı form ve tablo öğelerinde tarayıcının varsayılan stili zaten border-box uygular. MDN'ye göre bunlar <table>, <select>, <button> ve türü radio, checkbox, reset, button, submit, color ya da search olan <input> öğeleridir. Bu liste, aynı genişliği verdiğiniz bir metin kutusu ile bir düğmenin neden farklı genişlikte göründüğünü açıklar: Metin türündeki <input> bu listede yoktur, dolayısıyla varsayılan olarak content-box ile ölçülür.

css
input[type="text"],
button {
  width: 200px;
  padding: 8px;
  border: 1px solid gray;
  /* box-sizing ayarlanmazsa metin kutusu 200 + 16 + 2 = 218px,
     düğme ise tarayıcı varsayılanı border-box ile 200px olur */
}

input[type="text"] {
  box-sizing: border-box;
  /* artık ikisi de 200px */
}

Sayfa genelinde border-box ayarlamak

Her öğeye tek tek box-sizing yazmak yerine kuralı bir kez kök öğede tanımlayıp diğer öğelerin bu değeri devralmasını sağlayabilirsiniz. MDN'nin "sticky footer" tarifinde bu desen kullanılır: Kök öğe html için border-box belirlenir, evrensel seçici * ise her öğeye inherit verir.

css
html {
  box-sizing: border-box;
}

* {
  box-sizing: inherit;
  /* her öğe değeri ebeveyninden alır */
}

inherit genel anahtar kelimesi değeri ebeveynden almayı zorunlu kılar. Bu desenin avantajı, bir bileşenin kökünde box-sizing: content-box yazdığınızda o bileşenin tüm alt öğelerinin de bu değeri devralmasıdır; tek satırla bir alt ağacı farklı modele geçirebilirsiniz. Kalıtımın ve genel anahtar kelimelerin ayrıntısı için cascade ve kalıtım yazısına bakabilirsiniz.

Bir ayrıntı: Evrensel seçici yalnızca öğeleri eşler, sözde öğeleri (pseudo-element) kendiliğinden eşlemez. MDN, tüm ::before sözde öğelerini hedeflemek için *::before gibi bir seçici gerektiğini belirtir. ::before ve ::after ile oluşturduğunuz kutuların da aynı modeli kullanmasını istiyorsanız bunları seçici listesine ayrıca eklersiniz.

css
html {
  box-sizing: border-box;
}

*,
*::before,
*::after {
  box-sizing: inherit;
}

Sözde öğelerin nasıl oluşturulduğu ::before ve ::after yazısında, evrensel ve diğer temel seçiciler ise CSS seçiciler yazısında anlatılıyor.

content-box ne zaman hâlâ işe yarar?

border-box genel tercih olsa da content-box tamamen gereksiz değildir. MDN, position: relative ya da position: absolute kullanılan durumlarda content-box ile konumlandırma değerlerinin içeriğe göre kalabileceğini ve kenarlık ile padding değişikliklerinden bağımsız olabileceğini, bunun bazen istenen bir şey olduğunu belirtir.

Bununla bağlantılı bir hesap ayrıntısı içeren blok rehberinde geçer: Mutlak konumlu bir öğenin yüzde değerleri, içeren bloğun padding kutusuna göre hesaplanır. MDN'nin örneğinde 400 piksel genişliğinde, iki yanında 20 piksel padding olan mutlak konumlu bir kapsayıcı içindeki öğeye width: 50% verildiğinde sonuç (400 + 20 + 20) x 0,5 = 220 piksel olur. Rehber, kapsayıcının box-sizing değeri border-box olsaydı bu durumun böyle olmayacağını da not eder; çünkü o zaman 400 piksel padding'i zaten içerir. Konumlandırmanın kendisi position yazısında anlatılıyor.

css
section {
  position: absolute;
  width: 400px;
  height: 160px;
  padding: 30px 20px;
}

p {
  position: absolute;
  width: 50%;
  /* (400 + 20 + 20) * 0.5 = 220px */
  height: 25%;
  /* (160 + 30 + 30) * 0.25 = 55px */
}

Sık yapılan hatalar

Sık yapılan hatalar: border-box ile margin'in de dahil olduğunu sanmak, Metin kutusu ile düğmenin neden farklı genişlikte olduğunu anlamamak, Yalnızca * yazıp sözde öğeleri...
  • border-box ile margin'in de dahil olduğunu sanmak: Margin iki değerde de width hesabına girmez; kutunun dışında ayrıca yer kaplar.
  • Metin kutusu ile düğmenin neden farklı genişlikte olduğunu anlamamak: Tarayıcı düğmede border-box, metin türündeki <input> öğesinde content-box kullanır.
  • Yalnızca * yazıp sözde öğeleri unutmak: * sözde öğeleri eşlemez; *::before ve *::after ayrıca eklenmelidir.
  • Büyük padding ile içerik alanını yok etmek: border-box ile içerik alanı küçülür, sıfıra düştüğünde kutu yazdığınız genişliği aşar.
  • Yüksekliği hesaba katmamak: box-sizing yalnızca genişliği değil height, min-height ve max-height hesaplarını da etkiler.

Sık Sorulan Sorular

box-sizing varsayılan değeri nedir?

CSS standardındaki başlangıç değeri content-box değeridir. Ancak tarayıcıların varsayılan stil dosyası tablo, açılır liste, düğme ve bazı <input> türlerinde border-box uygular.

border-box kullanınca padding nereye gidiyor?

Padding ve kenarlık, verdiğiniz width ve height değerinin içine sığdırılır. Kutu dışarıdan aynı boyutta kalır, içerik alanı padding ve kenarlık kadar küçülür.

Tüm sayfaya border-box vermek bir şeyi bozar mı?

Kendi yazdığınız stillerde genellikle hesapları kolaylaştırır. Hazır bir bileşen ya da üçüncü taraf stil dosyası content-box varsayıyorsa, o bileşenin köküne box-sizing: content-box vermek yeterlidir; inherit desenini kullandıysanız alt öğeler de bu değeri devralır.

Yeni bir projede hangi değeri seçmeliyim?

Çoğu düzende border-box daha öngörülebilir sonuç verir, çünkü tasarımda yazan ölçü ile CSS'te yazdığınız sayı aynı olur. Sayfa genelinde html üzerinde border-box tanımlayıp inherit desenini kullanmak, gerektiğinde tek bir bileşeni content-box modeline döndürme esnekliğini de korur. İçerik alanının boyutunun padding ve kenarlıktan bağımsız sabit kalması gereken, örneğin konumlandırma değerlerini içeriğe göre hesapladığınız özel durumlarda ise o bileşen için content-box kullanın. Hangi modeli seçerseniz seçin, ekipte herkesin aynı varsayımla çalışması için kuralı stil dosyasının en başına koyup bir yorumla açıklamak iyi bir alışkanlıktır.

box-sizing margin collapsing'i etkiler mi?

Hayır. box-sizing yalnızca kutunun boyutunun nasıl hesaplandığını değiştirir. Dikey dış boşlukların birleşmesi ayrı kurallara bağlıdır; margin collapsing yazısında anlatılıyor.

Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.

İlgili içerikler: CSS öğrenme rehberi · CSS kutu modeli · Margin collapsing · Cascade ve kalıtım · calc() ve clamp() · flex-grow, flex-shrink ve flex-basis