---
title: 'Kapsayıcı Sorguları'
source: 'https://academia.sh/tr/kurslar/duzen-ve-duyarli-tasarim/kapsayici-sorgulari'
course: 'Düzen Sistemleri ve Duyarlı Tasarım'
language: tr
updated: '2026-08-17T18:09:28+00:00'
license: 'CC BY-SA 4.0'
---

# Kapsayıcı Sorguları

Sorgunun öznesinin görüntü alanından bileşenin kabına taşınması, kap bildirimi ve sınırlama gereği, kapsayıcı birimleri ve aynı bileşenin iki ayrı yerde doğru karar vermesi.

Önceki dersteki bütün sorgular tek bir şeye bakıyordu: görüntü alanının kendisi. Sayfa düzeni
için bu doğru öznedir; sayfanın kaç sütun olacağını gerçekten ekranın genişliği belirler.

Ölçüm kartı için doğru özne değildir. Kartın nasıl görünmesi gerektiğini belirleyen, ekranın
genişliği değil kartın **yerleştirildiği kabın** genişliğidir. Bu ders sorgunun öznesini
değiştirir ve değişimin ne kadar fark ettiğini hesapla ölçer.

## Aynı Kart, İki Kap

İstasyon sayfasında ölçüm kartı iki yerde bulunur: ana bölümdeki kart ızgarasında ve yan
bilgideki özet listesinde. İki kabın genişlikleri farklıdır ve bu genişlikler görüntü alanının
genişliğinden doğrudan okunamaz.

Kartın kendi eşiği vardır: 280 birimin altında başlık, değer ve birim alt alta dizilir; üstünde
yan yana durur. Aşağıdaki program bu kararı iki ayrı sorgu türüyle veriyor.

```js
// kapsayici.mjs — ayni kartin iki ayri kapta aldigi olcu, iki sorgu turuyle karar
const IC_BOSLUK = 48;
const SAYFA_ARALIK = 24;
const ANA_EN_DAR = 480, YAN_EN_DAR = 260;
const KART = 200, KART_ARALIK = 16;

// sayfa duzeni: minmax(480px, 2fr) minmax(260px, 1fr), tek sutun esigi 812px
function bolumler(gorusAlani) {
  if (gorusAlani < 812) return { ana: gorusAlani - IC_BOSLUK, yan: gorusAlani - IC_BOSLUK };
  let kalan = gorusAlani - IC_BOSLUK - SAYFA_ARALIK;
  let ana = (kalan * 2) / 3, yan = kalan / 3;
  if (yan < YAN_EN_DAR) { yan = YAN_EN_DAR; ana = kalan - yan; }
  if (ana < ANA_EN_DAR) { ana = ANA_EN_DAR; yan = kalan - ana; }
  return { ana, yan };
}

// kart izgarasi: repeat(auto-fill, minmax(200px, 1fr))
function kartOlcusu(kapGenisligi) {
  const n = Math.max(1, Math.floor((kapGenisligi + KART_ARALIK) / (KART + KART_ARALIK)));
  return { sutun: n, olcu: (kapGenisligi - KART_ARALIK * (n - 1)) / n };
}

// kartin kendi esigi: 280px altinda basliklar alt alta, ustunde yan yana
const KART_ESIGI = 280;

console.log("kartin yan yana duzene gectigi olcu: 280px");
console.log("ortam sorgusu karari: (min-width: 812px) -> her kart yan yana");
console.log("kapsayici sorgusu karari: (min-width: 280px) -> her kart kendi kabina gore\n");

console.log("gorus  ana bolum  yan bilgi  ana kart  yan kart  ortam sorgusu       kapsayici sorgusu");
console.log("alani                                            ana / yan           ana / yan");
const hatalar = [];
for (const W of [400, 720, 812, 900, 1024, 1280, 1600]) {
  const { ana, yan } = bolumler(W);
  const anaKart = kartOlcusu(ana), yanKart = kartOlcusu(yan);
  const ortam = W >= 812 ? "yanyana" : "altalta";
  const kapAna = anaKart.olcu >= KART_ESIGI ? "yanyana" : "altalta";
  const kapYan = yanKart.olcu >= KART_ESIGI ? "yanyana" : "altalta";
  if (ortam !== kapAna) hatalar.push(`${W}px ana bolum`);
  if (ortam !== kapYan) hatalar.push(`${W}px yan bilgi`);
  console.log(
    `${String(W).padStart(5)}  ${ana.toFixed(0).padStart(9)}  ${yan.toFixed(0).padStart(9)}  ` +
      `${anaKart.olcu.toFixed(0).padStart(8)}  ${yanKart.olcu.toFixed(0).padStart(8)}  ` +
      `${(ortam + " / " + ortam).padEnd(18)}  ${kapAna} / ${kapYan}`,
  );
}

console.log(`\nortam sorgusunun yanlis karar verdigi durum sayisi: ${hatalar.length}`);
for (const h of hatalar) console.log(`  ${h}`);
```

```
kartin yan yana duzene gectigi olcu: 280px
ortam sorgusu karari: (min-width: 812px) -> her kart yan yana
kapsayici sorgusu karari: (min-width: 280px) -> her kart kendi kabina gore

gorus  ana bolum  yan bilgi  ana kart  yan kart  ortam sorgusu       kapsayici sorgusu
alani                                            ana / yan           ana / yan
  400        352        352       352       352  altalta / altalta   yanyana / yanyana
  720        672        672       213       213  altalta / altalta   altalta / altalta
  812        480        260       232       260  yanyana / yanyana   altalta / altalta
  900        552        276       268       276  yanyana / yanyana   altalta / altalta
 1024        635        317       201       317  yanyana / yanyana   altalta / yanyana
 1280        805        403       258       403  yanyana / yanyana   altalta / yanyana
 1600       1019        509       243       247  yanyana / yanyana   altalta / altalta

ortam sorgusunun yanlis karar verdigi durum sayisi: 10
  400px ana bolum
  400px yan bilgi
  812px ana bolum
  812px yan bilgi
  900px ana bolum
  900px yan bilgi
  1024px ana bolum
  1280px ana bolum
  1600px ana bolum
  1600px yan bilgi
```

On dört karardan onu yanlış. Bu oran, ortam sorgusunun bileşen düzeyinde kötü bir araç
olduğunu tek başına gösteriyor ama asıl ilginç olan hataların **yönü**.

İlk satır beklenenin tersini veriyor. Görüntü alanı 400 birim — dar bir ekran. Sayfa tek
sütunlu olduğu için kart ızgarası tek sütun üretiyor ve kart 352 birim genişliğinde. Kart, dar
ekranda **geniş**. Ortam sorgusu ise ekran dar olduğu için kartı alt alta diziyor.

Son satır aynı yanılgının öbür ucu. Görüntü alanı 1600 birim; ana bölüm 1019 birime çıkıyor ve
kart ızgarası dört sütun üretiyor. Her kart 243 birim: kartın kendi eşiğinin altında. Geniş
ekranda kart **dar**.

Aradaki satırlar üçüncü bir durumu gösteriyor: 1024 ve 1280 birimde ana bölümdeki kartlar dar,
yan bilgideki kart geniş. Tek bir görüntü alanı ölçüsü, aynı anda iki farklı yanıt gerektiren
iki kap içeriyor. Ortam sorgusunun verebileceği tek bir yanıt vardır ve ikisinden en az biri
yanlış olur.

Sonuç bir kuraldır: **sayfanın yapısı görüntü alanına, bileşenin biçimi kabına sorulur.**

## Kap Bildirmek

**Kapsayıcı sorgusu (container query)** iki adımdan oluşur. Önce bir öge **sorgu kabı (query
container)** ilan edilir, sonra o kabın soyundan gelen ögeler kabın ölçüsünü sorgular.

`container-type` bildirimi kabı ilan eder ve üç değeri vardır. `inline-size`, kabın yalnız
satır içi eksendeki ölçüsünü sorgulanabilir kılar. `size`, iki ekseni birden açar.
`normal` ise ölçü sorgusu açmaz; yalnız biçem sorgularına izin verir.

Bildirimin bir bedeli vardır ve bu bedel bir mantık zorunluluğudur. Kabın ölçüsü sorgulanacaksa,
o ölçü sorgunun sonucundan **etkilenmemelidir**; aksi halde döngü oluşur: kap daralır, sorgu
değişir, içerik değişir, kap genişler, sorgu değişir. Bunu engellemek için kaba **sınırlama
(containment)** uygulanır: `inline-size` değeri satır içi eksende, `size` değeri iki eksende
kabın ölçüsünü içeriğinden bağımsız kılar.

Pratik sonucu şudur: `container-type: size` yazılan bir kaba yükseklik dışarıdan verilmelidir,
yoksa yüksekliği sıfır kabul edilir. `inline-size` bu sorunu doğurmaz, çünkü satır içi ölçü
zaten çoğu zaman kapsayanından gelir. Bu yüzden yaygın olan değer `inline-size` değeridir.

İkinci bildirim `container-name`, kaba ad verir. Adsız bir sorgu **en yakın** sorgu kabını
hedefler; adlı bir sorgu, o adı taşıyan en yakın kabı arar. İç içe kaplar bulunduğunda ad,
hangisinin sorgulandığını belirsizlikten çıkarır. `container` kısayolu ikisini birlikte yazar.

Bir sınır burada belirir ve unutulduğunda şaşırtır: **bir öge kendisini sorgulayamaz.** Sorgu
kabına yazılan bildirimler kabın kendi ölçüsüne göre değişemez; yalnız soyundan gelenler
değişebilir. Bileşenin en dış ögesi bu yüzden kap olarak ilan edilir ve biçimlendirilen ögeler
onun içinde durur.

## Kapsayıcı Birimleri

Sorgunun öznesi değiştiğinde uzunluk birimlerinin de karşılığı gerekir. **Kapsayıcı birimleri
(container query units)** kabın ölçüsünün yüzde birine karşılık gelir: `cqi` satır içi eksende,
`cqb` blok eksende, `cqw` ve `cqh` fiziksel eksenlerde, `cqmin` ve `cqmax` ikisinin küçüğü ve
büyüğü.

```js
// cqbirim.mjs — kapsayici birimi (cqi) ile gorus alani biriminin (vw) karsilastirmasi
const IC_BOSLUK = 48, SAYFA_ARALIK = 24;
const ANA_EN_DAR = 480, YAN_EN_DAR = 260;
const KART = 200, KART_ARALIK = 16, KOK = 16;

function bolumler(gorusAlani) {
  if (gorusAlani < 812) return { ana: gorusAlani - IC_BOSLUK, yan: gorusAlani - IC_BOSLUK };
  let kalan = gorusAlani - IC_BOSLUK - SAYFA_ARALIK;
  let ana = (kalan * 2) / 3, yan = kalan / 3;
  if (yan < YAN_EN_DAR) { yan = YAN_EN_DAR; ana = kalan - yan; }
  return { ana, yan };
}

function kartOlcusu(kap) {
  const n = Math.max(1, Math.floor((kap + KART_ARALIK) / (KART + KART_ARALIK)));
  return (kap - KART_ARALIK * (n - 1)) / n;
}

const clamp = (k, t, b) => Math.max(k, Math.min(t, b));
const ALT = 0.875 * KOK;   // 14px
const UST = 1.25 * KOK;    // 20px
const SABIT = 0.75 * KOK;  // 12px

// cqi: kapsayicinin satir ici olcusunun yuzde biri
const cqiDeger = (kap) => clamp(ALT, SABIT + (1.5 * kap) / 100, UST);
// vw: gorus alaninin yuzde biri
const vwDeger = (gorus) => clamp(ALT, SABIT + (1.5 * gorus) / 100, UST);

console.log("font-size: clamp(0.875rem, 0.75rem + 1.5cqi, 1.25rem)   (kok 16px)");
console.log("karsilastirma: ayni ifade 1.5vw ile yazilsaydi\n");
console.log("gorus  ana kart  yan kart  cqi: ana  cqi: yan  vw: ana  vw: yan  vw ayrim yapiyor mu");
for (const W of [400, 720, 900, 1024, 1280, 1600]) {
  const { ana, yan } = bolumler(W);
  const anaKart = kartOlcusu(ana), yanKart = kartOlcusu(yan);
  const ca = cqiDeger(anaKart), cy = cqiDeger(yanKart);
  const va = vwDeger(W), vy = vwDeger(W);
  console.log(
    `${String(W).padStart(5)}  ${anaKart.toFixed(0).padStart(8)}  ${yanKart.toFixed(0).padStart(8)}  ` +
      `${ca.toFixed(2).padStart(8)}  ${cy.toFixed(2).padStart(8)}  ` +
      `${va.toFixed(2).padStart(7)}  ${vy.toFixed(2).padStart(7)}  ${(va === vy ? "hayir" : "evet").padStart(19)}`,
  );
}

console.log("\n--- ayni kart tek basina: kabin olcusu degisince cqi degeri ---");
console.log("kap olcusu  1cqi   uygulanan yazi boyutu  hangi bolge");
for (const kap of [180, 240, 300, 380, 460, 560]) {
  const bir = kap / 100;
  const d = cqiDeger(kap);
  const bolge = d === ALT ? "alt sinir" : d === UST ? "ust sinir" : "tercih edilen";
  console.log(
    `${String(kap).padStart(10)}  ${bir.toFixed(2).padStart(4)}  ${d.toFixed(2).padStart(21)}  ${bolge.padStart(11)}`,
  );
}
```

```
font-size: clamp(0.875rem, 0.75rem + 1.5cqi, 1.25rem)   (kok 16px)
karsilastirma: ayni ifade 1.5vw ile yazilsaydi

gorus  ana kart  yan kart  cqi: ana  cqi: yan  vw: ana  vw: yan  vw ayrim yapiyor mu
  400       352       352     17.28     17.28    18.00    18.00                hayir
  720       213       213     15.20     15.20    20.00    20.00                hayir
  900       268       276     16.02     16.14    20.00    20.00                hayir
 1024       201       317     15.01     16.76    20.00    20.00                hayir
 1280       258       403     15.87     18.04    20.00    20.00                hayir
 1600       243       247     15.64     15.70    20.00    20.00                hayir

--- ayni kart tek basina: kabin olcusu degisince cqi degeri ---
kap olcusu  1cqi   uygulanan yazi boyutu  hangi bolge
       180  1.80                  14.70  tercih edilen
       240  2.40                  15.60  tercih edilen
       300  3.00                  16.50  tercih edilen
       380  3.80                  17.70  tercih edilen
       460  4.60                  18.90  tercih edilen
       560  5.60                  20.00    ust sinir
```

Son sütun, görüntü alanı biriminin bileşen ölçeklemesinde neden yetersiz kaldığını gösteriyor:
`vw` iki kabı hiçbir satırda ayırt etmiyor. Aynı sayfada, aynı anda, iki farklı genişlikteki
kaba aynı değeri veriyor — üstelik 720 biriminden sonra üst sınıra dayandığı için değer hiç
değişmiyor.

Kapsayıcı birimi ise kabın ölçüsünü izliyor. 1024 birimlik görüntü alanında ana bölümdeki kart
15,01, yan bilgideki kart 16,76 birimlik yazı alıyor; ikisi de kendi genişliğine oranlı.

İkinci tablo tek bir kabın davranışını ayrıştırıyor. Kap genişledikçe `1cqi` büyür ve tercih
edilen değer yükselir; 560 birimde üst sınıra dayanır ve kelepçelenir. CSS Fonksiyonları
dersindeki üç bölgeli davranış burada da geçerlidir, yalnız girdi değişmiştir.

Bir ayrıntı: kapsayıcı birimleri hiçbir sorgu kabının içinde olmayan bir ögede kullanılırsa
görüntü alanına göre çözülür. Birim yazmak kabı ilan etmez; `container-type` bildirimi ayrıca
yazılmalıdır.

## Bileşen Kendi Eşiğini Taşır

Kapsayıcı sorgusunun asıl kazancı hesapta değil, biçem dosyasının yapısındadır.

Ortam sorgusuyla yazıldığında bileşenin eşiği, bileşenin bulunduğu **her yer** için ayrı ayrı
hesaplanmak zorundadır: ana bölümdeki kart için bir eşik, yan bilgideki kart için başka bir
eşik, sayfa düzeni değiştiğinde ikisi birden. Bileşen yeni bir yere taşındığında eşikler yeniden
hesaplanır.

Kapsayıcı sorgusuyla yazıldığında eşik bileşenin kendisine aittir ve tek bir yerde durur.
Bileşen nereye konursa konsun doğru kararı verir; sayfa düzeni değiştiğinde bileşenin biçem
kodu değişmez.

```css
/* duzen.css — 9. adım: kart kendi kabını sorgular */
.olcum-karti-kabi {
  container-type: inline-size;
  container-name: kart;
}

.olcum-karti {
  display: grid;
  gap: 0.25rem;
  font-size: clamp(0.875rem, 0.75rem + 1.5cqi, 1.25rem);
}

@container kart (min-width: 280px) {
  .olcum-karti {
    grid-template-columns: 1fr auto;
    align-items: baseline;
  }

  .olcum-karti .aciklama { grid-column: 1 / -1; }
}

@container kart (min-width: 420px) {
  .olcum-karti .egilim { display: block; }
}
```

Kabın ayrı bir öge olması bir zorunluluktur: kart, kendisini sorgulayamaz. Kap yalnız
`container-type` ve `container-name` taşır; görsel bildirimlerin tamamı içerideki `.olcum-karti`
ögesindedir.

İki eşik iki ayrı soruya karşılık geliyor. 280 birimde başlık ve değer yan yana geçiyor; 420
birimde eğilim göstergesi görünür oluyor. İkisi de görüntü alanından değil kabın genişliğinden
okunuyor ve iki farklı kapta iki farklı sonuç veriyor.

Sorgunun bir üçüncü biçimi daha vardır. Ölçü yerine bir özel özelliğin değeri sorgulanabilir;
`@container style(--durum: uyari)` yazımı, kapta tanımlı özelliğin değerine göre biçem ayırır.
Ölçü sorgusundan farkı, kabın ölçüsüne değil biçem durumuna bakmasıdır ve sınırlama gerektirmez.

## Özet

- Sayfanın yapısı görüntü alanına, bileşenin biçimi bulunduğu kaba sorulur; iki soru aynı ölçüyle
  yanıtlanamaz.
- İstasyon sayfasının kart yerleşiminde ortam sorgusu on dört karardan onunda yanlış sonuç verir;
  dar ekranda kart geniş, geniş ekranda kart dar olabilir.
- `container-type` bir ögeyi sorgu kabı yapar ve karşılığında sınırlama uygular; `size` değeri
  yüksekliğin dışarıdan verilmesini gerektirdiği için `inline-size` daha az kısıtlıdır.
- Bir öge kendisini sorgulayamaz; kap, biçimlendirilecek bileşenin dışında ayrı bir öge olarak
  ilan edilir.
- Kapsayıcı birimleri kabın ölçüsünün yüzde birine karşılık gelir ve aynı sayfadaki iki kabı
  ayırt eder; görüntü alanı birimi ayırt edemez.
- Eşik bileşenin kendisine yazıldığında bileşen taşındığında biçem kodu değişmez; ortam
  sorgusuyla yazılan eşik her yerleşim için yeniden hesaplanır.

## Sonraki Adım

Bu derste yazı boyutu bir kez kabın genişliğine bağlandı ve `clamp()` ifadesinin içine
yerleştirildi. İfadenin üç sayısı — alt sınır, tercih edilen değer, üst sınır — seçilmiş gibi
göründü ama nasıl seçildikleri söylenmedi. Sonraki ders bu üç sayıyı hesaplanabilir kılar: iki
ölçü noktası verildiğinde aradaki doğrusal geçiş nasıl kurulur, ölçek adımları arasındaki oran
dar ekranda neden daralır ve yazı boyutunun kullanıcı ayarına saygı göstermesi ne demektir?
