---
title: 'Esnek Kutu Modeli'
source: 'https://academia.sh/tr/kurslar/duzen-ve-duyarli-tasarim/esnek-kutu-modeli'
course: 'Düzen Sistemleri ve Duyarlı Tasarım'
language: tr
updated: '2026-08-17T18:09:24+00:00'
license: 'CC BY-SA 4.0'
---

# Esnek Kutu Modeli

Esnek kutu bağlamının kurulması, ana ve çapraz eksenin yön bildiriminden türetilmesi, boş alanın ana eksende dağıtılması ve çapraz eksende hizalama.

CSS ile Görsel Sunum kursu normal akışın kurallarını kurdu: blok kutular blok ekseninde
yığılır, satır içi kutular satır kutularına yerleştirilir. Kutuları yan yana dizmek için o
kursta kaydırma ve konumlandırma gösterildi; ikisi de kutuyu akıştan çıkarır ve
kapsayanının yüksekliğini hesaplayamaz duruma getirir.

Bu ders, kutuları yan yana dizmek için tanımlanmış olan **düzen modelini (layout model)**
ele alır. Esnek kutu, akıştan çıkarma yoluna gitmez; kapsayanın içinde yeni bir yerleşim
kuralı kurar ve boş alanı çocuklar arasında bölüştürür.

## Esnek Kutu Bağlamı

Bir kutuya `display: flex` bildirildiğinde kutunun **kendisi** akışta blok kutu olarak
kalır; değişen şey **çocuklarının** yerleştirilme kuralıdır. Bu kutu artık bir **esnek
kapsayıcıdır (flex container)** ve doğrudan çocukları **esnek ögelerdir (flex item)**.

Üç sonuç hemen doğar:

1. Çocukların `display` değeri **bloklaştırılır**. Bir `span` çocuk, satır içi kutu olmaktan
   çıkar ve esnek öge olur; genişlik ve dikey dış boşluk alabilir.
2. Kutular arasındaki dış boşluk **çökmez**. Akış Düzeni dersindeki çökme kuralı yalnızca
   blok düzeninde tanımlıdır; esnek kutu bağlamında iki komşu boşluk toplanır.
3. Etiketle sarılmamış metin de bir esnek öge olur. Ögeye adı olmadığı için **anonim
   kutu** denir ve seçiciyle hedeflenemez.

Üçüncü madde, düzenin bozulduğu durumlarda ilk bakılacak yerlerden biridir: kapsayıcının
içindeki bir satır sonu ve girinti boşluk üretmez, ama gerçek bir metin parçası öge sayılır.

## İki Eksen

Esnek kutu **tek eksenli** bir modeldir. Ögeler tek bir doğrultuda dizilir ve boş alan o
doğrultuda bölüştürülür. Bu doğrultuya **ana eksen (main axis)**, ona dik olana **çapraz
eksen (cross axis)** denir.

Ana ekseni `flex-direction` belirler:

| Bildirim | Ana eksen | Ana başlangıç | Çapraz eksen |
|---|---|---|---|
| `row` | satır içi eksen | satır içi başlangıç | blok eksen |
| `row-reverse` | satır içi eksen | satır içi bitiş | blok eksen |
| `column` | blok eksen | blok başlangıç | satır içi eksen |
| `column-reverse` | blok eksen | blok bitiş | satır içi eksen |

Tablodaki adlandırma bilinçli olarak "yatay" ve "dikey" demiyor. Satır içi eksen, metnin
aktığı doğrultudur ve belgenin yazma yönüne bağlıdır; sağdan sola yazılan bir belgede
`row` yönündeki ilk öge sağda başlar. Esnek kutu bildirimleri bu doğrultuları soyut olarak
adlandırdığı için aynı biçem dosyası yön değiştiğinde de doğru çalışır.

Ana eksenin iki ucu **ana başlangıç** ve **ana bitiş**, çapraz eksenin iki ucu **çapraz
başlangıç** ve **çapraz bitiş** olarak anılır. Hizalama bildirimlerinin tamamı bu dört uca
göre okunur.

## Boş Alanın Dağıtımı

Ögelerin ana eksendeki ölçüleri toplandığında kapsayıcıdan küçük kalıyorsa geriye **boş
alan** kalır. `justify-content` bildirimi bu alanın nereye konacağını söyler.

Aşağıdaki program, üç ögeli bir satırda altı dağıtım değerini hesaplar. Kapsayıcı 720
birim, aralar 16 birimdir.

```js
// eksen.mjs — bir esnek satirda ana eksen dagitimi ve capraz eksen hizalamasi
const KAPSAYICI = 720;
const ARALIK = 16;
const kutular = [
  { ad: "arama", ana: 180, capraz: 40 },
  { ad: "tarih", ana: 140, capraz: 32 },
  { ad: "durum", ana: 120, capraz: 56 },
];

const toplamAna = kutular.reduce((t, k) => t + k.ana, 0);
const araToplam = ARALIK * (kutular.length - 1);
const bosAlan = KAPSAYICI - toplamAna - araToplam;
console.log(`kapsayici=${KAPSAYICI}  kutular=${toplamAna}  aralik=${araToplam}  bos alan=${bosAlan}`);

// ana eksende dagitim: her deger, bos alani farkli yerlere koyar
function anaEksen(deger) {
  const n = kutular.length;
  let bas = 0, ek = 0;
  if (deger === "flex-start") { bas = 0; ek = 0; }
  if (deger === "flex-end") { bas = bosAlan; ek = 0; }
  if (deger === "center") { bas = bosAlan / 2; ek = 0; }
  if (deger === "space-between") { bas = 0; ek = bosAlan / (n - 1); }
  if (deger === "space-around") { ek = bosAlan / n; bas = ek / 2; }
  if (deger === "space-evenly") { ek = bosAlan / (n + 1); bas = ek; }
  const yerler = [];
  let x = bas;
  for (const k of kutular) {
    yerler.push({ ad: k.ad, bas: x, son: x + k.ana });
    x += k.ana + ARALIK + ek;
  }
  return yerler;
}

console.log("\n--- ana eksen (justify-content) ---");
for (const d of ["flex-start", "flex-end", "center", "space-between", "space-around", "space-evenly"]) {
  const y = anaEksen(d);
  const metin = y.map((k) => `${k.ad} ${k.bas.toFixed(1)}..${k.son.toFixed(1)}`).join("  ");
  console.log(d.padEnd(14), metin);
}

// capraz eksende hizalama: satir yuksekligi en uzun kutuyla belirlenir
const SATIR = Math.max(...kutular.map((k) => k.capraz));
console.log(`\n--- capraz eksen (align-items), satir yuksekligi=${SATIR} ---`);
for (const d of ["flex-start", "flex-end", "center", "stretch"]) {
  const y = kutular.map((k) => {
    if (d === "stretch") return `${k.ad} 0..${SATIR}`;
    const bas = d === "flex-start" ? 0 : d === "flex-end" ? SATIR - k.capraz : (SATIR - k.capraz) / 2;
    return `${k.ad} ${bas.toFixed(1)}..${(bas + k.capraz).toFixed(1)}`;
  });
  console.log(d.padEnd(12), y.join("  "));
}
```

```
kapsayici=720  kutular=440  aralik=32  bos alan=248

--- ana eksen (justify-content) ---
flex-start     arama 0.0..180.0  tarih 196.0..336.0  durum 352.0..472.0
flex-end       arama 248.0..428.0  tarih 444.0..584.0  durum 600.0..720.0
center         arama 124.0..304.0  tarih 320.0..460.0  durum 476.0..596.0
space-between  arama 0.0..180.0  tarih 320.0..460.0  durum 600.0..720.0
space-around   arama 41.3..221.3  tarih 320.0..460.0  durum 558.7..678.7
space-evenly   arama 62.0..242.0  tarih 320.0..460.0  durum 538.0..658.0

--- capraz eksen (align-items), satir yuksekligi=56 ---
flex-start   arama 0.0..40.0  tarih 0.0..32.0  durum 0.0..56.0
flex-end     arama 16.0..56.0  tarih 24.0..56.0  durum 0.0..56.0
center       arama 8.0..48.0  tarih 12.0..44.0  durum 0.0..56.0
stretch      arama 0..56  tarih 0..56  durum 0..56
```

Boş alan 248 birimdir ve altı satır bu 248 birimi altı ayrı biçimde yerleştirir.

`flex-start`, `flex-end` ve `center` boş alanı **tek parça** bırakır; yalnızca yerini
değiştirir. Kalan üçü boş alanı **böler** ve payların nereye düştüğü ayrışır:

- `space-between` iki uca hiç pay ayırmaz, alanı ögeler arasına eşit böler:
  $248 / 2 = 124$ birim ek boşluk.
- `space-around` her ögeye kendi payını verir, pay ögenin iki yanına yarımlanır:
  $248 / 3 \approx 82{,}67$; kenarlarda yarım pay $\approx 41{,}33$, aralarda iki yarım
  pay bitişir ve $\approx 82{,}67$ olur.
- `space-evenly` bütün boşlukları eşitler: $248 / 4 = 62$ birim, kenarda da arada da aynı.

Üç değerin de orta ögeyi aynı yere koyması rastlantı değil: dağıtım simetriktir ve üç öge
ortasında bir öge varsa o öge merkezde kalır. Ayrım kenarlardadır.

Sıra bir uyarı gerektirir: `flex-start` ve `flex-end` yerine `start`/`end` yazımı da
tanımlıdır ve ikisi çoğu durumda aynı sonucu verir. Aynı biçem dosyası içinde tek bir yazım
seçilir; bu kurs boyunca `flex-` önekli biçim kullanılacaktır.

## Çapraz Eksende Hizalama

Çapraz eksende dağıtacak boş alan yoktur; her öge kendi başına hizalanır. `align-items`
kapsayıcıda tüm ögeler için, `align-self` tek bir ögede yazılır ve kapsayıcıdaki değeri
ezer.

Çıktının ikinci bloğu dört değeri gösteriyor. Satır yüksekliği en uzun ögeyle belirleniyor
(56 birim) ve diğer ikisi bu yüksekliğin içinde konumlanıyor. `flex-start` üste,
`flex-end` alta, `center` ortaya çeker.

Dördüncü değer olan `stretch` diğerlerinden farklıdır ve **varsayılandır**: öge, çapraz
eksendeki ölçüsü bildirilmemişse satırın tamamına **gerdirilir**. Çıktıda üç ögenin de
`0..56` olması budur. Ögeye çapraz eksende bir ölçü bildirilirse gerdirme uygulanmaz;
bildirilen ölçü korunur ve öge çapraz başlangıca hizalanır.

Gerdirmenin pratik değeri, yan yana duran kutuların **eşit yükseklikte** olmasıdır. Farklı
uzunlukta metin taşıyan üç kart, hiçbir yükseklik bildirilmeden aynı boyda görünür; bu,
akış düzeninde ancak sabit yükseklik yazarak elde edilebilirdi.

Beşinci bir değer olan `baseline`, ögeleri kendi ilk metin satırlarının taban çizgisine
göre hizalar. Farklı yazı boyutlarındaki başlıkları yan yana koyarken üst kenar hizası
yerine yazı hizası isteniyorsa bu değer kullanılır.

## Aralık ve Otomatik Boşluk

Ögeler arasındaki mesafe iki yolla verilebilir. Birincisi ögelere dış boşluk yazmaktır ve
ilk ile son ögede istenmeyen kenar boşluğu üretir. İkincisi kapsayıcıya **aralık (gap)**
bildirmektir: `gap` yalnızca ögelerin **arasına** uygulanır, kenarlara dokunmaz.

Yukarıdaki hesapta ara toplamının $16 \times 2 = 32$ olması bundandır: üç öge, iki ara.

İkinci bir araç, ögeye `margin` değeri olarak `auto` yazmaktır. Otomatik dış boşluk, ana
eksendeki boş alanın **tamamını yutar** ve `justify-content` uygulanmadan önce çalışır. Bir
gezinme çubuğunda son ögeyi karşı uca itmenin en doğrudan yolu budur:

```css
/* duzen.css — 1. adım: gezinme çubuğu tek eksende */
.gezinme > ul {
  display: flex;
  gap: 1.5rem;
  align-items: center;
}

.gezinme .istasyon-durumu {
  margin-inline-start: auto;
}
```

`margin-inline-start: auto` bildirimi, durum rozetinden önceki bütün boş alanı o ögeye
verir ve rozet satırın sonuna yapışır. Aynı sonuç `justify-content: space-between` ile de
elde edilebilir, ama o bildirim **bütün** aralara pay dağıtır; burada istenen tek bir
noktada kırılmadır.

Bu dosya, CSS ile Görsel Sunum kursunda kurulan `istasyon.css` dosyasının yanına konur.
Görsel bildirimler orada kalır, düzen bildirimleri burada toplanır; ayrımın gerekçesi
kursun son konusunda ele alınacaktır.

## Satır Kırma

Varsayılan olarak esnek ögeler **tek satırda** kalır; toplam ölçü kapsayıcıyı aşsa bile
yeni satıra geçmez, ögeler daralır. `flex-wrap: wrap` bildirimi bu davranışı değiştirir ve
sığmayan ögeler yeni bir satıra iner.

Satır kırma açıldığında üçüncü bir hizalama bildirimi anlam kazanır: `align-content`,
**satırların** çapraz eksende nasıl dağıtılacağını söyler ve değer kümesi
`justify-content` ile aynıdır. Tek satır varsa bu bildirimin etkisi yoktur.

Buradaki ayrım sık karıştırılır ve tek cümleyle özetlenebilir: `align-items` bir satırın
**içindeki ögeleri**, `align-content` kapsayıcının içindeki **satırları** hizalar.

## Özet

- `display: flex` kutunun kendisini değil çocuklarının yerleştirilme kuralını değiştirir;
  çocuklar bloklaşır, dış boşlukları çökmez ve sarmalanmamış metin anonim öge olur.
- Esnek kutu tek eksenlidir: `flex-direction` ana ekseni belirler, çapraz eksen ona diktir
  ve iki eksen de yazma yönüne göre soyut adlandırılır.
- `justify-content` ana eksendeki boş alanı yerleştirir; `flex-start`, `flex-end` ve
  `center` alanı tek parça bırakır, `space-between`, `space-around` ve `space-evenly` onu
  farklı paylaşım kurallarıyla böler.
- Çapraz eksende varsayılan `stretch` ögeleri satır yüksekliğine gerdirir; hizalama
  değerleri yalnızca çapraz ölçü bildirildiğinde ya da gerdirme kapatıldığında görünür.
- `gap` yalnızca aralara uygulanır, `margin: auto` ana eksendeki boş alanın tamamını yutar
  ve dağıtım bildiriminden önce çalışır.

## Sonraki Adım

Bu dersin hesabında ögelerin ana eksendeki ölçüleri sabit alındı ve boş alan hep artı
çıktı. Gerçek bir düzende ölçüler içerikten gelir ve kapsayıcı daraldığında boş alan eksiye
düşer. O durumda hangi öge ne kadar daralır, fazla alan hangi ögeye gider? Sonraki ders bu
paylaşımı yöneten üç bildirimi ve aritmetiğini ele alır.
