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

# Duyarlı Tasarım İlkesi

Duyarlılığın üç bileşeni, kesme noktalarının içerikten hesapla türetilmesi, iç boyutlandırmayla kendiliğinden çözülen eşikler ve şerit tanımının eşiği nasıl kaydırdığı.

Çok sütunlu düzen dersinde bir karar sessizce verildi: sütun genişliği kapsayıcıya sığmadığında
sütun sayısı düşürüldü. Eşik, bir ekran genişliği listesinden değil, metnin okunabilir kaldığı
en dar ölçüden geldi.

Bu ders aynı akıl yürütmeyi sayfanın bütününe taşır. Bir düzenin hangi genişlikte değişmesi
gerektiği hesaplanabilir bir sorudur; yanıtı aygıt adlarında değil, içeriğin kendi
ölçülerindedir.

## Duyarlılığın Üç Bileşeni

**Duyarlı tasarım (responsive design)** tek bir bildirimin adı değildir; üç davranışın birlikte
bulunmasıdır.

**Akışkan ızgara (fluid grid).** Düzenin ölçüleri sabit uzunluklarla değil, oranlarla ve
kalan alanla verilir. `fr`, yüzde, `minmax()` ve `auto` bu işi görür; sabit piksel genişlikler
yalnız gerçekten sabit olması gereken yerlerde kalır.

**Esnek medya.** Görsel ve gömülü içerik kapsayıcısını aşmaz; ölçüsü kendi doğal boyutu değil,
kapsayıcının bıraktığı yerdir.

**Koşullu biçem.** Yukarıdaki ikisi tek başına yetmediğinde — düzenin yapısı değişmek zorunda
olduğunda — biçem bir koşula bağlanır.

Sıralama önemlidir. İlk iki bileşen ne kadar iş görürse, üçüncüsüne o kadar az iş kalır.
Sorguyla yazılan her koşul, biçem dosyasında bakımı gereken bir daldır; iç boyutlandırmayla
çözülen her eşik ise dosyada hiç görünmez.

## Kesme Noktası Bir Ölçüdür

**Kesme noktası (breakpoint)**, düzenin yapısının değiştiği genişliktir. Sorunun doğru
sorulması şöyledir: bu bileşen, anlamını yitirmeden ne kadar daralabilir? Yanıt bir sayıdır ve
bileşenin içeriğinden gelir.

Aşağıdaki program, ölçüm istasyonu sayfasının üç bileşeni için bu sayıyı hesaplıyor.

```js
// kesme.mjs — kesme noktalarinin icerikten turetilmesi
// Sayfanin yatay ic bosluklari her iki yanda 24px.
const IC_BOSLUK = 24 * 2;

// 1) Metin sutunu: govde yazisi 18px, ortalama karakter genisligi 0.5em -> 9px/karakter
const KARAKTER = 9;
const OLCU_ALT = 45;   // okunabilir en az karakter
const OLCU_UST = 75;   // okunabilir en cok karakter
const metinAlt = OLCU_ALT * KARAKTER;
const metinUst = OLCU_UST * KARAKTER;

// 2) Olcum kartlari: bir kartin anlamli kaldigi en dar olcu ve aralik
const KART = 200;
const KART_ARALIK = 16;
const kartEsik = (n) => n * (KART + KART_ARALIK) - KART_ARALIK;

// 3) Sayfa duzeni: ana bolum ve yan bilgi yan yana durabilmek icin kendi en dar olculeri
const ANA_EN_DAR = 480;
const YAN_EN_DAR = 260;
const SAYFA_ARALIK = 24;
const ikiSutunEsik = ANA_EN_DAR + YAN_EN_DAR + SAYFA_ARALIK;

console.log("--- 1) metin sutunu ---");
console.log(`govde yazisi 18px, 1 karakter ~ ${KARAKTER}px`);
console.log(`olcu ${OLCU_ALT}-${OLCU_UST} karakter -> sutun ${metinAlt}-${metinUst}px`);
console.log(`gorus alani karsiligi: ${metinAlt + IC_BOSLUK}-${metinUst + IC_BOSLUK}px`);
console.log(`ust sinir asildiginda satir uzar: esik ${metinUst + IC_BOSLUK}px`);

console.log("\n--- 2) olcum kartlari ---");
console.log(`kart en dar ${KART}px, aralik ${KART_ARALIK}px`);
console.log("sutun  gereken icerik alani  gorus alani esigi");
for (let n = 1; n <= 5; n++) {
  console.log(
    `${String(n).padStart(5)}  ${String(kartEsik(n)).padStart(20)}  ${String(kartEsik(n) + IC_BOSLUK).padStart(18)}`,
  );
}

console.log("\n--- 3) sayfa duzeni ---");
console.log(`ana bolum en dar ${ANA_EN_DAR}px + yan bilgi en dar ${YAN_EN_DAR}px + aralik ${SAYFA_ARALIK}px`);
console.log(`iki sutunun mumkun oldugu en dar icerik alani: ${ikiSutunEsik}px`);
console.log(`gorus alani esigi (alt sinir): ${ikiSutunEsik + IC_BOSLUK}px`);

console.log("\n--- turetilen esiklerin tamami ---");
const esikler = [
  { ad: "kart 2 sutun", px: kartEsik(2) + IC_BOSLUK, sorgu: false },
  { ad: "kart 3 sutun", px: kartEsik(3) + IC_BOSLUK, sorgu: false },
  { ad: "metin ust siniri", px: metinUst + IC_BOSLUK, sorgu: false },
  { ad: "sayfa iki sutun*", px: ikiSutunEsik + IC_BOSLUK, sorgu: true },
  { ad: "kart 4 sutun", px: kartEsik(4) + IC_BOSLUK, sorgu: false },
  { ad: "kart 5 sutun", px: kartEsik(5) + IC_BOSLUK, sorgu: false },
];
esikler.sort((a, b) => a.px - b.px);
console.log("esik(px)  bilesen              sorgu gerekiyor mu");
for (const e of esikler) {
  console.log(
    `${String(e.px).padStart(8)}  ${e.ad.padEnd(20)} ${e.sorgu ? "evet" : "hayir (ic boyutlandirma yeter)"}`,
  );
}
const yazilacak = esikler.filter((e) => e.sorgu);
console.log(`\ntoplam esik: ${esikler.length}, yazilacak sorgu: ${yazilacak.length} (${yazilacak.map((e) => e.px + "px").join(", ")})`);
console.log("* en dar olculerin toplamindan gelen alt sinir; serit tanimina gore yukari cikar");
```

```
--- 1) metin sutunu ---
govde yazisi 18px, 1 karakter ~ 9px
olcu 45-75 karakter -> sutun 405-675px
gorus alani karsiligi: 453-723px
ust sinir asildiginda satir uzar: esik 723px

--- 2) olcum kartlari ---
kart en dar 200px, aralik 16px
sutun  gereken icerik alani  gorus alani esigi
    1                   200                 248
    2                   416                 464
    3                   632                 680
    4                   848                 896
    5                  1064                1112

--- 3) sayfa duzeni ---
ana bolum en dar 480px + yan bilgi en dar 260px + aralik 24px
iki sutunun mumkun oldugu en dar icerik alani: 764px
gorus alani esigi (alt sinir): 812px

--- turetilen esiklerin tamami ---
esik(px)  bilesen              sorgu gerekiyor mu
     464  kart 2 sutun         hayir (ic boyutlandirma yeter)
     680  kart 3 sutun         hayir (ic boyutlandirma yeter)
     723  metin ust siniri     hayir (ic boyutlandirma yeter)
     812  sayfa iki sutun*     evet
     896  kart 4 sutun         hayir (ic boyutlandirma yeter)
    1112  kart 5 sutun         hayir (ic boyutlandirma yeter)

toplam esik: 6, yazilacak sorgu: 1 (812px)
* en dar olculerin toplamindan gelen alt sinir; serit tanimina gore yukari cikar
```

Üç bileşen, üç ayrı ölçü kaynağı.

Metin sütununun ölçüsü tipografiden gelir. Bir satırda 45 karakterin altına inildiğinde göz
çok sık satır atlar, 75 karakterin üstüne çıkıldığında satır sonundan sonrakinin başına dönmek
zorlaşır. On sekiz taban ölçüsündeki bir gövde yazısında karakter genişliği yaklaşık dokuz
birimdir; iki sınır 405 ve 675 birime karşılık gelir.

Kartların ölçüsü içeriğin kendisinden gelir: bir ölçüm kartında başlık, değer ve birim yan yana
okunabilmelidir ve bu 200 birimin altında bozulur. Kaç sütun sığdığı buradan çıkar.

Sayfa düzeninin ölçüsü iki bölümün ölçülerinin toplamıdır. Yan yana durabilmeleri için gereken
en dar alan, ikisinin en dar ölçüsü ile aralarındaki boşluğun toplamıdır.

Elde edilen liste altı eşik içeriyor ve hiçbiri bir aygıt adıyla anılmıyor. Sayılar tuhaf: 464,
680, 723, 812. Bu tuhaflık bir kusur değil, ölçünün gerçekten içerikten geldiğinin işaretidir.

## Yazılmayan Eşikler

Altı eşikten yalnız biri koşullu biçem gerektiriyor. Kalan beşi, önceki derslerde kurulan
**iç boyutlandırma (intrinsic sizing)** araçlarıyla kendiliğinden karşılanır.

Kart ızgarası `repeat(auto-fill, minmax(200px, 1fr))` yazımıyla tanımlıdır. Sütun sayısı
kapsayıcı genişliğinden hesaplanır ve 464, 680, 896, 1112 eşikleri hesabın doğal sonucu olarak
geçilir. Bu eşikleri sorguyla yazmak aynı hesabı ikinci kez, elle yapmak olurdu.

Metin sütununun üst sınırı `max-inline-size` ile verilir; ölçü 675 birimi aşmaz, kalan alan dış
boşluğa gider. Bunun için de koşul gerekmez.

Geriye sayfa düzeninin kendisi kalır. `grid-template-areas` bildirimi bir yapıdır, bir ölçü
değil; iki sütunlu yerleşimden tek sütunluya geçmek bildirimin **başka bir bildirimle
değiştirilmesini** gerektirir. Iç boyutlandırma bir ölçüyü hesaplayabilir, bir yapıyı
seçemez.

Ölçüt buradan çıkar: **ölçü değişiyorsa iç boyutlandırma, yapı değişiyorsa koşullu biçem.**

## Şerit Tanımı Eşiği Kaydırır

Yukarıdaki 812 sayısı en dar ölçülerin toplamıdır ve bir alt sınırdır. Gerçek eşik, şeritlerin
nasıl tanımlandığına bağlıdır.

```js
// liste.mjs — esigin nereden geldigi: serit tanimina gore turetme
const IC_BOSLUK = 48;      // sayfanin iki yanindaki ic bosluk toplami
const ARALIK = 24;         // iki sutun arasindaki aralik
const ANA_EN_DAR = 480;    // ana bolumun anlamli kaldigi en dar olcu
const YAN_EN_DAR = 260;    // yan bilginin anlamli kaldigi en dar olcu

// minmax(alt, Nfr) seritlerinin olculmesi: pay alt sinirin altinda kalirsa
// serit alt sinirda dondurulur, kalan alan yeniden bolusturulur.
function seritler(gorusAlani, tanim) {
  let kalan = gorusAlani - IC_BOSLUK - ARALIK;
  const sonuc = tanim.map((t) => ({ ...t, olcu: null }));
  let degisti = true;
  while (degisti) {
    degisti = false;
    const acik = sonuc.filter((t) => t.olcu === null);
    const frToplam = acik.reduce((s, t) => s + t.fr, 0);
    for (const t of acik) {
      const pay = (kalan * t.fr) / frToplam;
      if (pay < t.alt) {
        t.olcu = t.alt;
        kalan -= t.alt;
        degisti = true;
        break;
      }
    }
    if (!degisti) for (const t of acik) t.olcu = (kalan * t.fr) / frToplam;
  }
  return sonuc;
}

const tanimlar = [
  ["minmax(0, 2fr) minmax(0, 1fr)", [{ ad: "ana", fr: 2, alt: 0 }, { ad: "yan", fr: 1, alt: 0 }]],
  ["minmax(480px, 2fr) minmax(260px, 1fr)",
    [{ ad: "ana", fr: 2, alt: ANA_EN_DAR }, { ad: "yan", fr: 1, alt: YAN_EN_DAR }]],
];

for (const [ad, tanim] of tanimlar) {
  console.log(`--- ${ad} ---`);
  console.log("gorus alani  ana sutun  yan sutun  ana yeterli  yan yeterli  toplam tasma");
  for (const W of [768, 812, 852, 900, 1024]) {
    const s = seritler(W, tanim);
    const ana = s[0].olcu, yan = s[1].olcu;
    const tasma = ana + yan + ARALIK - (W - IC_BOSLUK);
    console.log(
      `${String(W).padStart(11)}  ${ana.toFixed(1).padStart(9)}  ${yan.toFixed(1).padStart(9)}  ` +
        `${(ana >= ANA_EN_DAR ? "evet" : "HAYIR").padStart(11)}  ` +
        `${(yan >= YAN_EN_DAR ? "evet" : "HAYIR").padStart(11)}  ${tasma.toFixed(1).padStart(12)}`,
    );
  }
  // her iki serit de en dar olcusunu tasmasiz karsilayan ilk genislik
  let esik = 300;
  while (esik < 2000) {
    const s = seritler(esik, tanim);
    const tasma = s[0].olcu + s[1].olcu + ARALIK - (esik - IC_BOSLUK);
    if (s[0].olcu >= ANA_EN_DAR && s[1].olcu >= YAN_EN_DAR && tasma <= 0.001) break;
    esik += 1;
  }
  console.log(`turetilen kesme noktasi: ${esik}px\n`);
}

console.log("--- aygit adlarindan gelen bir esik ile karsilastirma ---");
const HAZIR = 768;
for (const [ad, tanim] of tanimlar) {
  const s = seritler(HAZIR, tanim);
  const tasma = s[0].olcu + s[1].olcu + ARALIK - (HAZIR - IC_BOSLUK);
  const dar = s[0].olcu < ANA_EN_DAR || s[1].olcu < YAN_EN_DAR;
  const tani = dar ? "seritler en dar olcunun altinda" : `seritler yeterli ama ${tasma.toFixed(0)}px tasma var`;
  console.log(`${HAZIR}px, ${ad}`);
  console.log(`  ana ${s[0].olcu.toFixed(1)}  yan ${s[1].olcu.toFixed(1)}  -> ${tani}`);
}
```

```
--- minmax(0, 2fr) minmax(0, 1fr) ---
gorus alani  ana sutun  yan sutun  ana yeterli  yan yeterli  toplam tasma
        768      464.0      232.0        HAYIR        HAYIR           0.0
        812      493.3      246.7         evet        HAYIR           0.0
        852      520.0      260.0         evet         evet           0.0
        900      552.0      276.0         evet         evet           0.0
       1024      634.7      317.3         evet         evet           0.0
turetilen kesme noktasi: 852px

--- minmax(480px, 2fr) minmax(260px, 1fr) ---
gorus alani  ana sutun  yan sutun  ana yeterli  yan yeterli  toplam tasma
        768      480.0      260.0         evet         evet          44.0
        812      480.0      260.0         evet         evet           0.0
        852      520.0      260.0         evet         evet           0.0
        900      552.0      276.0         evet         evet           0.0
       1024      634.7      317.3         evet         evet           0.0
turetilen kesme noktasi: 812px

--- aygit adlarindan gelen bir esik ile karsilastirma ---
768px, minmax(0, 2fr) minmax(0, 1fr)
  ana 464.0  yan 232.0  -> seritler en dar olcunun altinda
768px, minmax(480px, 2fr) minmax(260px, 1fr)
  ana 480.0  yan 260.0  -> seritler yeterli ama 44px tasma var
```

İki tanım, iki farklı eşik.

Birinci tanımda oran kilitlidir: yan bilgi her genişlikte kalanın üçte birini alır. Yan
bilginin 260 birime ulaşması için üçte birin 260 olması gerekir; eşik 852 birime çıkar. Alt
sınırların toplamı olan 812 burada yetmez, çünkü ana bölüm ihtiyacından fazlasını almaktadır.

İkinci tanımda alt sınırlar şeride yazılıdır. Şeritler önce en dar ölçülerine oturur, artan
alan orana göre bölüşülür. Eşik alt sınırların toplamına, yani 812 birime iner. Bu tanım
sayfaya 40 birim genişlik kazandırır ve kesme noktasını hesabın ilk sonucuyla aynı yere getirir.

Son blok, eşiğin dışarıdan seçilmesinin iki ayrı biçimde nasıl kırıldığını gösteriyor. Aygıt
adlarından gelen 768 birimlik eşikte birinci tanımda şeritler en dar ölçünün altında kalır:
düzen uygulanır ama içerik sıkışır. İkinci tanımda şeritler alt sınırlarını korur, bu kez
toplamları kapsayıcıyı 44 birim aşar: yatay taşma oluşur.

İki sonuç da aynı nedenden doğar. Eşik içerikten türetilmediğinde, ölçüler ile eşik arasındaki
bağ kopar ve hata ya sıkışma ya taşma olarak görünür.

## Dar Taraftan Başlamak

Kesme noktası bulunduktan sonra bir yazım kararı kalır: taban biçem hangi düzeni tarif etsin?

Taban biçem **dar** düzeni tarif ediyorsa, koşul genişledikçe eklenir. Tek sütunlu yerleşim
zaten yazılıdır; koşul yalnız ikinci sütunu kurar.

Taban biçem **geniş** düzeni tarif ediyorsa, koşul daraldıkça eklenir ve her koşulun içinde
tabanın kurduğu şeyi **geri alan** bildirimler bulunur: alan adlarını sıfırlamak, şerit sayısını
bire indirmek, dış boşlukları küçültmek.

Dar taraftan başlamak, geri alma bildirimlerini ortadan kaldırır. İkinci bir gerekçe daha
vardır: içerik dar bir alanda önceliklendirilmek zorundadır. Hangi bölümün önce geleceği, hangi
bilginin taşınabilir olduğu dar düzende karara bağlanır; geniş düzen bu kararların üzerine
kurulur. Ters yönde çalışıldığında dar düzen, geniş düzenden arta kalan olur.

```css
/* duzen.css — 7. adım: taban dar düzen, tek eşik */
.istasyon-duzeni {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas:
    "kunye"
    "olcumler"
    "yan-bilgi"
    "konum";
  gap: var(--aralik-1);
}

.olcum-kartlari {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: var(--aralik-0);
}

.istasyon-notlari { max-inline-size: 675px; }
```

Taban biçemde tek bir sorgu yoktur. Kart ızgarası genişlikle birlikte sütun kazanır, metin
sütunu üst sınırında durur, sayfa tek sütunludur. Yalnız 812 birimlik eşikte yapı değişir; o
bildirim sonraki derste yazılacaktır.

## Görüntü Alanı Bildirimi

Bir ön koşul, bütün bu hesabın geçerli olması için gereklidir. Küçük ekranlı aygıtlarda tarayıcı,
dar ekrana göre yazılmamış sayfaları okunur kılmak için geniş bir sanal görüntü alanı varsayıp
sonucu küçülterek gösterebilir. Bu durumda CSS'in gördüğü genişlik ekranın gerçek genişliği
olmaz ve türetilen eşikler hiç tetiklenmez.

Web'in Temelleri ve HTML kursunda tanıtılan görüntü alanı meta etiketi bu varsayımı kapatır:

```html
<meta name="viewport" content="width=device-width, initial-scale=1">
```

Bildirim, CSS'in gördüğü genişliği aygıtın kendi genişliğine eşitler. Duyarlı biçemin ilk
satırı biçem dosyasında değil, belgenin baş bölümündedir.

## Özet

- Duyarlılık üç bileşenin birlikte bulunmasıdır: akışkan ölçüler, kapsayıcısını aşmayan medya
  ve gerektiğinde koşullu biçem.
- Kesme noktası bir aygıt genişliği değil, bileşenin anlamını yitirmeden inebildiği en dar
  ölçüden türetilen bir sayıdır; türetilen sayılar yuvarlak olmaz.
- Ölçü değişiyorsa iç boyutlandırma yeter; yapı değişiyorsa koşullu biçem gerekir. Istasyon
  sayfasında altı eşikten yalnız biri sorguya dönüşür.
- Şerit tanımı eşiği kaydırır: oran kilitli tanımda eşik 852, alt sınırları yazılı tanımda 812
  birimdir.
- Eşik dışarıdan seçildiğinde hata iki biçimde görünür — şeritler en dar ölçünün altına iner ya
  da toplamları kapsayıcıyı aşarak taşma üretir.
- Taban biçem dar düzeni tarif ettiğinde koşullar ekleme yapar; geniş düzenden başlandığında her
  koşul geri alma bildirimleri taşır.

## Sonraki Adım

Türetilen eşik elde var: 812 birim. Geriye bu sayının biçem dosyasında nasıl yazılacağı kalıyor.
Koşul yalnız genişlikle kurulmaz; yüksekliğe, ekranın yönüne, çıktının kâğıda mı ekrana mı
gideceğine göre de biçem ayrılabilir. Sonraki ders koşullu biçemin yazımını ele alır: bir koşul
hangi özelliklere bakabilir, iki koşul nasıl birleştirilir ve iki aralığın ucundaki genişlikte
hangi kural kazanır?
