Tailwind CSS'te container query kullanmak için kapsayıcı öğeye @container sınıfını verir, içindeki öğelerde @sm:, @md:, @lg: gibi @ ile başlayan varyantları kullanırsınız. @md:flex-row, en yakın kapsayıcının genişliği 28rem veya daha fazlaysa uygulanır; pencerenin genişliğine bakmaz. v4.3.5 ile yaptığımız derlemelerde bunun için ayrı bir eklenti ya da yapılandırma gerekmedi.

Bu yazıda @container sınıfının ürettiği CSS'i, 13 varsayılan kapsayıcı boyutunu, @max-* ve aralık kullanımını, adlandırılmış kapsayıcıları, @container-size farkını, keyfi değerleri ve --container-* ile kendi boyutlarınızı eklemeyi v4.3.5 ile derlenmiş gerçek çıktılarla anlatıyoruz. Container query kavramının saf CSS tarafı (container-type, @container kuralı, sorgu birimleri) CSS container queries yazısında; serinin tamamı Tailwind öğrenme rehberinde.

Viewport sorgusu ile container query arasındaki fark

md: gibi bir kırılma noktası öneki tarayıcı penceresinin genişliğini ölçer. Aynı ürün kartını hem geniş bir ana sütunda hem dar bir kenar çubuğunda kullandığınızı düşünün: pencere 1200px genişliğindeyken kart iki yerde de md: kurallarını alır, oysa kenar çubuğunda yan yana düzen için yeterli yer yoktur. Resmî responsive design sayfası container query'leri bu soruna çözüm olarak sunar: öğe, ebeveyninin gerçekten sunduğu alana göre biçimlenir ve bu sayede bileşen nereye konursa konsun uyum sağlar, yeniden kullanılabilir hâle gelir. Viewport öneklerinin kendisi Tailwind responsive tasarım yazısında.

Temel kullanım: @container ve @md:

Aşağıdaki kartta dış div kapsayıcıdır. Kart dar bir alandaysa görsel ve metin alt alta, kapsayıcı 28rem veya daha genişse yan yana durur; 48rem'den geniş alanlarda boşluk da artar.

html
<div class="@container">
  <article class="flex flex-col gap-4 @md:flex-row @3xl:gap-8">
    <img class="w-full @md:w-40" src="urun.jpg" alt="Ürün">
    <p class="text-sm @lg:text-base">Ürün açıklaması</p>
  </article>
</div>

v4.3.5 ile derlenen CSS:

css
/* (kısaltıldı) */
@layer utilities {
  .\@container {
    container-type: inline-size;
  }
  .flex {
    display: flex;
  }
  .w-full {
    width: 100%;
  }
  .flex-col {
    flex-direction: column;
  }
  .gap-4 {
    gap: calc(var(--spacing) * 4);
  }
  .text-sm {
    font-size: var(--text-sm);
    line-height: var(--tw-leading, var(--text-sm--line-height));
  }
  @container (width >= 28rem) {
    .\@md\:w-40 {
      width: calc(var(--spacing) * 40);
    }
    .\@md\:flex-row {
      flex-direction: row;
    }
  }
  @container (width >= 32rem) {
    .\@lg\:text-base {
      font-size: var(--text-base);
      line-height: var(--tw-leading, var(--text-base--line-height));
    }
  }
  @container (width >= 48rem) {
    .\@3xl\:gap-8 {
      gap: calc(var(--spacing) * 8);
    }
  }
}

Çıktının anahtarı ilk kuraldır: @container sınıfı container-type: inline-size yazar, yani öğeyi yatay (satır yönündeki) boyutu sorgulanabilen bir kapsayıcı yapar. Varyantlı sınıflar ise @media yerine @container kurallarına girer. Seçicilerdeki @ işareti CSS'te özel anlamı olduğu için .\@md\:flex-row biçiminde kaçırılır; HTML'de yine @md:flex-row yazarsınız. Kırılma noktalarında olduğu gibi container query varyantları da mobile-first çalışır: @md: 28rem ve üstünde geçerlidir ve daha büyük bir varyant gelene kadar korunur.

Bir sorgu, onu kullanan öğenin kendisine değil, en yakın kapsayıcı atasına bakar. Bu yüzden @container sınıfını varyantları kullandığınız öğenin bir üstüne koyarsınız. Pratikte kapsayıcıyı bir sarmalayıcı öğe yapar, varyantları onun çocuklarında kullanırsınız.

Uygulamalı örnek: aynı kart iki farklı yerde

Uygulamalı örnek: aynı kart iki farklı yerde: 18rem kenar çubuğunda, 50rem ana sütunda, Pencere küçülse bile

Yukarıdaki kartın gerçek değeri, aynı işaretlemeyi farklı genişlikteki alanlara koyduğunuzda ortaya çıkar. Kartı 18rem genişliğinde bir kenar çubuğuna ve 50rem genişliğinde bir ana sütuna yerleştirdiğinizi düşünün; pencere genişliği her iki durumda da aynıdır.

  • 18rem kenar çubuğunda: Kapsayıcı genişliği 28rem eşiğinin altında kaldığı için @md, @lg ve @3xl kurallarının hiçbiri eşleşmez. Kart flex-col ile dikey kalır, görsel tam genişlikte olur, metin text-sm boyutunda ve boşluk gap-4 ile 1rem'dir.
  • 50rem ana sütunda: 28rem, 32rem ve 48rem eşiklerinin üçü de aşılır. Kart yatay düzene geçer, görsel 10rem genişliğe sabitlenir, metin --text-base (1rem) boyutuna büyür ve boşluk 2rem olur.
  • Pencere küçülse bile: Ana sütun 30rem'e daralırsa yalnızca @md eşleşmeye devam eder; kart yatay kalır ama boşluk 1rem'e döner ve metin küçülür.

Aynı sonucu viewport önekleriyle almak için kartın her kullanım yerine göre ayrı sınıf listesi yazmanız gerekirdi. Container query ile kart kendi alanını ölçtüğü için tek bir işaretleme yeterlidir. Bu, bir bileşen kütüphanesi kurarken ya da aynı parçayı header, sidebar ve footer düzeni içinde farklı bölgelerde kullanırken en büyük kazançtır.

container sınıfı ile @container aynı şey değil

Adları benzediği için sık karıştırılan iki sınıf vardır. @container öğeyi sorgulanabilir bir kapsayıcı yapar ve tek başına yalnızca container-type: inline-size yazar. Başında @ olmayan container sınıfı ise bambaşka bir iş yapar: v4.3.5'te derlendiğinde width: 100% ve her kırılma noktasında o kırılma noktasının değerine eşit bir max-width üretir (40rem'den başlayıp 96rem'e kadar). Yani container bir genişlik sınırlayıcıdır, sorgu kurmaz. Ayrıntısı Tailwind container sınıfı ve max-width yazısında. İkisini aynı öğede birlikte kullanmak da mümkündür, çünkü yazdıkları özellikler çakışmaz.

Varsayılan kapsayıcı boyutları

Varsayılan kapsayıcı boyutları: @3xs, @2xs, 20rem, 24rem

Kapsayıcı boyutları kırılma noktalarından ayrı bir ad alanıdır: --container-*. v4.3.5 tema dosyasında 16rem ile 80rem arasında 13 değer vardır. Piksel karşılıkları 16px kök yazı boyutu varsayımıyla verilmiştir.

VaryantDeğer16px kökteÜretilen sorgu
@3xs16rem256px@container (width >= 16rem)
@2xs18rem288px@container (width >= 18rem)
@xs20rem320px@container (width >= 20rem)
@sm24rem384px@container (width >= 24rem)
@md28rem448px@container (width >= 28rem)
@lg32rem512px@container (width >= 32rem)
@xl36rem576px@container (width >= 36rem)
@2xl42rem672px@container (width >= 42rem)
@3xl48rem768px@container (width >= 48rem)
@4xl56rem896px@container (width >= 56rem)
@5xl64rem1024px@container (width >= 64rem)
@6xl72rem1152px@container (width >= 72rem)
@7xl80rem1280px@container (width >= 80rem)

@max-* ve aralıklar

Kırılma noktalarındaki max-* mantığı burada @max-* olarak vardır ve "kapsayıcı bu boyutun altındaysa" anlamına gelir. Aralık için iki varyantı yığarsınız. Keyfi bir değer gerekiyorsa @min-[...] ve @max-[...] kullanılır.

html
<div class="@container">
  <p class="@max-sm:hidden @sm:@max-lg:text-sm @min-[30rem]:font-bold"></p>
</div>

v4.3.5 ile derlenen CSS:

css
/* (kısaltıldı) */
@layer utilities {
  .\@container {
    container-type: inline-size;
  }
  @container (width < 24rem) {
    .\@max-sm\:hidden {
      display: none;
    }
  }
  @container (width >= 24rem) {
    @container (width < 32rem) {
      .\@sm\:\@max-lg\:text-sm {
        font-size: var(--text-sm);
        line-height: var(--tw-leading, var(--text-sm--line-height));
      }
    }
  }
  @container (width >= 30rem) {
    .\@min-\[30rem\]\:font-bold {
      --tw-font-weight: var(--font-weight-bold);
      font-weight: var(--font-weight-bold);
    }
  }
}

Paragraf, kapsayıcı 24rem'den darsa gizlenir; 24rem ile 32rem arasında küçük yazı alır; 30rem ve üstünde kalınlaşır. Yığılmış aralık iki iç içe @container kuralına dönüşür. --font-weight-bold tema değeri 700'dür. Keyfi değerde birim olarak rem veya px yazabilirsiniz; ama kırılma noktalarında olduğu gibi aynı projede tek bir birimde kalmak sıralamayı tahmin edilebilir tutar.

Adlandırılmış kapsayıcılar

İç içe kapsayıcılarda bir sorgu her zaman en yakın kapsayıcıya bakar. Daha dıştaki bir kapsayıcıyı hedeflemek için resmî sayfa kapsayıcıya @container/{ad} ile ad vermeyi, varyantta da @{boyut}/{ad} yazımını gösterir.

html
<main class="@container/sayfa">
  <section class="@container/kart">
    <div class="grid grid-cols-1 @sm/kart:grid-cols-2 @5xl/sayfa:grid-cols-4"></div>
  </section>
</main>

v4.3.5 ile derlenen CSS:

css
/* (kısaltıldı) */
@layer utilities {
  .\@container\/kart {
    container-type: inline-size;
    container-name: kart;
  }
  .\@container\/sayfa {
    container-type: inline-size;
    container-name: sayfa;
  }
  .grid {
    display: grid;
  }
  .grid-cols-1 {
    grid-template-columns: repeat(1, minmax(0, 1fr));
  }
  @container kart (width >= 24rem) {
    .\@sm\/kart\:grid-cols-2 {
      grid-template-columns: repeat(2, minmax(0, 1fr));
    }
  }
  @container sayfa (width >= 64rem) {
    .\@5xl\/sayfa\:grid-cols-4 {
      grid-template-columns: repeat(4, minmax(0, 1fr));
    }
  }
}

Ad, container-name özelliğine yazılır ve sorgu @container kart (...) biçimini alır. Böylece grid, kendi bölümü 24rem'i geçince iki kolona, tüm ana alan 64rem'i geçince dört kolona çıkar. İki koşul da doğruysa sonra gelen sayfa kuralı kazanır, çünkü derlenen dosyada 64rem bloğu 24rem bloğunun arkasındadır. Adlar için bir yapılandırma gerekmez; HTML'de kullandığınız an derleyici kuralı üretir.

@container-size ve sorgu birimleri

Container query birimleri (cqw, cqi, cqh, cqb gibi) keyfi değer olarak herhangi bir utility içinde kullanılabilir. Resmî sayfa, yalnızca satır içi boyuta bağlı olmayan birimler (cqb, cqh) için kapsayıcının @container-size ile tanımlanmasını söyler; bu sınıf container-type: size yazar ve iki boyutu da sorgulanabilir yapar.

html
<div class="@container"><h2 class="text-[8cqi] md:@lg:p-4"></h2></div>
<div class="@container-size"><div class="h-[50cqb]"></div></div>

v4.3.5 ile ilk satırdan derlenen CSS:

css
/* (kısaltıldı) */
@layer utilities {
  .\@container {
    container-type: inline-size;
  }
  .text-\[8cqi\] {
    font-size: 8cqi;
  }
  @media (width >= 48rem) {
    @container (width >= 32rem) {
      .md\:\@lg\:p-4 {
        padding: calc(var(--spacing) * 4);
      }
    }
  }
}

İkinci satırdaki sınıflar sırasıyla .\@container-size { container-type: size; } ve .h-\[50cqb\] { height: 50cqb; } üretti. İlk satırda ise başlığın yazı boyutu kapsayıcının satır içi boyutunun yüzde 8'i olur. Aynı örnekte md:@lg:p-4 bir viewport önekiyle bir container varyantının yığılabileceğini gösterir: dışta medya sorgusu, içte kapsayıcı sorgusu oluşur ve ikisi de doğru olduğunda iç boşluk uygulanır.

Kendi kapsayıcı boyutlarınızı eklemek

Yeni bir boyut adı için @theme içine --container-* değişkeni eklersiniz. Resmî örnek --container-8xl: 96rem; tanımlar; biz yanına küçük bir ad da ekledik.

css
@import "tailwindcss" source(none);
@source "./ornek.html";

@theme {
  --container-8xl: 96rem;
  --container-kucuk: 15rem;
}

Kaynakta @kucuk:p-2 @8xl:p-6 geçen bir HTML ile v4.3.5 ile derlenen CSS:

css
/* (kısaltıldı) */
@layer utilities {
  .\@container {
    container-type: inline-size;
  }
  @container (width >= 15rem) {
    .\@kucuk\:p-2 {
      padding: calc(var(--spacing) * 2);
    }
  }
  @container (width >= 96rem) {
    .\@8xl\:p-6 {
      padding: calc(var(--spacing) * 6);
    }
  }
}

İki yeni ad doğru değerlerle ve doğru sırayla üretildi. Tema değişkenlerinin genel kuralları Tailwind @theme direktifi yazısında. Var olan bir boyutu silmek veya ad alanını sıfırlamak, kırılma noktalarındaki initial mantığıyla aynı biçimde çalışır; bunun ayrıntısı breakpoint özelleştirme yazısında gösterildi.

Sık yapılan hatalar

Sık yapılan hatalar: @container sınıfını unutmak, @container sınıfını aynı öğeye koymak, md ile @md'yi aynı değer sanmak, Gereksiz yere @container-size kullanmak
  • @container sınıfını unutmak: Sadece @md:flex-row yazıp hiçbir atada @container kullanmadığımızda CLI kuralı yine üretti: @container (width >= 28rem) { .\@md\:flex-row { ... } }. Ama sorgulanacak bir kapsayıcı olmadığı için tarayıcıda koşul eşleşmez. CSS'in var olması sınıfın çalıştığı anlamına gelmez.
  • @container sınıfını aynı öğeye koymak: Sorgu öğenin kendisine değil atasına bakar. Varyantları kullanan öğenin bir üstünde kapsayıcı olmalıdır.
  • md ile @md'yi aynı değer sanmak: Biri 48rem, diğeri 28rem'dir.
  • Gereksiz yere @container-size kullanmak: container-type: size yazar; resmî sayfa bunu yalnızca cqb/cqh gibi blok boyutuna bağlı birimler için önerir.
  • İç içe kapsayıcıda yanlış atayı hedeflemek: En yakın kapsayıcı yanıt verir. Dıştakini hedeflemek için ad verin: @container/sayfa ve @5xl/sayfa:.

Sık Sorulan Sorular

Container query için eklenti kurmak gerekiyor mu?

v4.3.5'te hayır. @container sınıfı ve @sm: ile @7xl: arasındaki varyantlar hiçbir ek yapılandırma olmadan derlendi.

Container query ile kırılma noktasını birlikte kullanabilir miyim?

Evet. md:@lg:p-4 gibi bir yığma, dışta medya sorgusu ve içte kapsayıcı sorgusu üretir. Sayfa iskeleti için viewport, bileşen içi düzen için container query kullanmak iyi bir ayrımdır.

Container varyantları hover gibi durumlarla birleşir mi?

Evet. @md:hover:underline sınıfını derlediğimizde dışta @container (width >= 28rem), onun içinde @media (hover: hover) ve en içte .\@md\:hover\:underline:hover seçicisi oluştu. Sıra, yazdığınız gibi soldan sağa uygulanır. Durum varyantlarının kendisi hover, focus ve active durumları yazısında.

@container sınıfı neden inline-size kullanıyor?

Derlenen CSS container-type: inline-size yazar; bu, satır yönündeki boyutu (yatay yazımda genişliği) sorgulanabilir yapar ve Tailwind'in genişliğe dayalı varyantları için yeterlidir. Blok boyutuna bağlı birimler gerekiyorsa container-type: size yazan @container-size vardır.

Tarayıcı desteğini nereden kontrol ederim?

Resmî Tailwind CSS: Compatibility sayfası v4'ün modern tarayıcılar için tasarlandığını belirtir ve tek tek özellikler için Can I use veritabanına bakmayı önerir. Hedef kitlenizin tarayıcılarını oradan doğrulayın.

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: Tailwind öğrenme rehberi · Responsive tasarım · Breakpoint özelleştirme · container sınıfı ve max-width · CSS container queries · Arbitrary values