Önkoşullar ve Kapsam
Bu rehber, HTML ve CSS temellerini bilen, display: flex ve display: grid ile en az bir kez çalışmış orta seviye geliştiriciler için yazıldı. Burada anlatılan özellikler (Flexbox ve CSS Grid Layout) W3C tarafından standartlaştırılmıştır ve tüm güncel tarayıcılarda desteklenir. Belirli bir sürüm numarasına bağlı değildir; kod örnekleri tarayıcı desteği açısından olgun özellikleri kullanır.
Amaç, iki modeli birbirinin alternatifi gibi değil, birlikte çalışan araçlar olarak kullanmaktır. Yanlış soru "Hangisi daha iyi?" değil, "Bu katmanda hangisi doğru araç?" sorusudur.
İki Model Arasındaki Temel Fark
Flexbox tek boyutlu bir yerleşim modelidir: bir satır ya da bir sütun boyunca öğeleri dağıtır. Grid ise iki boyutludur: satır ve sütunları aynı anda tanımlar.
Pratik ayrım şudur:
- İçeriğin boyutu yerleşimi belirliyorsa (buton grubu, etiket listesi, kart içi hizalama) Flexbox uygundur.
- Yerleşimin yapısı içerikten bağımsızsa (sayfa iskeleti, kart ızgarası, dashboard panelleri) Grid uygundur.
Bu ayrım kesin bir kural değil, bir başlangıç noktasıdır. Gerçek projelerde ikisi iç içe kullanılır.
Adım 1: Grid ile Sayfa İskeletini Kurma
Karmaşık bir sayfa tasarımı genellikle bir dış iskeletle başlar. Aşağıdaki örnek, başlık, kenar çubuğu, ana içerik ve alt bilgi içeren klasik bir düzeni tanımlar:
.layout {
display: grid;
grid-template-columns: 240px 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
min-height: 100vh;
gap: 16px;
}
.layout > header { grid-area: header; }
.layout > aside { grid-area: sidebar; }
.layout > main { grid-area: main; }
.layout > footer { grid-area: footer; }
Beklenen davranış: 1fr birimi, kalan boş alanı orantılı olarak doldurur. min-height: 100vh ile ızgara en az görünüm yüksekliği kadar olur; 1fr satırı bu durumda esner. grid-template-areas sayesinde HTML'deki sıralama değişse bile yerleşim bozulmaz — bu, erişilebilirlik açısından önemlidir çünkü okuma sırası ile görsel sırayı ayrıştırmanıza olanak tanır.
grid-template-areas kullanırken alan adlarının dikdörtgen oluşturması gerekir. Aşağıdaki gibi L şeklinde bir alan geçersizdir:
/* Geçersiz: "main" alanı dikdörtgen değil */
grid-template-areas:
"header header"
"sidebar main"
"main footer";
Adım 2: Esnek Kart Izgarası İçin auto-fit ve minmax
Sabit sütun sayısı yerine, kapsayıcı genişliğine göre uyum sağlayan bir kart ızgarası için:
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 16px;
}
Beklenen davranış: Her sütun en az 240px, en fazla kalan alanı paylaşacak şekilde genişler. Kapsayıcı daraldıkça sütun sayısı azalır; genişledikçe artar. auto-fit boş sütunları çözer, auto-fill ise boş sütunları korur. Fark, az sayıda kart olduğunda kartların tüm genişliği doldurup doldurmamasında ortaya çıkar.
minmax(240px, 1fr) içindeki 240px değeri bir "sihirli sayı" değildir; içeriğinizin gerçekten sığması gereken minimum genişliğe göre belirlenmelidir.
Adım 3: Grid Öğelerini Açıkça Yerleştirme
İskelet dışında, tek tek öğeleri satır ve sütun çizgileriyle yerleştirmek gerekebilir. Çizgi numaraları 1'den başlar:
.feature {
grid-column: 2 / 4; /* 2. çizgiden 4. çizgiye kadar */
grid-row: 1 / 3;
}
Negatif indeksler sondan sayar: -1 son çizgiyi belirtir. Bu, span anahtar sözcüğüyle birlikte kullanıldığında daha okunabilir olabilir:
.feature {
grid-column: 2 / span 2;
}
Adım 4: Flexbox ile Bileşen İçi Hizalama
Sayfa iskeleti Grid ile kurulduktan sonra, tek tek bileşenlerin içi genellikle Flexbox ile düzenlenir. Örneğin bir kart başlığı ve meta bilgisini iki uca yaslamak:
.card-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
}
.card-header .title {
flex: 1 1 auto;
min-width: 0; /* taşmayı önler */
}
Beklenen davranış: flex: 1 1 auto başlığın büyüyüp küçülmesini sağlar. min-width: 0 kritik bir ayrıntıdır: Flex öğelerinin varsayılan min-width: auto değeri, uzun metinlerin kapsayıcıyı taşırmasına neden olur. min-width: 0 verildiğinde text-overflow: ellipsis gibi kırpma davranışları düzgün çalışır.
Adım 5: İki Modeli İç İçe Kullanma
Gerçek tasarımlarda Grid ve Flexbox birbirinin içinde yer alır. Aşağıdaki örnekte dış katman Grid, kartın içi Flexbox'tır:
.dashboard {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 20px;
}
.widget {
display: flex;
flex-direction: column;
gap: 8px;
}
.widget .body {
flex: 1; /* alt bilgiyi en alta iter */
}
Beklenen davranış: .widget sütun yönünde esner; .body kalan alanı kaplar, böylece kart altbilgisi tüm kartlarda aynı hizada kalır. Bu, "kart yüksekliklerini eşitleme" probleminin yaygın çözümüdür.
Yaygın Hatalar
1. 1fr yerine 100% kullanmak. Grid içinde 100% kapsayıcı genişliğini ifade eder ve gap ile birlikte taşmaya yol açar. Esnek genişlik için 1fr tercih edilmelidir.
2. grid-auto-flow: dense kullanımını farkında olmadan bırakmak. Bu özellik boşlukları doldurmak için öğelerin görsel sırasını değiştirir. Klavye ve ekran okuyucu kullanıcıları için odak sırası bozulabilir. Bilinçli bir tercih değilse kullanılmamalıdır.
3. Flex öğelerinde min-width: auto tuzağı. Yukarıda değinildiği gibi, uzun içerikli öğelerde taşma yaşanıyorsa ilk kontrol edilecek şey budur.
4. grid-template-areas ile alan adlarını tutarsız yazmak. Alan adları büyük/küçük harfe duyarlıdır ve her satırda aynı sayıda hücre olmalıdır. Yazım hatası sessizce göz ardı edilmez; yerleşim bozulur.
5. Aynı katmanda hem Grid hem Flexbox dayatmak. Bir kapsayıcıya display: grid ve display: flex birlikte verilemez; son tanım kazanır. Hangi katmanın hangi modeli kullandığını netleştirin.
Güvenlik ve Erişilebilirlik Notları
CSS yerleşimi doğrudan bir güvenlik açığı üretmez, ancak iki dolaylı etki vardır:
- Görsel sıra ile DOM sırasını ayrıştırmak (örneğin
order,grid-areaveyadenseile) klavye odak sırasını ve ekran okuyucu okuma sırasını etkiler. Erişilebilirlik için DOM sırası anlamlı olmalıdır. - Kullanıcı tarafından kontrol edilen içerik (örneğin kullanıcı adları) yerleşim kapsayıcılarına yerleştirildiğinde,
min-width: 0ve uygunoverflowkuralları olmadan düzeni bozabilir. Bu bir gizlilik veya enjeksiyon sorunu değildir, ancak savunmacı tasarım gereğidir.
Sonuç
Karmaşık tasarımlarda üretken yaklaşım şudur: yapıyı Grid ile kurun, bileşen içi hizalamayı Flexbox ile çözün. minmax, auto-fit, grid-template-areas ve min-width: 0 gibi araçlar, sabit değerlerle uğraşmadan esnek ve okunabilir yerleşimler yazmanızı sağlar. Modelleri rakip değil, katmanlı bir araç seti olarak kullanın; her katmanda hangi modelin sorumlu olduğunu net tutun.