CSS container queries, bir öğeyi viewport'un değil, kendisini içeren kapsayıcının boyutuna ya da stiline göre biçimlendirmenizi sağlar. Önce bir öğeyi container-type özelliğiyle sorgu kapsayıcısı (query container) olarak işaretlersiniz, ardından @container kuralıyla o kapsayıcının genişliği gibi bir koşulu sorgularsınız. Koşul doğruysa kural bloğundaki stiller kapsayıcının alt öğelerine uygulanır.
Bu yaklaşımın en büyük kazancı yeniden kullanılabilir bileşenlerdir. MDN'nin örneğindeki kart bileşeni dar bir kenar çubuğuna da, geniş bir ana içerik alanına da yerleştirilebilir; kart hangi alanda olduğunu bilmek zorunda kalmadan kendi düzenini kapsayıcının genişliğine göre seçer. Bu yazıda boyut sorgularını, kapsayıcı adlandırmayı, yalnızca adla yapılan sorguları, kapsayıcı sorgu birimlerini (cqi, cqw vb.) ve özel özelliklerle yapılan stil sorgularını anlatıyoruz. Viewport tabanlı sorgular için media query yazısına bakabilirsiniz.
Sorgu kapsayıcısı oluşturmak: container-type

Bir kapsayıcının boyutunu sorgulayabilmek için tarayıcıya bunu baştan bildirmeniz gerekir. Bunu container-type özelliği yapar. Boyut sorguları için iki değer kullanılır: inline-size sorguyu yalnızca satır yönündeki boyuta (yatay yazıda genişlik) dayandırır; size ise hem satır hem blok yönündeki boyuta dayandırır. Varsayılan değer normal olup öğeyi boyut sorguları için kapsayıcı yapmaz, ancak öğe yine de stil sorguları ve yalnızca adla yapılan sorgular için kapsayıcı olabilir.
| Değer | Ne sağlar | Uygulanan containment |
|---|---|---|
| normal (varsayılan) | Boyut, scroll-state ve anchored sorguları yok; stil ve ad sorguları var | Yok |
| inline-size | Satır yönü boyutuna göre sorgu | style ve inline-size |
| size | Satır ve blok yönü boyutuna göre sorgu | style ve size (iki yönde) |
| scroll-state | Kaydırma durumu sorguları | Yok |
| anchored | Anchor positioning yedek seçeneği sorguları | Yok |
Tablodaki containment sütunu önemlidir. MDN'ye göre boyut kapsayıcılarına boyut sınırlaması (size containment) uygulanır; bu, öğenin boyut bilgisini içeriğinden almasını kapatır. Gerekçe sonsuz döngüyü önlemektir: Sorgunun içindeki bir kural içeriğin boyutunu değiştirse, bu da kapsayıcının boyutunu değiştirip sorguyu yanlışa çevirse, stil geri alınır, boyut eski hâline döner ve sorgu yeniden doğru olur. Containment bu zinciri baştan keser.
Bunun pratik bir yan etkisi var ve en sık yaşanan container query hatasının kaynağıdır. MDN, kapsayıcının boyutunun bağlamdan (ebeveyninin genişliğine yayılan bir blok öğe gibi) ya da açıkça verilmiş bir değerden gelmesi gerektiğini, aksi hâlde boyut sınırlaması uygulanan öğenin çökeceğini belirtir. container-type: size verdiğiniz bir öğenin yüksekliği artık içeriğinden hesaplanmaz; yükseklik belirtmezseniz sıfıra inebilir. Çoğu bileşen için yalnızca genişliği sorgulamak yeterli olduğundan inline-size genellikle daha güvenli bir seçimdir.
<div class="post">
<div class="card">
<h2>Kart başlığı</h2>
<p>Kart içeriği</p>
</div>
</div>/* satır yönü boyutuna dayalı kapsayıcı */
.post {
container-type: inline-size;
}
/* varsayılan başlık */
.card h2 {
font-size: 1em;
}
/* kapsayıcı 700px'ten genişse */
@container (width > 700px) {
.card h2 {
font-size: 2em;
}
}
/* sonuç: .post 700px veya daha darsa başlık 1em, daha genişse 2em */@container sözdizimi ve boyut özellikleri
@container kuralının koşulu bir kapsayıcı adı, bir sorgu ya da ikisini birden içermelidir. Ad yazılmamışsa sorgu, uygun container-type değerine sahip en yakın ata kapsayıcıya karşı değerlendirilir. Boyut sorgularında kullanılabilecek özellikler sınırlıdır: width, height, inline-size, block-size, aspect-ratio ve orientation. MDN, boyut sorgularının her zaman kapsayıcının içerik kutusunu (content box) ölçtüğünü belirtir; yani padding ve kenarlık sorgulanan genişliğe dahil değildir. Kutu modeli ayrıntıları için kutu modeli yazısına bakabilirsiniz.
@container (min-width: 400px) { /* ... */ }
@container (orientation: landscape) and (width > 400px) { /* ... */ }
@container (15em <= block-size <= 30em) { /* ... */ }
/* mantıksal anahtar kelimeler */
@container (width > 400px) and (height > 400px) { /* ... */ }
@container (width > 400px) or (height > 400px) { /* ... */ }
@container not (width < 400px) { /* ... */ }Sözdizimi ve mantıksal operatörler media query ile aynı kurallara dayanır; aralık yazımı, min-/max- önekleri ve kapsayıcı ya da dışlayıcı karşılaştırmalar burada da geçerlidir. MDN'nin @container sayfası bir kısıtı ayrıca vurgular: Bir kapsayıcı sorgusunda yalnızca bir not koşulu kullanılabilir ve bu koşul and ya da or ile birleştirilemez.
Unutulmaması gereken en önemli kural şudur: Sorgu doğru olduğunda stiller kapsayıcının alt öğelerine uygulanır, kapsayıcının kendisine değil. .post öğesini sorguladığınız bir blokta .post seçicisiyle kapsayıcıyı biçimlendirmeye çalışırsanız o kural sorgudan etkilenmez. Kapsayıcının kendi görünümünü değiştirmek istiyorsanız bir dış öğeyi kapsayıcı yapmanız ve asıl öğeyi onun içinde biçimlendirmeniz gerekir.
Kapsayıcıları adlandırmak: container-name ve container kısayolu
Sayfada iç içe birden fazla kapsayıcı olduğunda adsız sorgu her zaman en yakın atayı seçer. Belirli bir kapsayıcıyı hedeflemek için container-name ile ona ad verirsiniz. MDN adlar için şu kuralları sıralar: Ad büyük küçük harfe duyarlı bir <custom-ident> değeridir, tırnak içinde yazılmaz, or, and, not ya da default olamaz, --kenar-cubugu gibi çift tireyle başlayan adlar kullanılabilir ve bir öğeye boşlukla ayrılmış birden çok ad verilebilir. Varsayılan none değeri kapsayıcının adı olmadığını belirtir ama öğenin adsız sorgularla eşleşmesini engellemez.
.post {
container-name: sidebar;
container-type: inline-size;
}
/* aynı tanımın kısayolu: ad / tür */
.post {
container: sidebar / inline-size;
}
@container sidebar (width > 400px) {
.card {
font-size: 1.5em;
}
}container kısayolu container-name ve container-type özelliklerini birlikte ayarlar ve ad / tür biçiminde yazılır. Tek bir kapsayıcı sorgusuyla aynı anda birden fazla kapsayıcıyı hedefleyemezsiniz; MDN bunun yerine sorguları iç içe yazmayı önerir. Aşağıdaki örnekte stil, summary adlı kapsayıcı 400 pikselden genişse ve onun 800 pikselden geniş bir ata kapsayıcısı varsa uygulanır:
@container summary (width > 400px) {
@container (width > 800px) {
.card {
gap: 2rem;
}
}
}Yalnızca adla yapılan sorgular

Koşula sorgu yazmadan yalnızca bir ad verebilirsiniz. Bu tür sorgular, öğenin belirli bir container-name değerine sahip bir atası olup olmadığına bakar. Boyut ölçülmediği için kapsayıcıya container-type vermek gerekmez. Aşağıdaki örnekte ilk iki paragraf kapsayıcının içinde olduğu için stillenir, üçüncüsü dışarıda kaldığı için etkilenmez.
<div id="kapsayici">
<p>Kapsayıcının içindeyim.</p>
<p>Ben de içindeyim.</p>
</div>
<p>Ben dışarıdayım.</p>#kapsayici {
container-name: my-container;
}
@container my-container {
p {
background-color: lime;
padding: 0.5rem;
}
}
/* sonuç: yalnızca ilk iki <p> yeşil zeminli */Kapsayıcı sorgu uzunluk birimleri
Boyut kapsayıcısının (size ya da inline-size) alt öğelerinde kapsayıcıya göreli uzunluk birimleri kullanabilirsiniz. cqw kapsayıcı genişliğinin, cqh yüksekliğinin, cqi satır yönü boyutunun, cqb blok yönü boyutunun yüzde biridir. cqmin, cqi ile cqb değerlerinden küçük olanı; cqmax ise büyük olanı verir. Uygun bir kapsayıcı yoksa bu birimler, ilgili eksen için küçük viewport birimine (sv*) düşer. Viewport birimleri CSS birimleri yazısında anlatılıyor.
@container (width > 700px) {
.card h2 {
font-size: max(1.5em, 1.23em + 2cqi);
}
}
/* kapsayıcının satır yönü boyutu 600px olsaydı sorgu yanlış olurdu;
900px olsun ve devralınan font-size 16px olsun:
2cqi = 900 x 0.02 = 18px
1.23em = 1.23 x 16 = 19.68px -> toplam 37.68px
1.5em = 1.5 x 16 = 24px
max(24px, 37.68px) = 37.68px */Bu örnek MDN'nin kendi örneğidir; hesap adımları bizim eklememizdir. font-size özelliğinde kullanılan em, öğenin devraldığı yazı boyutunu temsil eder; bu yüzden 16 piksellik bir ebeveynde 1.23em 19,68 piksel olur. Kapsayıcı büyüdükçe 2cqi terimi de büyür ve başlık kapsayıcıyla orantılı ölçeklenir; max() ise başlığın hiçbir zaman 1.5em değerinin altına düşmemesini sağlar. max(), min() ve clamp() fonksiyonları calc, min, max ve clamp yazısında ayrıntılı işleniyor.
Stil sorguları: style() fonksiyonu
Kapsayıcı sorguları yalnızca boyutu değil, kapsayıcının hesaplanan stilini de sınayabilir. Bunun için koşulda style() fonksiyonu kullanılır. Boyut sorgularından farklı olarak her öğe bir stil kapsayıcısı olabilir; container-type vermek gerekmez ve sorgu en yakın ataya karşı değerlendirilir. MDN'nin rehberi, belirtimin normal CSS bildirimlerini de sorgulamaya izin verdiğini, ancak şu anda yalnızca özel özelliklerin (CSS değişkenleri) desteklendiğini söyler. style(font-weight: bold) gibi normal özellik sorguları rehbere göre henüz hiçbir tarayıcıda desteklenmiyor.
/* değer içeren sorgu: hesaplanan değer blue ise */
@container style(--accent-color: blue) {
.card {
border-color: currentcolor;
}
}
/* değersiz sorgu: değer başlangıç değerinden farklıysa */
@container style(--theme-color) { /* ... */ }
/* mantıksal birleşimler */
@container style(--theme: one) or style(--theme: two) { /* ... */ }
@container not style(--theme: one) { /* ... */ }Değersiz sorgunun davranışı özel özelliğin kayıtlı olup olmamasına bağlıdır. Kayıtsız bir özel özellik, örneğin yalnızca :root üzerinde --theme-color: rebeccapurple olarak tanımlanmışsa, style(--theme-color) o öğe ve tüm alt öğeleri için doğru döner. Özellik @property ile kaydedilmişse sorgu yalnızca hesaplanan değer initial-value değerinden farklı olan öğelerde doğru olur. Kayıtlı özellikleri @property yazısında anlatıyoruz.
Değerli sorgularda eşleşme hesaplanan değere göre yapılır. Kayıtsız bir özel özellikte değer yazıldığı gibi karşılaştırıldığından blue değerini tutan bir değişken #0000ff ile eşleşmez. Özellik @property ile syntax: "<color>" olarak kaydedilmişse tarayıcı renkleri gerçekten karşılaştırabilir ve blue, #00f, rgb(0 0 255 / 1) gibi değerlerin hepsi eşleşir. Sorguya !important yazmak geçerlidir ama etkisizdir; revert ve revert-layer ise geçersizdir ve sorguyu yanlış yapar.
Düz ve aralık yazımı arasındaki fark
MDN, stil sorgularında iki karşılaştırma biçimini ayırır. İki nokta üst üsteli düz yazım (style(--n: 3)) hesaplanan değeri belirteç düzeyinde karşılaştırır. Karşılaştırma operatörlü aralık yazımı (style(--n = 3)) ise iki tarafı sayı, uzunluk, açı gibi sayısal türlere çözümler, calc() ifadelerini hesaplar ve sayısal karşılaştırma yapar. İki taraf aynı türde değilse ya da sayısal türe çözümlenemiyorsa sorgu yanlıştır.
.box {
--n: calc(6/2);
}
/* YANLIŞ: kayıtsız --n değeri "calc(6/2)" belirtecidir, "3" değil */
@container style(--n: 3) { /* ... */ }
/* DOĞRU: iki taraf da sayıya çözülür, 6/2 = 3 ve 3 = 3 */
@container style(--n = 3) { /* ... */ }
/* üç değerli aralık: 0 < --n < 10 */
@container style(0 < --n < 10) { /* ... */ }Bu yüzden MDN'nin önerisi nettir: --theme: dark gibi anahtar kelime ya da metin benzeri değerleri düz yazımla, --columns >= 3 gibi sayısal karşılaştırmaları aralık yazımıyla sorgulayın. style(--theme = dark) her zaman yanlıştır, çünkü dark sayısal bir tür değildir. Rehber ayrıca sorguladığınız stili, o sorguyla biçimlendirdiğiniz öğenin kendisine uygulamamanızı ister; aksi hâlde sonsuz döngü oluşabilir. Özel özelliklerin genel kullanımı CSS değişkenleri yazısında anlatılıyor.
Media query ile container query karşılaştırması

| Konu | @media | @container |
|---|---|---|
| Neyi sorgular | Viewport ve cihaz, kullanıcı tercihleri | En yakın (ya da adı verilen) kapsayıcı |
| Ön hazırlık | Gerekmez | Boyut için container-type: size veya inline-size |
| Stillenen öğeler | Seçicinin eşleştiği her öğe | Kapsayıcının alt öğeleri |
| Ölçülen kutu | Viewport (width kaydırma çubuğunu içerir) | Kapsayıcının içerik kutusu |
| Göreli birimler | vw, vh, svh, dvh vb. | cqw, cqh, cqi, cqb, cqmin, cqmax |
| Tipik kullanım | Sayfa iskeleti, baskı, erişilebilirlik tercihleri | Yeniden kullanılabilir bileşen düzeni |
Uygulamalı mini örnek: daralan ve genişleyen kart
MDN'nin container-type sayfasındaki örneği temel alalım: Aynı kart, 300 piksellik bir kapsayıcıda tek sütun, 500 piksellik bir kapsayıcıda iki sütun olsun. Kapsayıcılar sabit genişlik taşıdığı için boyut bilgisi açıkça verilmiştir ve containment kaynaklı çökme yaşanmaz.
<div class="container">
<div class="card"><h3>Normal kart</h3><div class="content">...</div></div>
</div>
<div class="container wide">
<div class="card"><h3>Geniş kart</h3><div class="content">...</div></div>
</div>.container {
container-type: inline-size;
width: 300px;
height: 120px;
}
.wide {
width: 500px;
}
@container (width > 400px) {
.card {
display: grid;
grid-template-columns: 1fr 2fr;
}
}
/* sonuç: 300px kapsayıcıdaki kart tek sütun kalır;
500px kapsayıcıdaki kart 1fr 2fr iki sütunlu grid olur */Burada kapsayıcıya verilen width değeri kenarlık ve padding içermiyorsa içerik kutusu doğrudan 300 ve 500 piksel olur; ilki 400 pikselin altında kaldığı için sorgu yanlış, ikincisi üstünde olduğu için doğrudur. Kapsayıcıya padding eklerseniz sorgunun içerik kutusunu ölçtüğünü hatırlayın. fr birimi ve grid-template-columns CSS grid rehberinde anlatılıyor.
Sık yapılan hatalar
container-typevermeden boyut sorgusu yazmak: Hiçbir ata boyut kapsayıcısı değilse sorgu eşleşmez.- Kapsayıcının kendisini biçimlendirmeye çalışmak: Sorgunun içindeki stiller yalnızca alt öğelere uygulanır.
- Gereksiz yere
sizekullanmak: Yüksekliği bağlamdan ya da açık bir değerden gelmeyen öğe boyut sınırlaması yüzünden çöker. Çoğu durumdainline-sizeyeterlidir. - Adı tırnakla ya da yasaklı kelimeyle yazmak:
container-name: "kart"vecontainer-name: defaultgeçersizdir. - Padding'i genişliğe dahil sanmak: Boyut sorguları kapsayıcının içerik kutusunu ölçer.
- Renkleri kayıtsız değişkende karşılaştırmak:
style(--renk: blue), değişken#0000fftutuyorsa eşleşmez; özelliği@propertyile kaydedin. - Sayısal değeri düz yazımla sorgulamak:
calc()içeren değerler için aralık yazımını (=,>=) kullanın.
Sık Sorulan Sorular
Container query media query yerine mi geçiyor?
Hayır, ikisi farklı sorulara cevap verir. Media query viewport ve kullanıcı tercihlerini, container query bir bileşenin yerleştiği alanı sorgular. Bir sayfada ikisini birlikte kullanmak olağandır.
inline-size ile size arasında hangisini seçmeliyim?
Yalnızca genişliğe göre değişen bileşenler için inline-size seçin. size, iki yönde de boyut sınırlaması uyguladığı için öğenin yüksekliğinin açıkça ya da bağlamdan belirlenmiş olmasını gerektirir.
Stil sorgusu için container-type gerekli mi?
Hayır. MDN'ye göre tüm öğeler stil sorgusu kapsayıcısı olabilir. container-type yalnızca boyut, scroll-state ve anchored sorguları için gereklidir.
cqi birimini kapsayıcı yokken kullanırsam ne olur?
Uygun bir kapsayıcı bulunamazsa kapsayıcı sorgu birimleri ilgili eksen için küçük viewport birimine (svi, svb gibi sv* birimleri) düşer.
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 · Media query sözdizimi · @property ile kayıtlı özellikler · CSS değişkenleri · @supports · Grid auto-fill ve minmax