Sütunlarını ve satırlarını kur, boşlukları ayarla, önizlemedeki hücrelere tıklayarak öğe yerleştir. Izgarayı anında gör, hazır CSS ve HTML kodunu tek tıkla kopyala. Her şey tarayıcında çalışır, hiçbir değer sunucuya gönderilmez.
Bir ayar varsayılan değerinde kaldığı sürece çıktıya yazılmaz, böylece kod gereksiz satırlarla şişmez.
fr birimli satırlar yalnızca kapsayıcının bir yüksekliği olduğunda görünür olur. Bu kaydırıcı sadece önizlemeyi etkiler, çıktıya girmez.
Henüz öğe yok. Önizlemede önce başlangıç hücresine, sonra bitiş hücresine tıkla.
Bir elemana display: grid verdiğinizde o eleman bir ızgara biçimlendirme bağlamı açar. Artık doğrudan çocukları normal akışta alt alta dizilmez; sizin tanımladığınız sütun ve satır şeritlerinin oluşturduğu iki boyutlu bir çizgi ağına oturur. Grid’i Flexbox’tan ayıran nokta budur: Flexbox tek bir eksende dağıtım yapar, Grid iki ekseni aynı anda tanımlar.
Izgaranın iskeleti grid-template-columns ve grid-template-rows ile kurulur. İkisi de boşlukla ayrılmış bir şerit listesi alır ve listedeki her değer bir sütunun ya da satırın boyutudur. Şeritlerin arasında numaralı çizgiler oluşur: üç sütunlu bir ızgarada soldan sağa 1, 2, 3 ve 4 numaralı dört dikey çizgi bulunur. Öğeleri yerleştirirken yazdığınız sayılar da bu çizgilerdir, sütunların kendisi değil. Bu ayrımı bir kez oturttuğunuzda grid-column: 1 / 3 yazımının neden iki sütun kapladığı da netleşir.
Bir şerit sabit bir uzunluk (px, rem), kapsayıcıya oranlı bir yüzde, içeriğe göre büyüyen auto, mümkün olan en dar hâli veren min-content ya da taşmadan sığan en geniş hâli veren max-content olabilir. Bunların hepsi ölçülebilir değerlerdir.
fr ise farklı çalışır ve en çok yanlış anlaşılan birimdir. fr bir uzunluk değil, bir pay katsayısıdır ve kapsayıcının tamamını değil, yalnızca boş alanı paylaştırır. Bu boş alan, esnek olmayan şeritler ve aralarındaki boşluklar düşüldükten sonra geriye kalan yerdir. Yani 200px 1fr 1fr yazdığınızda 1fr’lerin her biri “toplamın yarısı” değil, “200px ve gap’ler çıktıktan sonra kalanın yarısı” kadar yer alır.
minmax(min, max) bir şeride alt ve üst sınır verir. Şerit alt sınırın altına inmez, üst sınırın üstüne çıkmaz, arada içeriğe ve boş alana göre serbestçe hareket eder. Tek başına da işe yarar ama asıl gücü repeat() ile birleştiğinde ortaya çıkar.
Medya sorgusu yazmadan duyarlı bir kart ızgarası isteyen hemen herkes şu satırı kullanır: repeat(auto-fit, minmax(240px, 1fr)). Tarayıcı kapsayıcıya 240px’ten dar olmayan kaç sütun sığdırabileceğini hesaplar, sığdırır ve artan yeri 1fr üzerinden sütunlara dağıtır. Ekran daraldıkça sütun sayısı kendiliğinden azalır.
auto-fit ile auto-fill arasındaki fark yalnızca içerik azken görünür. auto-fill üretilen boş şeritleri ızgarada bırakır, dolayısıyla üç kartınız varken de sekiz sütunluk bir düzen durur ve kartlar sola yaslanır. auto-fit ise boş kalan şeritleri sıfırlar, böylece kalan kartlar genişleyip satırı doldurur. Kartların büyümesini istiyorsanız auto-fit, sütun hizasının sabit kalmasını istiyorsanız auto-fill doğru tercihtir.
Bir öğeyi yerleştirmenin iki yolu var. Birincisi çizgi numarası: grid-column: 2 / 4 öğeyi 2. dikey çizgiden 4. dikey çizgiye kadar uzatır. span anahtar kelimesiyle “nereden başlarsa başlasın iki sütun kaplasın” da diyebilirsiniz.
İkincisi grid-template-areas: kapsayıcıda düzeni isimlerden oluşan bir şema olarak çizersiniz, sonra her çocuğa grid-area ile bir isim verirsiniz. Sayfa iskeleti gibi az sayıda ve anlamlı bölgeden oluşan düzenlerde bu yöntem CSS’i okunur hâle getirir; düzeni değiştirmek için tek yapmanız gereken şemayı yeniden yazmaktır. Buna karşılık kart listesi gibi tekrar eden ve sayısı belirsiz içeriklerde alan adları hızla hantallaşır, orada çizgi numarası daha pratiktir.
Tanımladığınız şeritlerden daha fazla öğe koyduğunuzda tarayıcı kendiliğinden yeni şeritler üretir. Bunlara örtük şerit denir ve boyutları varsayılan olarak auto’dur. Yüksekliklerini kendiniz belirlemek isterseniz grid-auto-rows kullanın; yeni öğelerin satır yerine sütun açmasını isterseniz grid-auto-flow: column yazın.
grid-auto-flow: dense ise farklı boyutlardaki öğelerin bıraktığı delikleri, sonradan gelen küçük öğeleri geri alarak doldurur. Görsel boşlukları kapatır ama öğelerin görsel sırasını DOM sırasından ayırır, bu da klavyeyle gezinen ve ekran okuyucu kullanan kişiler için kafa karıştırıcı olabilir. Sırası önemsiz galerilerde rahatça kullanılır, okunması gereken içerikte kaçınmakta fayda var.
İki eksen var: justify-* satır içi ekseni yani yatayı, align-* blok eksenini yani dikeyi kontrol eder. İki de kapsam var: *-items her öğeyi kendi hücresinin içinde hizalar, *-content ise şerit kümesinin tamamını kapsayıcının içinde hizalar. Bu ikincisi yalnızca şeritler kapsayıcıdan küçük kaldığında bir şey yapar; sütunlarınız 1fr ise ortada boş alan kalmadığı için justify-content hiçbir etki yaratmaz. Aracın çıktısında varsayılan değerde kalan hizalama satırlarının hiç yazılmamasının sebebi de bu: yazılmayan bir satır okuyana yanlış bir şey ima etmez.
| Konu | CSS Grid | Flexbox |
|---|---|---|
| Eksen | Satır ve sütun birlikte | Tek eksen |
| Düzeni kim kurar | Kapsayıcı, önceden | Öğeler, içeriğe göre |
| Tipik iş | Sayfa iskeleti, kart ızgarası, tablo benzeri düzen | Araç çubuğu, buton grubu, etiket dizisi |
| Hizalama | İki eksende birden | Ana eksende dağıtım, çapraz eksende hizalama |
| Öğe sayısı belirsizse | auto-fit ile şerit sayısı kendi ayarlanır | wrap ile öğeler alt satıra iner |
Pratik kural şu: dış çerçeveyi Grid ile kurun, çerçevenin içindeki küçük ve tek eksenli grupları Flexbox ile dizin. İkisi rakip değil, iç içe kullanılan iki katmandır.
Renk geçişli bir arka planla birlikte çalışıyorsanız CSS gradyan oluşturucu aracıyla üretilen değeri doğrudan buradaki kapsayıcıya uygulayabilirsiniz.
Kaç sütun ve kaç satır istediğini gir, sonra her şeridin birimini tek tek seç: fr, px, yüzde, auto, min-content, max-content ya da minmax. Şeritler birbirinin aynısıysa araç çıktıyı kendiliğinden repeat() ile kısaltır.
row-gap ve column-gap kaydırıcılarını sürükle; iki değer eşitken çıktıya tek satırlık gap kısaltması yazılır. justify ve align seçimlerinden varsayılanda kalanlar koda hiç eklenmez, böylece CSS gereksiz satırlarla şişmez.
Önizlemede önce başlangıç hücresine, sonra bitiş hücresine tıkla; aradaki dikdörtgen bir grid öğesine dönüşür. Her öğeye ad ve renk verebilir, listeden tek tıkla silebilirsin.
Kapsayıcı kuralı ve her öğe için ayrı kural anında yazılır, yanındaki HTML bloğu da aynı sınıf adlarını kullanır. İki paneli ayrı ayrı kopyalayıp projene olduğu gibi yapıştırabilirsin.
fr, kapsayıcının toplam genişliğinin değil, boş alanın payıdır. Tarayıcı önce esnek olmayan şeritleri (px, %, auto, min-content gibi) ve bütün gap değerlerini düşer, geriye kalanı fr katsayılarına göre paylaştırır. Bu yüzden 200px 1fr 1fr yazdığınızda iki esnek sütun toplamın yarısını değil, 200px ve boşluklar çıktıktan sonra kalanın yarısını alır.
İkisi de kapsayıcıya kaç şerit sığdığını hesaplar. Fark, öğe sayısı şerit sayısından azken ortaya çıkar: auto-fill boş şeritleri ızgarada bırakır, öğeler sola yaslanır ve sağda boşluk kalır. auto-fit boş şeritleri sıfıra indirir, dolayısıyla var olan öğeler genişleyip satırı doldurur. Kartların büyümesini istiyorsanız auto-fit, sütun hizasının değişmemesini istiyorsanız auto-fill seçin.
Neredeyse her zaman sebebi şudur: 1fr aslında minmax(auto, 1fr) anlamına gelir ve auto alt sınırı şeridin içeriğinden dar olmasını engeller. İçinde bölünemeyen uzun bir metin, geniş bir tablo ya da overflow: auto verilmiş bir kutu varsa sütun kapsayıcıyı aşar. Şeridi minmax(0, 1fr) yapın ya da içerideki öğeye min-width: 0 verin.
İkisi de aynı sonucu üretir, seçim okunabilirlikle ilgilidir. Sayfa iskeleti gibi az sayıda ve isimlendirilebilir bölgeden oluşan düzenlerde grid-template-areas, CSS’e düzenin resmini çizdiği için daha anlaşılırdır ve düzeni değiştirmek şemayı yeniden yazmaktan ibarettir. Uzunluğu belli olmayan kart listelerinde ise alan adları hantallaşır; orada çizgi numarası ve span daha kullanışlıdır.
justify-items her öğeyi kendi hücresinin içinde yatay olarak hizalar. justify-content ise şeritlerin tamamını tek bir blok gibi alıp kapsayıcının içinde hizalar. İkincisi yalnızca şeritler kapsayıcıdan dar kaldığında bir şey yapar; sütunlarınız fr ile tanımlıysa artan alan kalmadığı için hiçbir etkisi görünmez. Dikey karşılıkları align-items ve align-content’tir.
Hayır. gap yalnızca şeritlerin arasına boşluk koyar: ızgaranın dış kenarında boşluk üretmez ve ilk öğeden önce, son öğeden sonra bir şey eklemez. margin ise öğenin kendisine aittir, komşusuyla çakışabilir ve son öğede istemediğiniz bir boşluk bırakır. Izgaranın çevresinde boşluk istiyorsanız kapsayıcıya padding verin.
Hayır, ikisi farklı işler için var. Grid iki boyutlu bir düzeni kapsayıcı tarafında önceden tanımlar; sayfa iskeleti, kart ızgarası ve tablo benzeri yerleşimler onun alanıdır. Flexbox tek eksende çalışır ve düzeni öğelerin içeriğine bırakır; araç çubuğu, buton grubu ve etiket dizisi gibi işlerde daha uygundur. Yaygın pratik dış çerçeveyi Grid ile kurup içindeki küçük grupları Flexbox ile dizmektir.