Ders 01 / 23
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.
İçindekiler
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:
- Çocukların
displaydeğeri bloklaştırılır. Birspançocuk, satır içi kutu olmaktan çıkar ve esnek öge olur; genişlik ve dikey dış boşluk alabilir. - 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.
- 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.
// 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-betweeniki uca hiç pay ayırmaz, alanı ögeler arasına eşit böler: birim ek boşluk.space-aroundher ögeye kendi payını verir, pay ögenin iki yanına yarımlanır: ; kenarlarda yarım pay , aralarda iki yarım pay bitişir ve olur.space-evenlybütün boşlukları eşitler: 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 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:
/* 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: flexkutunun 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-directionana ekseni belirler, çapraz eksen ona diktir ve iki eksen de yazma yönüne göre soyut adlandırılır. justify-contentana eksendeki boş alanı yerleştirir;flex-start,flex-endvecenteralanı tek parça bırakır,space-between,space-aroundvespace-evenlyonu 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. gapyalnızca aralara uygulanır,margin: autoana 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.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.