CSS grid, satırları ve sütunları aynı anda kontrol eden iki boyutlu bir yerleşim modelidir. Bir öğeye display: grid verdiğinizde o öğe grid kapsayıcı, doğrudan çocukları da grid öğesi olur; sütunları grid-template-columns, satırları grid-template-rows ile tanımlar, aralarına gap ile boşluk koyarsınız. Esnek sütunlar için grid'e özgü fr birimi, tekrar eden izler için de repeat() fonksiyonu kullanılır.

Bu yazı grid'in temel kavramlarını anlatır: kapsayıcı, iz, çizgi, hücre ve alan; sabit ve esnek iz boyutları; fr hesabı; repeat(); açık ve örtük grid ayrımı; boşluklar ve iç içe grid'ler. Öğeleri çizgi numaralarıyla ya da adlandırılmış alanlarla yerleştirmeyi grid-template-areas ve çizgi yerleşimi, otomatik yerleşimi ve auto-fill ile minmax() desenini auto-fill, auto-fit ve minmax() yazısında ele alıyoruz. Serinin bütünü için CSS öğrenme rehberi sayfasına bakabilirsiniz.

Grid neyi farklı yapar?

MDN grid'i, birbirini kesen yatay ve dikey çizgilerden oluşan bir sistem olarak tanımlar. Öğeler bu çizgilerin oluşturduğu satır ve sütunlara yerleştirilir. Grid'in sunduğu başlıca yetenekler şunlardır: piksel gibi sabit ya da yüzde ve fr gibi esnek iz boyutları; öğeleri çizgi numarası, çizgi adı ya da alan adıyla tam istenen yere koyabilme; yer verilmemiş öğeler için bir otomatik yerleşim algoritması; içerik arttığında yeni satır ve sütunlar oluşturma; hizalama kontrolü ve öğelerin aynı hücrede üst üste binebilmesi.

Flexbox ile en temel fark boyut sayısıdır. Flexbox bir satır ya da bir sütunla ilgilenir ve kaydırılan her satır bağımsız davranır. Grid ise satır ve sütunları birlikte yönetir; bir sütundaki öğeler her satırda aynı hizada kalır. MDN'in bir başka ayrımı da yönle ilgilidir: flexbox içerikten dışarıya çalışır, yani öğelerin boyutu düzeni belirler; grid ise düzenden içeriye çalışır, önce izleri tanımlarsınız, sonra öğeleri bu izlere yerleştirirsiniz. Boyutlandırmanın büyük kısmı da bu yüzden öğelerde değil, kapsayıcıda yapılır.

Grid kapsayıcı ve grid öğeleri

Kapsayıcı display: grid ya da satır içi bir kutu için display: inline-grid ile oluşturulur. Bunu yaptığınız anda doğrudan çocuklar grid öğesi olur. Yalnızca display: grid yazdığınızda tarayıcıda gözle görülür bir değişiklik olmaz; çünkü grid tek sütunlu bir ızgara oluşturur ve öğeler alt alta dizilir. Izgaranın sütun kazanması için iz tanımlamanız gerekir.

html
<div class="izgara">
  <div>Bir</div>
  <div>İki</div>
  <div>Üç</div>
  <div>Dört</div>
  <div>Beş</div>
</div>
css
.izgara {
  display: grid;
  grid-template-columns: 200px 200px 200px;
}
/* sonuç: 200px genişliğinde üç sütun; beş öğe ilk satıra üç,
   ikinci satıra iki tane olmak üzere hücrelere birer birer yerleşir */

Flexbox'ta olduğu gibi grid düzeni de yalnızca doğrudan çocuklara uygulanır. Bir grid öğesinin içindeki öğeler normal akışta kalır. Bu yüzden içteki öğeleri de ızgaraya katmak istediğinizde ya o öğeyi ayrıca grid kapsayıcı yaparsınız ya da aşağıda kısaca değindiğimiz subgrid değerini kullanırsınız.

Grid terimleri

Grid terimleri: İz (track), Çizgi (line), Hücre (cell), Alan (area)
TerimAnlamı
İz (track)iki komşu çizgi arasındaki alan; bir satır ya da bir sütun
Çizgi (line)izleri ayıran yatay ve dikey çizgiler; 1'den başlayarak numaralanır
Hücre (cell)ızgaranın en küçük birimi, bir satır ile bir sütunun kesişimi
Alan (area)bir ya da daha fazla hücreden oluşan dikdörtgen bölge
Oluk (gutter)izler arasındaki boşluk; gap ile oluşturulur
Açık gridgrid-template-columns ve grid-template-rows ile tanımlanan izler
Örtük gridiçerik açık grid dışına taştığında otomatik oluşturulan izler

Grid'i tanımlarken çizgileri değil izleri tanımlarsınız; çizgiler kendiliğinden oluşur. Üç sütunlu bir ızgarada dört sütun çizgisi vardır. Çizgiler belgenin yazma yönüne göre numaralanır: soldan sağa bir dilde 1 numaralı çizgi solda, sağdan sola bir dilde sağdadır. Alanlar her zaman dikdörtgen olmak zorundadır; MDN L şeklinde bir alan oluşturmanın mümkün olmadığını belirtir.

grid-template-columns ve grid-template-rows

Bu iki özellik açık grid'in sütun ve satır izlerini tanımlar. Değer, boşlukla ayrılmış bir iz boyutları listesidir. Başlangıç değeri nonedır; yani açık grid yoktur ve gereken izler örtük olarak oluşturulur. Her iz için şu türlerden biri kullanılabilir:

  • Uzunluk: 200px, 10rem gibi negatif olmayan bir değer.
  • Yüzde: Sütunlarda grid kapsayıcının satır içi boyutuna göre hesaplanır. Kapsayıcının boyutu izlerine bağlıysa tarayıcı yüzdeyi auto gibi ele alır.
  • fr: Kalan alanın bir payı; aşağıda ayrıntılı.
  • min-content, max-content, auto: İçeriğe göre boyutlanan izler. auto çoğu durumda minmax(min-content, max-content) gibi davranır ve yalnızca auto izler justify-content, align-content ile esnetilebilir.
  • minmax() ve fit-content(): Bir boyut aralığı ya da sınırlı içerik boyutu tanımlar; ayrıntıları minmax() yazısında.
css
.duzen {
  display: grid;
  grid-template-columns: 250px 1fr;        /* sabit yan panel + esnek içerik */
  grid-template-rows: auto 1fr auto;       /* başlık, gövde, alt bilgi */
}

fr birimi: kalan alanın payı

fr birimi: kalan alanın payı

fr, grid'e özgü esnek bir uzunluktur. MDN'e göre <flex> veri türü bir sayı ve ardından gelen fr biriminden oluşur ve grid kapsayıcıda kalan alanın bir kesrini temsil eder. Tüm CSS boyutlarında olduğu gibi sayı ile birim arasında boşluk olmaz; 1fr ve 2.5fr geçerlidir. Hesap şu sırayla yapılır: önce sabit izler ve boşluklar kapsayıcının boyutundan düşülür, kalan alan fr değerlerinin toplamına bölünür ve her iz kendi katsayısı kadar pay alır.

css
/* 800px genişliğinde, gap olmayan kapsayıcı */
.a { grid-template-columns: 1fr 1fr 1fr; }
/* 800px / 3 = yaklaşık 266.67px, üç eşit sütun */

.b { grid-template-columns: 2fr 1fr 1fr; }
/* toplam 4 pay, bir pay = 800px / 4 = 200px
   sonuç: 400px, 200px, 200px */

.c { grid-template-columns: 500px 1fr 2fr; }
/* kalan = 800px - 500px = 300px, toplam 3 pay, bir pay = 100px
   sonuç: 500px, 100px, 200px */

Boşluklar da fr dağıtımından önce düşülür. MDN, gap tarafından kullanılan alanın esnek izlere alan dağıtılmadan önce hesaba katıldığını belirtir. 640 piksellik bir kapsayıcıda grid-template-columns: 1fr 1fr 1fr ve gap: 20px varsa iki oluk 40 piksel kaplar; kalan 600 piksel üç sütuna bölünür ve her sütun tam 200 piksel olur. Aynı düzeni 33.33% genişlikli üç sütunla kurmaya çalışırsanız her sütun yaklaşık 213 piksel olur, buna 40 piksellik boşluk eklenince toplam kapsayıcıdan taşar. fr kullanmanın en pratik faydası budur: oluklar için hesap yapmanız gerekmez.

repeat() ile tekrar eden izler

Çok sayıda iz içeren ızgaralarda repeat() fonksiyonu iz listesinin tamamını ya da bir bölümünü tekrar eder. İlk argüman tekrar sayısıdır ve 1 ya da daha büyük bir tam sayı olmalıdır; ikinci argüman tekrarlanacak iz listesidir. Tekrar edilen parça tek bir iz olmak zorunda değildir; bir iz kalıbı da olabilir.

css
.a { grid-template-columns: repeat(3, 1fr); }
/* 1fr 1fr 1fr ile aynı */

.b { grid-template-columns: 20px repeat(6, 1fr) 20px; }
/* 8 sütun: 20px, altı tane 1fr, 20px */

.c { grid-template-columns: repeat(5, 1fr 2fr); }
/* 10 sütun: 1fr 2fr kalıbı beş kez */

Tekrar sayısı yerine auto-fill ya da auto-fit anahtar sözcüklerini kullanarak "sığdığı kadar sütun" oluşturabilirsiniz. Bu iki anahtar sözcük ve repeat() kısıtlamaları auto-fill ve auto-fit yazısının konusudur. MDN ayrıca bir repeat() fonksiyonunun başka bir repeat() içine yazılamayacağını belirtir.

Açık grid ve örtük grid

Yukarıdaki ilk örnekte yalnızca sütunları tanımladık; satırlar ise içerik geldikçe kendiliğinden oluştu. Tanımladığınız sütunlar açık grid'i, gerektiği için oluşturulan satırlar örtük grid'i oluşturur. Bir öğeyi açık grid'in dışına yerleştirdiğinizde ya da içerik açık izlere sığmadığında örtük izler eklenir. Örtük izler varsayılan olarak auto boyutludur; hem içeriklerine göre hem de kapsayıcıdaki boş alana göre boyutlanırlar.

css
.izgara {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: minmax(100px, auto);
}
/* sonuç: örtük satırlar en az 100px yüksekliğinde;
   içerik daha uzunsa satır içeriğe göre uzar */

Örtük izlerin boyutu grid-auto-rows ve grid-auto-columns ile kontrol edilir. Bu özelliklerin ayrıntıları ve otomatik yerleşim algoritması grid otomatik yerleşim yazısında ele alınıyor.

gap: oluklar

Hücreler arasındaki boşluklar column-gap, row-gap ya da kısaltma olan gap ile oluşturulur. İki değer verirseniz ilki satırlar arası, ikincisi sütunlar arası boşluktur. Oluklar yalnızca izlerin arasında oluşur; ilk izden önce, son izden sonra ve kapsayıcının kenarlarında boşluk eklemez. MDN, çizgi tabanlı yerleşim açısından oluğun kalın ve şeffaf bir çizgi gibi davrandığını, içine bir şey yerleştirilemeyeceğini belirtir.

css
.izgara {
  display: grid;
  grid-template-columns: repeat(3, 100px);
  grid-template-rows: repeat(3, 100px);
  gap: 10px;
}
.genis { grid-column: span 2; }
/* .genis iki sütun ve aradaki bir oluğu kaplar:
   100px + 10px + 100px = 210px
   üç sütun kaplasaydı: 100 + 10 + 100 + 10 + 100 = 320px */

Bu hesap MDN'in gap sayfasındaki örnekle aynıdır: birden fazla izi kaplayan bir öğe için oluk, iz boyutlandırmasında ekstra, boş ve sabit boyutlu bir iz gibi sayılır. Eski grid belirtimlerinde bu özelliğin adı grid-gap'ti; tarayıcılar eski siteler için bu adı gap'in takma adı olarak kabul eder. Yeni kodda gap kullanmanız yeterlidir.

Öğeleri kısaca yerleştirmek

Öğelere hiçbir yerleşim bilgisi vermezseniz otomatik yerleşim onları kaynak sırasına göre hücrelere birer birer koyar. Belirli bir öğeyi birden fazla hücreye yaymak için çizgi numaralarını kullanırsınız: grid-column: 1 / 4 öğeyi 1 numaralı çizgiden 4 numaralı çizgiye, yani üç sütun boyunca uzatır. -1 açık grid'in son çizgisini ifade ettiği için grid-column: 1 / -1 öğeyi her zaman tüm genişliğe yayar. Çizgi numaraları, span ve adlandırılmış alanların tamamı grid çizgi yerleşimi yazısında.

Üst üste binen öğeler ve z-index

Grid öğeleri aynı hücreyi ya da alanı paylaşabilir. İki öğe çakıştığında kaynakta sonra gelen öğe üstte görünür. Bu sırayı, konumlandırılmış öğelerde olduğu gibi z-index ile değiştirebilirsiniz; MDN'in örneğinde ikinci öğeye birincisinden düşük bir z-index verildiğinde ikinci öğe alta geçer. Yığın bağlamının genel kuralları z-index ve stacking context yazısında anlatılıyor.

İç içe grid ve subgrid

Bir grid öğesi kendisi de grid kapsayıcı olabilir. Ancak normal iç içe grid ebeveyniyle ilişkisizdir: ebeveynin gap değerini almaz ve çizgileri ebeveynin çizgileriyle hizalanmaz. İçteki ızgaranın ebeveyn izlerini kullanması için grid-template-columns ya da grid-template-rows değerine subgrid yazılır; böylece iç ızgara, ebeveynde kapladığı izlerin boyutlarını devralır. Subgrid'in davranışı ve sınırlamaları subgrid kısa girişinde ele alınıyor.

Flexbox mı grid mi?

MDN karar için iki soru önerir: Düzeni yalnızca satır ya da yalnızca sütun olarak mı kontrol etmeniz gerekiyor? O zaman flexbox. Satır ve sütunu birlikte mi kontrol etmeniz gerekiyor? O zaman grid. Bir başka işaret de şudur: flexbox kullanırken esnekliği kapatmaya, örneğin öğeleri üstteki satırla hizalamak için onlara sabit genişlik vermeye başladıysanız muhtemelen grid'e ihtiyacınız vardır. İki yöntem birbirinin rakibi değildir; aynı sayfada sayfa iskeleti için grid, bileşen içleri için flexbox kullanmak olağandır. Flexbox tarafı için CSS flexbox rehberi yazısına bakabilirsiniz.

Sık yapılan hatalar

Sık yapılan hatalar: Yalnızca display: grid yazıp sütun beklemek, Sütun sayısını çizgi sayısıyla karıştırmak, Oluklar için yüzde hesabı yapmak, Torunların ızgaraya yerleşmesini...
  • Yalnızca display: grid yazıp sütun beklemek: İz tanımlamazsanız grid tek sütun oluşturur ve görünüm değişmez.
  • Sütun sayısını çizgi sayısıyla karıştırmak: N sütunlu bir ızgarada N + 1 çizgi vardır; tüm genişlik için 1 / -1 kullanın.
  • Oluklar için yüzde hesabı yapmak: Yüzdelik sütunlarla gap birlikte taşmaya yol açabilir; fr boşlukları otomatik düşer.
  • Torunların ızgaraya yerleşmesini beklemek: Yalnızca doğrudan çocuklar grid öğesidir.
  • Sayı ile fr arasına boşluk koymak: 1 fr geçersizdir; 1fr yazılmalıdır.

Sık Sorulan Sorular

fr ile yüzde arasındaki fark nedir?

Yüzde, kapsayıcının toplam boyutuna göre hesaplanır ve boşlukları hesaba katmaz. fr ise sabit izler ve boşluklar düşüldükten sonra kalan alanın payıdır; bu yüzden gap ile birlikte taşma oluşturmaz.

grid-template-rows yazmak zorunda mıyım?

Hayır. Satırları tanımlamazsanız içerik geldikçe örtük satırlar oluşturulur ve varsayılan olarak içeriklerine göre boyutlanırlar. Sabit ya da en az yüksekliği olan satırlar istiyorsanız grid-auto-rows kullanabilirsiniz.

grid-gap ile gap aynı mı?

Evet. grid-gap eski belirtimlerdeki addır ve tarayıcılar uyumluluk için onu gap'in takma adı olarak kabul eder. gap ayrıca flexbox ve çok sütunlu düzenlerde de çalışır.

Grid ile duyarlı (responsive) düzen nasıl kurulur?

Ya medya sorguları içinde iz tanımlarını değiştirirsiniz ya da repeat(auto-fill, minmax(...)) ile sütun sayısını kapsayıcı genişliğine bıraktırırsınız. Duyarlı tasarımın genel kavramları mobil uyumluluk yazısında anlatılıyor.

Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.

İlgili içerikler: CSS öğrenme rehberi · Grid alanları ve çizgi yerleşimi · auto-fill, auto-fit ve minmax() · CSS flexbox rehberi · CSS ortalama yöntemleri