Bölüm 9 / 20
Flexbox
Tek boyutlu yerleşim.
13 dakikalık okuma
Flexbox'tan önce yerleşim, aslında yerleşim için tasarlanmamış
araçlarla yapılırdı: kayan ögeler (float), satır içi bloklar, negatif kenar boşlukları ve
tablolar. Hepsinin ortak sorunu, dikey ortalamak ya da kalan boşluğu paylaştırmak gibi basit
isteklerin hileye dönüşmesiydi. Flexbox bu işi doğrudan yapar: bir eksende ögeleri
dizer, kalan boşluğu dağıtır, sığmayanı daraltır. Bu ders yalnız özellik listesi değil;
hangi özelliğin hangi eksende çalıştığını, flex: 1 yazınca ne olduğunu ve
Flexbox'ın en çok zaman kaybettiren üç tuzağını anlatıyor.
01Ne öğreneceksin
- Ana eksen / çapraz eksen ayrımı — Flexbox'ın tamamı bu ikisine dayanır
- Kapsayıcı özellikleri:
flex-direction,flex-wrap,justify-content,align-items,align-content,gap - Öge özellikleri:
flex-grow,flex-shrink,flex-basis,align-self,order flex: 1gerçekte ne demek;flex-basisilewidthfarkı- Tuzak 1:
min-width: autoyüzünden daralmayan öge ve taşan metin - Tuzak 2:
orderDOM sırasını değiştirmez — klavye ve ekran okuyucu sırası bozulur - Tuzak 3:
align-itemsilealign-contentkarışıklığı margin: autoile boşluk yutma; satır içi boşluk sorununun bitmesi- Gerçek kalıplar: üst bar, eşit yükseklikli kartlar, ekrana yapışan altbilgi
- Flexbox mı Grid mi — karar ölçütü
02Tek boyut fikri ve iki eksen
Bir ögeye display: flex verdiğin anda o öge flex kapsayıcısı,
doğrudan çocukları flex ögesi olur. Kapsayıcı çocukları tek bir eksende dizer.
"Tek boyutlu" olması budur: Flexbox ya bir satırla ya bir sütunla ilgilenir; satırlar arası
hizalamayı (yani ızgarayı) Grid yapar.
.kapsayici { display: flex; } /* blok düzeyinde kapsayıcı */
.kapsayici { display: inline-flex; } /* metin akışında duran kapsayıcı */
Her şey iki eksene göre tanımlanır:
flex-direction | Ana eksen | Çapraz eksen |
|---|---|---|
row (varsayılan) | Yatay → | Dikey ↓ |
row-reverse | Yatay ← | Dikey ↓ |
column | Dikey ↓ | Yatay → |
column-reverse | Dikey ↑ | Yatay → |
Ezberlenecek tek kural: justify-content her zaman ana eksende,
align-items her zaman çapraz eksende çalışır. Yani
flex-direction: column yazdığın anda ikisinin yönü yer değiştirir —
"neden ortalanmıyor" sorularının çoğunun cevabı budur.
/* Yatay dizilim: yatayda ortala, dikeyde ortala */
.a { display: flex; justify-content: center; align-items: center; }
/* Dikey dizilim: AYNI kod, artık justify DİKEYDE, align YATAYDA çalışır */
.b { display: flex; flex-direction: column; justify-content: center; align-items: center; }
Flexbox'ın hemen fark edilen bir yan faydası daha var: 2. derste gördüğün satır içi
ögeler arasındaki gizemli boşluk (kaynak kodundaki satır sonunun görünür bir boşluğa
dönüşmesi) flex kapsayıcısında ortadan kalkar. Flex ögeleri arasındaki mesafe yalnız
gap ve kenar boşluklarıyla belirlenir; işaretlemedeki girintiler etkisizdir.
Aynı şekilde flex çocuklarında kenar boşluğu çökmesi de olmaz (8. ders).
03Kapsayıcı özellikleri
.kapsayici {
display: flex;
flex-direction: row; /* ana ekseni seç */
flex-wrap: wrap; /* sığmayanlar alt satıra geçsin */
gap: 1rem; /* ögeler arası boşluk — satır ve sütun */
gap: 1rem 2rem; /* satır arası | sütun arası */
justify-content: flex-start; /* ANA eksende dağıtım */
align-items: stretch; /* ÇAPRAZ eksende hizalama (tek satır) */
align-content: flex-start; /* ÇAPRAZ eksende SATIRLARIN dağıtımı (çok satır) */
}
justify-content | Ne yapar |
|---|---|
flex-start / flex-end | Başa / sona yasla |
center | Ortala |
space-between | İlk başta, son sonda; aralar eşit |
space-around | Her ögenin iki yanına eşit pay — kenarlar yarım görünür |
space-evenly | Kenarlar dâhil tüm boşluklar eşit |
align-items | Ne yapar |
|---|---|
stretch (varsayılan) | Çapraz eksende kapsayıcıyı doldurur — kartların eşit yükseklikte olmasının sebebi budur |
flex-start / flex-end | Üste / alta yasla |
center | Ortala |
baseline | Metin taban çizgilerini hizala — farklı yazı boyutlarında etiket–değer hizalamak için |
align-items ile align-content ayrımı en sık karıştırılan
konudur: align-items bir satırın içindeki ögeleri hizalar,
align-content ise satırların kendisini dağıtır ve yalnızca
flex-wrap: wrap varken ve birden çok satır oluştuğunda etkilidir. Tek
satır varsa align-content yazmanın hiçbir etkisi olmaz.
gap, kenar boşluğuyla boşluk vermeye göre çok daha temizdir: son ögeden sonra
fazladan boşluk kalmaz, :last-child istisnası yazmana gerek olmaz ve sarma
olduğunda satır araları da otomatik ayarlanır.
04Öge özellikleri: flex kısayolu
.oge {
flex-grow: 0; /* kalan boşluktan pay al mı? kaç birim? */
flex-shrink: 1; /* yer yetmezse daralsın mı? ne oranda? */
flex-basis: auto; /* dağıtımdan ÖNCEKİ başlangıç boyutu */
flex: 0 1 auto; /* üçünün kısayolu — VARSAYILAN budur */
}
Üç yaygın kısayol ve gerçek karşılıkları:
| Yazım | Açılımı | Anlamı |
|---|---|---|
flex: 1 | 1 1 0% | Kalan boşluğu paylaş, başlangıç boyutunu yok say → eşit genişlikte sütunlar |
flex: auto | 1 1 auto | Büyü ve daral, ama içerik boyutundan başla → içeriği çok olan daha geniş olur |
flex: none | 0 0 auto | Ne büyü ne daral — sabit ögeler (simge, logo) |
flex: 0 0 200px | — | Sabit 200 px genişlik; kenar çubukları için |
flex: 1 ile flex: auto farkı mülakat sorusudur ve pratikte
görünür: üç kutuya flex: 1 verirsen içeriği ne olursa olsun tam eşit
genişlikte olurlar (çünkü flex-basis: 0 ile herkes sıfırdan başlar, kalan boşluk
eşit bölünür). flex: auto verirsen uzun metinli kutu daha geniş olur (herkes
kendi içerik boyutundan başlar, yalnız kalan boşluk eşit bölünür).
flex-basis ana eksendeki boyutu belirler ve width'i
ezer (dikey dizilimde height'ı). İkisini birden yazmak yaygın bir
karışıklık kaynağıdır; flex-basis varsa width yalnızca
flex-basis: auto olduğunda devreye girer.
/* Klasik üç sütun: kenar çubukları sabit, orta esner */
.duzen { display: flex; gap: 1rem; }
.yan-menu { flex: 0 0 240px; }
.icerik { flex: 1; min-width: 0; } /* min-width: 0 — aşağıdaki tuzak */
.yan-bilgi { flex: 0 0 300px; }
05Üç tuzak
Tuzak 1: min-width: auto — daralmayan öge
Flex ögelerinin varsayılan min-width değeri auto'dur, yani
içeriklerinden daha dar olamazlar. flex-shrink: 1 yazmış olsan bile bu
sınır geçerlidir. Sonuç:
.kutu { flex: 1; }
/* İçinde uzun bir URL, geniş bir tablo ya da <pre> bloğu varsa
kutu daralmaz — kapsayıcıyı zorlar ve SAYFADA YATAY KAYDIRMA çıkar. */
.kutu { flex: 1; min-width: 0; } /* çözüm */
.kutu { flex: 1; overflow: hidden; } /* alternatif (kırpar) */
Bu, Flexbox'ta en çok zaman kaybettiren tek satırdır. Belirtisi hep aynıdır: "yan yana iki
kutum var, içine uzun bir şey koyunca düzen bozuluyor." Dikey dizilimde karşılığı
min-height: 0'dır ve kaydırılabilir bir liste yaparken aynı biçimde gerekir.
Tuzak 2: order ile görsel sıra
.oge { order: 0; } /* varsayılan; küçükten büyüğe dizilir, negatif olabilir */
order ögelerin görsel sırasını değiştirir; DOM sırasını
değiştirmez. 5. derste "DOM sırası = okuma sırasıdır" demiştik — burası o kuralın
kırıldığı yerdir:
- Klavye hâlâ DOM sırasını izler. Gözle 1-2-3 gördüğün düğmeler arasında Tab ile 3-1-2 sırasıyla gezersin.
- Ekran okuyucu hâlâ DOM sırasını okur; görsel sırayla anlatılan bir içerik (önce başlık, sonra açıklama) sesli olarak ters gelir.
- Metin seçme ve kopyalama da DOM sırasına göre çalışır.
Bu WCAG 1.3.2 ("anlamlı sıra") ve 2.4.3 ("odak sırası") ölçütlerini ihlal edebilir. Kural:
order ve row-reverse yalnız görsel önemi olmayan, sırası anlam
taşımayan durumlarda kullanılır. İçerik sırası önemliyse çözüm işaretlemeyi doğru sırada
yazmak ve gerekiyorsa Grid ile yerleştirmektir — Grid'de de aynı tuzak
grid-area ile mevcuttur (10. ders).
Tuzak 3: margin: auto boşluğu yutar
Flex kapsayıcısında auto kenar boşluğu kalan tüm boşluğu emer. Bu bir
hile değil, tanımlı davranıştır ve justify-content'ten daha esnektir:
/* Üst barda: logo solda, GERİSİ sağda */
.ustbar { display: flex; align-items: center; gap: 1rem; }
.logo { margin-right: auto; }
/* Bir ögeyi hem yatay hem dikey ortala */
.oge { margin: auto; }
Dikkat: margin: auto boşluğu emdiği için justify-content'in
etkisini ortadan kaldırır — dağıtılacak boşluk kalmaz. İkisini birlikte kullanıp
"çalışmıyor" demek yaygındır.
06Gerçek kalıplar
/* 1. Üst bar: marka solda, menü sağda, dikey ortalı */
.ustbar { display: flex; align-items: center; gap: 1rem; }
.marka { margin-right: auto; }
/* 2. Ekrana yapışan altbilgi: içerik azken bile altbilgi en altta */
body { min-height: 100dvh; display: flex; flex-direction: column; }
main { flex: 1; }
/* 3. Eşit yükseklikli kartlar + alta yaslı düğme */
.liste { display: flex; flex-wrap: wrap; gap: 1rem; }
.kart { flex: 1 1 260px; display: flex; flex-direction: column; }
.kart p { flex: 1; } /* metin büyür, düğmeyi aşağı iter */
/* 4. Medya nesnesi: solda simge, sağda esneyen metin */
.medya { display: flex; gap: .75rem; align-items: flex-start; }
.medya img { flex: none; width: 48px; }
.medya div { flex: 1; min-width: 0; }
/* 5. Etiket-değer hizalama: farklı yazı boyutlarında taban çizgisi */
.olcum { display: flex; align-items: baseline; gap: .5rem; }
Üçüncü kalıptaki flex: 1 1 260px özellikle işe yarar: kartlar en az 260 px
olmaya çalışır, sığmazsa alt satıra geçer, kalan boşluğu paylaşır. Bu, medya sorgusu
yazmadan duyarlı bir kart ızgarası verir — ama son satırdaki kartlar geride kalanları
paylaştığı için farklı genişlikte olur. Son satırın da eşit olmasını istiyorsan
Flexbox yetmez; Grid gerekir.
Flexbox mı, Grid mi
Flexbox içerikten yerleşime, Grid yerleşimden içeriğe çalışır. Ölçüt: ögelerin boyutunu içerikleri belirlesin ve tek bir eksende dizilsinler istiyorsan Flexbox; satır ve sütun hizalaması gereken, hücre boyutlarını sen belirlediğin bir düzen istiyorsan Grid. Pratik ayrım: üst bar, düğme grubu, etiket-değer satırı, bir kartın iç dizilimi → Flexbox. Sayfa iskeleti, kart ızgarası, form etiket-alan hizalaması, gerçekten iki boyutlu her şey → Grid. İkisi rakip değildir; tipik bir sayfada dış iskelet Grid, iç bileşenler Flexbox olur ve bu en yaygın birleşimdir.
07Mini alıştırma — Flexbox'ı sınırlarına kadar zorla
Yaklaşık 20 dakika · tek HTML dosyası + DevTools flex denetleyicisi
- Kur: beş kutulu bir flex kapsayıcısı yaz. DevTools'ta kapsayıcının yanındaki
flexrozetine tıklayıp görsel denetleyiciyi aç. - Eksen değişimi:
justify-content: center; align-items: centerver; sonraflex-direction: columnekle. Ne değişti, neden? - Dağıtım:
space-between,space-aroundvespace-evenlyarasında geçiş yap. Kenarlardaki boşlukları ölç. - Varsayılan
stretch: kutuların içine farklı uzunlukta metin koy — yükseklikleri neden eşit?align-items: flex-startyapıp farkı gör. flex: 1vsauto: üç kutuya farklı uzunlukta metin koy, sıraylaflex: 1veflex: autouygula. Genişlikleri ölç.- Sabit + esnek:
flex: 0 0 240pxbir kenar çubuğu veflex: 1bir içerik alanı yap. Pencereyi daralt — hangisi daraldı? - Tuzak 1: içerik alanına çok uzun bir URL yapıştır. Yatay kaydırma çıktı mı?
min-width: 0ekleyip tekrarla. - Sarma:
flex-wrap: wrapveflex: 1 1 260pxile kart listesi yap. Pencereyi daraltıp kaç sütuna düştüğünü izle. Son satırdaki kartlar diğerleriyle aynı genişlikte mi? align-content: çok satırlı sarmalı listedealign-content: centerdene (kapsayıcıya yükseklik vererek). Tek satıra düşürdüğünde etkisi kayboluyor mu?margin: auto: üst bar kalıbını kur; logoyamargin-right: autover. Sonra kapsayıcıyajustify-content: space-betweenekle — bir şey değişti mi?- Tuzak 2: üç düğmeye
order: 3, 1, 2ver. Gözle sırayı doğrula, sonra yalnız klavyeyle Tab'la. Odak hangi sırayla gezdi? - Eşit yükseklikli kart + alta yaslı düğme: 3. kalıbı uygula; bir kartın metnini uzatıp düğmelerin hizada kaldığını doğrula.
- Yapışan altbilgi: 2. kalıbı kur ve sayfada tek bir paragrafla test et. Altbilgi ekranın altında mı?
- Satır içi boşluk: üç
<span>'i alt alta satırlara yazıp normal akışta göster — aralarında boşluk var mı? Kapsayıcıyı flex yapıp tekrar bak.
08Kendini sına
justify-content ile align-items farkı nedir? flex-direction: column olunca ne değişir?
justify-content ana eksende,
align-items çapraz eksende hizalar. Ana ekseni
flex-direction belirler: row'da ana eksen yatay, çapraz eksen
dikeydir; column'da ikisi yer değiştirir — artık
justify-content dikeyde, align-items yatayda çalışır. Bu yüzden
aynı kodu column'a çevirdiğinde "ortalama bozuldu" hissi olur; bozulan bir şey
yoktur, eksenler dönmüştür. Üçüncü bir özellik daha vardır ve karıştırılır:
align-content tek tek ögeleri değil satırların kendisini çapraz eksende
dağıtır ve yalnızca flex-wrap: wrap ile birden çok satır oluştuğunda
etkilidir — tek satırda yazmanın hiçbir etkisi olmaz. Son olarak
align-items'ın varsayılanı stretch'tir; yan yana kartların
içerikleri farklı olduğu hâlde eşit yükseklikte görünmesinin sebebi budur.
flex: 1 ne anlama gelir? flex: auto'dan farkı nedir?
flex, üç özelliğin kısayoludur:
flex-grow flex-shrink flex-basis. flex: 1 =
1 1 0% — "büyü, daral ve başlangıç boyutunu sıfır say". Herkes sıfırdan
başladığı için kapsayıcının tüm genişliği eşit bölünür; içeriği uzun olan kutu da
kısa olan kadar yer kaplar, yani tam eşit sütunlar elde edersin.
flex: auto = 1 1 auto — "büyü, daral, ama içerik
boyutundan başla". Önce her öge kendi doğal genişliğini alır, yalnız kalan
boşluk eşit paylaşılır; sonuçta uzun metinli kutu daha geniş olur.
flex: none = 0 0 auto ise ögeyi hiç esnetmez (logo, simge, sabit
kenar çubuğu). Bir ayrıntı: flex-basis ana eksende width'i
ezer, dolayısıyla ikisini birlikte yazmak karışıklık üretir. Ve dikkat:
flex: 1 yazmak ögenin gerçekten daralacağını garanti etmez — varsayılan
min-width: auto yüzünden öge içeriğinden dar olamaz; bunun için
min-width: 0 gerekir.
Flexbox'ta bir öge flex-shrink: 1 olmasına rağmen daralmıyor. Neden?
Çünkü flex ögelerinin varsayılan min-width değeri
auto'dur ve bu, ögenin kendi içeriğinin en küçük boyutundan daha
dar olamayacağı anlamına gelir. İçeride kırılamayan uzun bir kelime, bir URL, geniş bir
tablo ya da bir <pre> bloğu varsa taban boyut büyük olur ve daralma
oradan sonra durur. Belirtisi tipiktir: yan yana iki kutu düzgün çalışırken içine uzun bir
şey konduğunda kapsayıcı taşar ve sayfada yatay kaydırma çubuğu çıkar. Çözüm daraması
gereken ögeye min-width: 0 yazmaktır (dikey dizilimde
min-height: 0); alternatif olarak overflow: hidden ya da
auto da taban boyutu sıfırlar ama içeriği kırpar ya da kendi kaydırma
bağlamını açar. Metnin kendisi taşıyorsa ayrıca overflow-wrap: break-word
eklenir. Bu, Flexbox'ta en çok zaman kaybettiren tek satırdır ve Grid'de de aynı davranış
(minmax(0, 1fr) ihtiyacı) olarak karşına çıkar.
order özelliğini kullanmanın sakıncası nedir?
order yalnızca görsel sırayı değiştirir; DOM
sırasına dokunmaz. Buna bağlı olan her şey eski sırada kalır: klavye odak sırası
(gözle 1-2-3 gördüğün düğmeler arasında Tab ile başka bir sırayla gezersin), ekran
okuyucu okuma sırası, metin seçme ve kopyalama sırası. Bu, WCAG 1.3.2 ("anlamlı sıra")
ve 2.4.3 ("odak sırası") ölçütlerini ihlal edebilir — özellikle bir formda alanların ya da
bir gezinmede bağlantıların sırası değiştirildiğinde kullanıcı ciddi biçimde kaybolur.
Aynı sakınca row-reverse/column-reverse ve Grid'de
grid-area ile yerleştirme için de geçerlidir. Kural: sırası anlam taşıyan
içerikte kullanma; doğru çözüm işaretlemeyi baştan doğru sırada yazmak, gerekiyorsa
yerleşimi Grid ile kurmaktır. order'ın meşru kullanımı, sırası önemsiz görsel
ögelerde ya da dar ekranda tamamen dekoratif bir bloğu öne/arkaya almakta kalır — ve o
durumda bile klavye turuyla doğrulanmalıdır.
09Sınav köşesi
Yazılıda nasıl sorulur
(1) Flexbox nedir, hangi problemi çözer? (2) Ana eksen ve çapraz eksen kavramları.
(3) justify-content değerlerini sayınız. (4) align-items ile
align-content farkı. (5) flex-grow, flex-shrink,
flex-basis ne yapar; flex: 1 neye eşittir?
(6) flex-wrap ne işe yarar? (7) Bir ögeyi yatay ve dikey ortalamanın yolları.
(8) order özelliği ve sakıncası. (9) Flexbox ile Grid farkı, hangisi ne zaman?
(10) gap ile margin ile boşluk vermenin farkı.
(11) Uygulamalı: "üstte logo solda menü sağda bir bar yapınız."
Sözlüde nasıl anlatılır — 2 dakikalık taslak
Düzen: (1) Tanım — "Flexbox tek boyutlu yerleşim modelidir: ögeleri bir eksende dizer,
kalan boşluğu dağıtır, sığmayanı daraltır. Ondan önce bu işler float ve negatif kenar
boşluğu hileleriyle yapılıyordu." (2) Model — "her şey ana eksen ve çapraz eksene göre
tanımlıdır; justify-content ana eksende, align-items çapraz
eksende çalışır ve column yazdığın anda ikisi yer değiştirir."
(3) Kısayol — "flex: 1 aslında 1 1 0%'tir; eşit sütunlar verir.
flex: auto içerik boyutundan başladığı için eşit vermez —
bu ikisini karıştırmak yaygın bir hatadır." (4) Kıdem vuruşu — "flex ögelerinin
varsayılan min-width değeri auto'dur; içinde uzun bir URL ya da
tablo olan kutu daralmaz ve sayfa yatay kayar. Bunu min-width: 0 ile
çözerim; bu Flexbox'ta en çok zaman kaybettiren satırdır."
(5) Erişilebilirlik ve karar — "order görsel sırayı değiştirir ama klavye ve
ekran okuyucu DOM sırasını izler, bu yüzden sırası anlamlı içerikte kullanmam. Tek eksen
ve içeriğe göre boyut varsa Flexbox, satır–sütun hizalaması gerekiyorsa Grid seçerim;
tipik sayfada dış iskelet Grid, iç bileşenler Flexbox olur."
