---
title: 'Ortam Sorguları'
source: 'https://academia.sh/tr/kurslar/duzen-ve-duyarli-tasarim/ortam-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'
---

# Ortam Sorguları

Ortam sorgusunun bileşenleri, kuralların basamaklamadaki yeri, iki aralığın ucundaki çakışma ve boşluk, sorgu birimlerinin kullanıcı yazı boyutuyla ilişkisi ve özellik sorguları.

Bir önceki ders türetilen eşiği verdi: 812 birim. Geriye bu sayının biçem dosyasında nasıl
yazılacağı kalıyor.

Koşullu biçemin aracı **ortam sorgusudur (media query)**. Sorgu bir soru sorar, yanıt doğruysa
içindeki kurallar hesaba katılır. Bu ders sorunun neye bakabildiğini, kuralların basamaklamada
nereye oturduğunu ve iki aralığın birleştiği noktada ne olduğunu ele alır.

## Sorgunun Bileşenleri

Bir ortam sorgusu üç parçadan kurulur.

**Ortam türü (media type)**, çıktının hangi ortama gittiğini söyler: `screen` ekran, `print`
yazdırma ya da yazdırma önizlemesi, `all` her ikisi. Yazılmazsa `all` varsayılır.

**Ortam özelliği (media feature)**, ortamın ölçülebilir bir niteliğini sınar ve parantez içinde
yazılır. En sık kullanılanlar `width` ve `height`; bunların yanında ekranın yönünü veren
`orientation`, en boy oranını veren `aspect-ratio`, piksel yoğunluğunu veren `resolution`
bulunur. Bir başka grup, ekran ölçüsünü değil giriş yeteneğini sınar: `pointer` işaretleme
aygıtının inceliğini, `hover` üzerine gelme davranışının bulunup bulunmadığını bildirir.

**Mantıksal işleçler.** `and` iki koşulu birlikte ister, virgül ise "ya da" anlamındadır; virgülle
ayrılmış dallardan biri doğruysa sorgu doğrudur. `not` bir sorguyu tersine çevirir.

Özellik sınamasının iki yazımı vardır. Eskisi `min-` ve `max-` öneklerini kullanır ve **kapalı
aralık** üretir: `(min-width: 812px)` bildirimi "genişlik 812'ye eşit ya da büyük" demektir.
Yenisi karşılaştırma işleçlerini doğrudan yazar: `(width >= 812px)`. İkinci yazım açık aralık
da kurabilir ve iki sınırı tek koşulda birleştirebilir.

## Değerlendirme ve Basamaklama

Sorgunun sonucu ile kuralın uygulanması iki ayrı adımdır. Sorgu doğruysa içindeki kurallar
basamaklamaya **katılır**; hangi bildirimin kazandığına basamaklama karar verir.

Burada sık yapılan bir varsayım yanlıştır: ortam sorgusu özgüllük **eklemez**. Sorgunun içindeki
`.istasyon-duzeni` seçicisi ile dışındaki `.istasyon-duzeni` seçicisi aynı özgüllüktedir; ikisi
çakıştığında sonra yazılan kazanır.

```js
// sorgu.mjs — ortam sorgusu degerlendiricisi ve basamaklama sonucu
// Desteklenen yazimlar: (min-width: Npx), (max-width: Npx), (width >= Npx),
// (Npx <= width < Mpx), (orientation: portrait|landscape), and, virgul, not.

function ozellikDegeri(ad, ortam) {
  if (ad === "width") return ortam.genislik;
  if (ad === "height") return ortam.yukseklik;
  if (ad === "orientation") return ortam.genislik >= ortam.yukseklik ? "landscape" : "portrait";
  throw new Error(`bilinmeyen ozellik: ${ad}`);
}

function ozellik(metin, ortam) {
  const s = metin.trim().replace(/^\(/, "").replace(/\)$/, "").trim();

  let m = s.match(/^(\d+(?:\.\d+)?)px\s*(<=|<)\s*([a-z-]+)\s*(<=|<)\s*(\d+(?:\.\d+)?)px$/);
  if (m) {
    const v = ozellikDegeri(m[3], ortam);
    const altOk = m[2] === "<=" ? Number(m[1]) <= v : Number(m[1]) < v;
    const ustOk = m[4] === "<=" ? v <= Number(m[5]) : v < Number(m[5]);
    return altOk && ustOk;
  }

  m = s.match(/^([a-z-]+)\s*(>=|<=|>|<)\s*(\d+(?:\.\d+)?)px$/);
  if (m) {
    const v = ozellikDegeri(m[1], ortam);
    const n = Number(m[3]);
    return m[2] === ">=" ? v >= n : m[2] === "<=" ? v <= n : m[2] === ">" ? v > n : v < n;
  }

  m = s.match(/^(min-|max-)?([a-z-]+)\s*:\s*(.+)$/);
  if (m) {
    const v = ozellikDegeri(m[2], ortam);
    const hedef = m[3].endsWith("px") ? Number(m[3].slice(0, -2)) : m[3];
    if (m[1] === "min-") return v >= hedef;
    if (m[1] === "max-") return v <= hedef;
    return v === hedef;
  }

  throw new Error(`cozulemeyen kosul: ${s}`);
}

function sorguEslesir(sorgu, ortam) {
  return sorgu.split(",").some((dal) => {
    const parcalar = dal.trim().split(/\s+and\s+/);
    const olumsuz = parcalar[0].startsWith("not ");
    parcalar[0] = parcalar[0].replace(/^not\s+/, "");
    const sonuc = parcalar.every((p) => ozellik(p, ortam));
    return olumsuz ? !sonuc : sonuc;
  });
}

const ortamlar = [
  { ad: "dar dikey", genislik: 380, yukseklik: 780 },
  { ad: "orta dikey", genislik: 720, yukseklik: 1024 },
  { ad: "esik ustu", genislik: 812, yukseklik: 1000 },
  { ad: "genis yatay", genislik: 1280, yukseklik: 800 },
  { ad: "alcak yatay", genislik: 900, yukseklik: 420 },
];

const kurallar = [
  { sorgu: null, deger: "tek sutun" },
  { sorgu: "(min-width: 812px)", deger: "iki sutun" },
  { sorgu: "(min-width: 1200px)", deger: "iki sutun + genis kenar" },
  { sorgu: "(orientation: landscape) and (max-height: 480px)", deger: "sikisik baslik" },
];

console.log("--- kurallar kaynak sirasinda, sonuncu eslesen kazanir ---");
kurallar.forEach((k, i) => console.log(`${i + 1}. ${k.sorgu ?? "(taban, sorgusuz)"} -> ${k.deger}`));

console.log("\nortam            genislik  yukseklik  eslesen kurallar  uygulanan");
for (const o of ortamlar) {
  const eslesen = kurallar
    .map((k, i) => (k.sorgu === null || sorguEslesir(k.sorgu, o) ? i + 1 : null))
    .filter((x) => x !== null);
  const kazanan = kurallar[eslesen[eslesen.length - 1] - 1].deger;
  console.log(
    `${o.ad.padEnd(15)}  ${String(o.genislik).padStart(8)}  ${String(o.yukseklik).padStart(9)}  ` +
      `${eslesen.join(",").padStart(16)}  ${kazanan}`,
  );
}

console.log("\n--- iki araligin ucundaki genislik ---");
const cift = [
  ["(max-width: 812px)", "(min-width: 812px)"],
  ["(max-width: 811.98px)", "(min-width: 812px)"],
  ["(width < 812px)", "(width >= 812px)"],
];
for (const [a, b] of cift) {
  console.log(`\n${a}  |  ${b}`);
  console.log("genislik  ilk  ikinci  durum");
  for (const g of [811, 811.99, 812, 813]) {
    const o = { genislik: g, yukseklik: 900 };
    const x = sorguEslesir(a, o);
    const y = sorguEslesir(b, o);
    const durum = x && y ? "IKISI DE eslesti" : x || y ? "tek kural" : "HICBIRI eslesmedi";
    console.log(
      `${String(g).padStart(8)}  ${String(x).padStart(5)}  ${String(y).padStart(6)}  ${durum}`,
    );
  }
}
```

```
--- kurallar kaynak sirasinda, sonuncu eslesen kazanir ---
1. (taban, sorgusuz) -> tek sutun
2. (min-width: 812px) -> iki sutun
3. (min-width: 1200px) -> iki sutun + genis kenar
4. (orientation: landscape) and (max-height: 480px) -> sikisik baslik

ortam            genislik  yukseklik  eslesen kurallar  uygulanan
dar dikey             380        780                 1  tek sutun
orta dikey            720       1024                 1  tek sutun
esik ustu             812       1000               1,2  iki sutun
genis yatay          1280        800             1,2,3  iki sutun + genis kenar
alcak yatay           900        420             1,2,4  sikisik baslik

--- iki araligin ucundaki genislik ---

(max-width: 812px)  |  (min-width: 812px)
genislik  ilk  ikinci  durum
     811   true   false  tek kural
  811.99   true   false  tek kural
     812   true    true  IKISI DE eslesti
     813  false    true  tek kural

(max-width: 811.98px)  |  (min-width: 812px)
genislik  ilk  ikinci  durum
     811   true   false  tek kural
  811.99  false   false  HICBIRI eslesmedi
     812  false    true  tek kural
     813  false    true  tek kural

(width < 812px)  |  (width >= 812px)
genislik  ilk  ikinci  durum
     811   true   false  tek kural
  811.99   true   false  tek kural
     812  false    true  tek kural
     813  false    true  tek kural
```

Birinci tablo eşleşmenin biriktiğini gösteriyor. 1280 birimlik bir ortamda üç kural birden
doğrudur; uygulanan değer, doğru olanların **sonuncusudur**. Bu, kuralların yazım sırasının
anlam taşıdığı anlamına gelir: aynı bildirimi hedefleyen sorgular dar aralıktan geniş aralığa
doğru sıralanmazsa geniş aralığın kuralı dar aralığınki tarafından ezilir.

Dördüncü kural farklı bir eksende çalışıyor. 900 birim genişliğindeki alçak bir ortamda hem
genişlik koşulu hem yön ve yükseklik koşulu doğru; sonuncusu kazanıyor. Genişlik tek ölçü
değildir: yatay tutulan ve dikeyde yeri kısıtlı bir ortamda başlığın alçalması, genişlikle
ilgisi olmayan bir karardır.

## Aralıkların Ucu

İkinci bölüm, iki komşu aralığın birleştiği noktayı üç yazımla sınıyor.

Birinci çift klasik hatadır. `max-width: 812px` ve `min-width: 812px` yazımlarının ikisi de
812 birimde doğrudur, çünkü iki önek de **kapalı** sınır üretir. Tam o genişlikte iki kural
birden uygulanır ve sonuç kaynak sırasına kalır. Hata görünmez olabilir — sonuç zaten
istenen kural olabilir — ama bildirimler farklıysa ikisinin karışımı uygulanır.

İkinci çift, sık önerilen düzeltmeyi deniyor: üst sınırı biraz aşağı çekmek. Çakışma
kalkıyor ama yerine bir **boşluk** geliyor. 811.99 birimlik bir genişlikte hiçbir kural
eşleşmiyor. Kesirli genişlikler kuramsal bir olasılık değildir; yakınlaştırma ve
ölçeklendirme kesirli CSS piksel değerleri üretir.

Üçüncü çift, karşılaştırma yazımıyla aralığı gerçekten böler. `(width < 812px)` ve
`(width >= 812px)` birbirini dışlar ve birlikte bütün sayı doğrusunu kaplar. Ne çakışma ne
boşluk kalır.

En sağlam yol, ikinci aralığı hiç yazmamaktır. Taban biçem dar düzeni tarif ediyorsa yalnız
`(min-width: 812px)` yazılır; alt aralık için kural gerekmez ve uç noktası sorunu doğmaz.

## Sorgudaki Birim

Uzunluk yazılan her yerde birim seçimi bir karardır. Ortam sorgusunda bu kararın alışılmadık
bir sonucu vardır: sorgudaki `em`, kök ögeye yazılan yazı boyutuna göre değil, **kullanıcının
varsayılan yazı boyutuna** göre çözülür.

```js
// birim.mjs — ortam sorgusundaki uzunluk biriminin kullanici yazi boyutuyla iliskisi
// Sorgudaki em, kok ogeye yazilan font-size'a degil, kullanicinin varsayilan
// yazi boyutuna gore cozulur.

// 16px varsayilanda olculen icerik gereksinimleri
const ANA = 480, YAN = 260, ARALIK = 24, IC_BOSLUK = 48;
const TABAN = 16;
const GEREKEN_16 = ANA + YAN + ARALIK + IC_BOSLUK;

const emEsik = GEREKEN_16 / TABAN;   // ayni esigin em karsiligi
const pxEsik = GEREKEN_16;

console.log(`16px varsayilanda iki sutun icin gereken genislik: ${GEREKEN_16}px`);
console.log(`px yazilirsa: (min-width: ${pxEsik}px)`);
console.log(`em yazilirsa: (min-width: ${emEsik}em)\n`);

console.log("kullanici  gereken   px sorgusu  em sorgusu  px ile sapma  em ile sapma");
console.log("varsayilan genislik  tetiklenir  tetiklenir");
for (const d of [12, 16, 20, 24, 32]) {
  const gereken = (GEREKEN_16 * d) / TABAN;   // butun olculer rem tabanli oldugu icin olceklenir
  const pxTetik = pxEsik;
  const emTetik = emEsik * d;
  console.log(
    `${String(d + "px").padStart(10)}  ${gereken.toFixed(0).padStart(8)}  ` +
      `${pxTetik.toFixed(0).padStart(10)}  ${emTetik.toFixed(0).padStart(10)}  ` +
      `${(pxTetik - gereken).toFixed(0).padStart(12)}  ${(emTetik - gereken).toFixed(0).padStart(12)}`,
  );
}

console.log("\n--- 20px varsayilanda 812px genisliginde ne oluyor ---");
const d = 20;
const olcek = d / TABAN;
const alan = 812 - IC_BOSLUK * olcek - ARALIK * olcek;
const ana = (alan * 2) / 3, yan = alan / 3;
console.log(`ana bolum: ${ana.toFixed(1)}px  (gereken ${(ANA * olcek).toFixed(1)}px)`);
console.log(`yan bilgi: ${yan.toFixed(1)}px  (gereken ${(YAN * olcek).toFixed(1)}px)`);
console.log(`px sorgusu bu genislikte iki sutunu acar; em sorgusu ${(emEsik * d).toFixed(0)}px degerine kadar beklemis olur`);
```

```
16px varsayilanda iki sutun icin gereken genislik: 812px
px yazilirsa: (min-width: 812px)
em yazilirsa: (min-width: 50.75em)

kullanici  gereken   px sorgusu  em sorgusu  px ile sapma  em ile sapma
varsayilan genislik  tetiklenir  tetiklenir
      12px       609         812         609           203             0
      16px       812         812         812             0             0
      20px      1015         812        1015          -203             0
      24px      1218         812        1218          -406             0
      32px      1624         812        1624          -812             0

--- 20px varsayilanda 812px genisliginde ne oluyor ---
ana bolum: 481.3px  (gereken 600.0px)
yan bilgi: 240.7px  (gereken 325.0px)
px sorgusu bu genislikte iki sutunu acar; em sorgusu 1015px degerine kadar beklemis olur
```

Sağdaki iki sütun karşılaştırmayı tek başına yapıyor. Kullanıcı varsayılan yazı boyutunu
değiştirdiğinde bütün ölçüler taban birime bağlı olduğu için birlikte büyür; iki sütunun
gerektirdiği genişlik de büyür. Piksel yazılan sorgu bu değişimi göremez ve eşiği yerinde
bırakır: 20 birimlik bir varsayılanda düzen, ihtiyacın 203 birim altında iki sütuna geçer.
Taban birim yazılan sorgu ihtiyaçla birlikte kayar ve sapma her satırda sıfır kalır.

Son blok, sapmanın somut karşılığını veriyor: eşik erken tetiklendiğinde ana bölüm 481, yan
bilgi 241 birime düşer; oysa büyütülmüş yazıyla aynı içeriğin 600 ve 325 birime ihtiyacı
vardır. Yazı büyütmek, sayfayı okunur kılmak için yapılan bir ayardır; düzen bu ayarı ölçeğe
katmazsa ayarın kendisi sonucu bozar.

Kural şudur: ortam sorgusunda uzunluk taban birimle yazılır. Aynı gerekçe yükseklik ve en boy
oranı sınamaları için de geçerlidir.

## Ortam Türleri ve Özellik Sorguları

Genişlik dışındaki iki sınama, ortam sorgularının yalnız ekran ölçüsüyle ilgili olmadığını
gösterir.

`@media print` kuralları yazdırma çıktısına uygulanır. Yazdırılan bir ölçüm sayfasında gezinme
çubuğunun, süzgeç alanının ve bağlantı süslemelerinin yeri yoktur; buna karşılık bağlantı
adreslerinin metne yazılması ve sayfa kırılmalarının denetlenmesi gerekir. Çok sütunlu düzen
dersinde tanıtılan `break-inside` bildirimi burada da çalışır.

Ortam sorgularından ayrı ama aynı biçimde yazılan ikinci bir yapı, **özellik sorgusudur
(feature query)**. `@supports` bir bildirimin tanınıp tanınmadığını sınar; ortamı değil, biçem
dilinin çözülmesini sorgular. Izgara ve Esnek Kutu Seçimi dersinde bırakılan soru buradan
yanıtlanır: `subgrid` değerinin tanındığı yerde iç ızgara kapsayanın hatlarını devralır,
tanınmadığı yerde kendi şeritlerini tanımlar.

```css
/* duzen.css — 8. adım: türetilen eşik ve yazdırma */
@media (min-width: 50.75em) {
  .istasyon-duzeni {
    grid-template-columns: minmax(480px, 2fr) minmax(260px, 1fr);
    grid-template-areas:
      "kunye     kunye"
      "olcumler  yan-bilgi"
      "konum     yan-bilgi";
  }
}

@supports (grid-template-columns: subgrid) {
  .olcum-karti {
    display: grid;
    grid-template-rows: subgrid;
    grid-row: span 3;
  }
}

@media print {
  .gezinme,
  .olcum-suzgeci { display: none; }

  .istasyon-duzeni {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "kunye" "olcumler" "konum" "yan-bilgi";
  }

  .olcum-cizelgesi tr { break-inside: avoid; }
}
```

Üç blok, üç ayrı soru soruyor. Birincisi ortamın genişliğini sınıyor ve yalnız yapıyı
değiştiriyor; ölçüler taban biçemdeki iç boyutlandırmadan geliyor. İkincisi bir bildirimin
tanınıp tanınmadığını sınıyor ve tanınıyorsa kart satırlarını dış ızgaranın hatlarına
bağlıyor. Üçüncüsü çıktının nereye gittiğini sınıyor.

Üçünün ortak yanı, hiçbirinin taban biçemde yazılanı geri almamasıdır. Her blok kendi
koşulunda yeni bir bildirim ekler.

## Özet

- Ortam sorgusu ortam türü, parantez içinde yazılan ortam özellikleri ve `and`, virgül, `not`
  işleçlerinden kurulur; yazılmayan tür `all` sayılır.
- Sorgu özgüllük eklemez; içindeki kurallar dışarıdakilerle aynı özgüllükte yarışır ve
  çakışmayı kaynak sırası çözer.
- `min-` ve `max-` önekleri kapalı sınır üretir: aynı sayıya yazılan iki sorgu o noktada
  birlikte eşleşir; sınırı kesirle kaydırmak çakışmayı boşluğa çevirir.
- Karşılaştırma yazımı aralığı çakışmasız ve boşluksuz böler; tek yönlü tek bir sorgu yazmak
  ise sorunu tamamen ortadan kaldırır.
- Sorgudaki taban birim kullanıcının varsayılan yazı boyutuna göre çözülür ve eşiği içerikle
  birlikte kaydırır; piksel yazılan eşik bu ayarı göremez.
- `@media print` çıktının ortamını, `@supports` biçem dilinin bir bildirimi tanıyıp
  tanımadığını sınar; ikisi de taban biçemi geri almadan bildirim ekler.

## Sonraki Adım

Bu dersteki bütün sorgular tek bir şeye bakıyordu: görüntü alanının kendisi. Oysa ölçüm
kartının nasıl görünmesi gerektiğini belirleyen, ekranın genişliği değil kartın **içine
yerleştirildiği yerin** genişliğidir. Aynı kart geniş bir ekranda dar bir yan sütunda
durabilir; görüntü alanı geniş olduğu için kart geniş düzenini açar ve sıkışır. Sonraki ders
sorunun öznesini değiştirir: bir bileşen, bulunduğu kabın ölçüsünü nasıl sorgular?
