---
title: 'Etkileşim Durumları'
source: 'https://academia.sh/tr/kurslar/arayuz-temelleri/etkilesim-durumlari'
course: 'Arayüz Tasarımının Temelleri'
language: tr
updated: '2026-08-17T18:09:35+00:00'
license: 'CC BY-SA 4.0'
---

# Etkileşim Durumları

Beş etkileşim durumunun tanımı, durum değişikliğinin ölçülebilir eşiğe bağlanması, üzerine gelme ile seçili olmanın kanal çakışması ve odak göstergesinin alan ve kontrast hesabı.

Önceki konu katalog arayüzünün durağan görüntüsünü tamamladı: metin ölçekten bir basamak,
renk rol tablosundan bir değer alıyor ve iki temada da denetlenmiş durumda. Ancak arayüz
durağan değil. "Ödünç al" düğmesi imleç üzerine geldiğinde, klavyeyle odaklanıldığında,
basılı tutulduğunda ve kayıt rafta olmadığı için kullanılamaz olduğunda farklı görünür.

Bu görünümlerin her biri ayrı bir tasarım kararıdır ve hiçbiri tanımlanmadı.
Tanımlanmadıklarında kararlar bileşen yazılırken tek tek verilir; aynı arayüzdeki iki düğme
farklı biçimde tepki verir ve hangi tepkinin ne anlama geldiği öğrenilemez.

## Beş Durum

Bir etkileşimli bileşenin taşıdığı durumlar şunlardır:

- **Varsayılan (default).** Bileşenin hiçbir etkileşim altında olmadığı görünümü. Diğer
  bütün durumlar buna göre tanımlanır.
- **Üzerine gelme (hover).** İmlecin bileşenin üzerinde olduğu durum. Bildirdiği
  bilgi şudur: burası tıklanabilir bir yer. Yalnızca imleçli girdilerde vardır.
- **Odak (focus).** Bileşenin klavye girdisini alacak öge olduğu durum. Bildirdiği bilgi
  şudur: tuşa basılırsa etkilenecek olan burasıdır.
- **Basılı (active).** Bileşenin o anda basılı tutulduğu durum. Bildirdiği bilgi, girdinin
  alındığıdır.
- **Devre dışı (disabled).** Bileşenin şu anda kullanılamayacağı durum.

Beş durumun ikisi sık karıştırılır. Üzerine gelme ile odak farklı girdi türlerinden
gelir ve farklı şeyler bildirir; birini diğerinin yerine kullanmak, klavyeyle gezen
kullanıcının arayüzde nerede olduğunu göremediği anlamına gelir. Ekran Boyutu ve Girdi Türü
dersinde gösterildiği gibi dokunmatik girdide üzerine gelme durumu hiç oluşmaz; odak ise
her girdi türünde oluşur. Bu yüzden üzerine gelme durumuna yalnızca **ek** bilgi
yüklenebilir, taşıyıcı bilgi yüklenemez.

Durumlar birleşebilir. Bir düğme aynı anda hem odaklı hem basılı olabilir; hem odaklı hem
üzerine gelinmiş olabilir. Bu yüzden durumlar birbirinin yerine geçen bir liste değil,
üst üste binen katmanlardır ve her biri **ayrı bir kanal** kullanmak zorundadır.

## Durum Değişikliği Ölçülebilir Olmalı

Bir durum, varsayılandan ayırt edilemiyorsa yoktur. Ayrımın ölçüsü, önceki derslerde
kullanılan kontrast oranıdır; eşik ise bu kursun benimsediği 1.2 değeridir.

```js
// durumlar.mjs — etkilesim durumlarinin varsayilandan ayrilabilirligi ve metin kontrasti

function hslRgb(h, s, l) {
  s /= 100; l /= 100;
  const k = (n) => (n + h / 30) % 12;
  const a = s * Math.min(l, 1 - l);
  const f = (n) => l - a * Math.max(-1, Math.min(k(n) - 3, Math.min(9 - k(n), 1)));
  return [f(0), f(8), f(4)].map((v) => Math.round(v * 255));
}
const onaltilik = (rgb) => "#" + rgb.map((v) => v.toString(16).padStart(2, "0")).join("");
function kanal(v) {
  const s = v / 255;
  return s <= 0.03928 ? s / 12.92 : Math.pow((s + 0.055) / 1.055, 2.4);
}
const parlaklik = ([r, g, b]) => 0.2126 * kanal(r) + 0.7152 * kanal(g) + 0.0722 * kanal(b);
function kontrast(a, b) {
  const [x, y] = [parlaklik(a), parlaklik(b)].sort((p, q) => q - p);
  return (x + 0.05) / (y + 0.05);
}

const ACIKLIK = { "000": 100, "050": 97, 100: 92, 200: 84, 300: 74, 400: 62, 500: 50, 600: 40, 700: 31, 800: 22, 900: 14 };
const TON = { notr: [214, 8], ana: [214, 62] };
const renk = (aile, b) => hslRgb(TON[aile][0], TON[aile][1], ACIKLIK[b]);

const AYRIM_ESIGI = 1.2;   // bu kursun benimsedigi en kucuk durum degisikligi orani
const METIN_ESIGI = 4.5;

const DOLGU_DUGME = [
  { durum: "varsayilan",    yuzey: ["ana", "600"],  metin: ["notr", "000"] },
  { durum: "uzerine gelme", yuzey: ["ana", "700"],  metin: ["notr", "000"] },
  { durum: "basili",        yuzey: ["ana", "800"],  metin: ["notr", "000"] },
  { durum: "devre disi",    yuzey: ["notr", "200"], metin: ["notr", "400"] },
];

const DUZ_DUGME = [
  { durum: "varsayilan",    yuzey: ["notr", "000"], metin: ["ana", "600"] },
  { durum: "uzerine gelme", yuzey: ["ana", "100"],  metin: ["ana", "700"] },
  { durum: "basili",        yuzey: ["ana", "200"],  metin: ["ana", "800"] },
  { durum: "devre disi",    yuzey: ["notr", "000"], metin: ["notr", "400"] },
];

function denetle(baslik, dizi) {
  console.log(`\n--- ${baslik} ---`);
  console.log("durum           yuzey    metin    metin/yuzey  yuzey ayrimi  metin ayrimi  tasiyan kanal");
  const t = dizi[0];
  for (const d of dizi) {
    const y = renk(...d.yuzey);
    const m = renk(...d.metin);
    const km = kontrast(m, y);
    const ay = kontrast(y, renk(...t.yuzey));
    const am = kontrast(m, renk(...t.metin));
    const kanallar = [];
    if (ay >= AYRIM_ESIGI) kanallar.push("yuzey");
    if (am >= AYRIM_ESIGI) kanallar.push("metin");
    console.log(
      `${d.durum.padEnd(15)} ${onaltilik(y)}  ${onaltilik(m)}  ${km.toFixed(2).padStart(9)}:1  ` +
        `${ay.toFixed(3).padStart(12)}  ${am.toFixed(3).padStart(12)}  ` +
        (d === t ? "-" : kanallar.length ? kanallar.join("+") : "AYRILMIYOR") +
        (km < METIN_ESIGI ? "  [metin esigi alti]" : "")
    );
  }
}

denetle("birincil dugme (dolgulu)", DOLGU_DUGME);
denetle("ikincil dugme (dolgusuz)", DUZ_DUGME);

// Sonuc listesi satiri: uzerine gelme ile secili olma ayni kanali paylasiyor
console.log("\n--- sonuc listesi satiri ---");
console.log("durum           yuzey    varsayilana karsi  uzerine gelmeye karsi");
const SATIR = [
  ["varsayilan", ["notr", "000"]],
  ["uzerine gelme", ["notr", "050"]],
  ["secili", ["ana", "100"]],
];
for (const [ad, bas] of SATIR) {
  const y = renk(...bas);
  console.log(
    `${ad.padEnd(15)} ${onaltilik(y)}  ${kontrast(y, renk("notr", "000")).toFixed(3).padStart(17)}  ${kontrast(y, renk("notr", "050")).toFixed(3).padStart(21)}`
  );
}

// Satir icin uzerine gelme yuzeyi hangi basamakta esigi gecer?
console.log("\nuzerine gelme adayi  varsayilana karsi  secili duruma karsi");
for (const b of ["050", "100", "200"]) {
  const y = renk("notr", b);
  console.log(
    `${("notr-" + b).padEnd(20)} ${kontrast(y, renk("notr", "000")).toFixed(3).padStart(17)}  ${kontrast(y, renk("ana", "100")).toFixed(3).padStart(20)}`
  );
}
```

```
--- birincil dugme (dolgulu) ---
durum           yuzey    metin    metin/yuzey  yuzey ayrimi  metin ayrimi  tasiyan kanal
varsayilan      #275ea5  #ffffff       6.50:1         1.000         1.000  -
uzerine gelme   #1e4980  #ffffff       9.05:1         1.393         1.000  yuzey
basili          #15335b  #ffffff      12.68:1         1.950         1.000  yuzey
devre disi      #d3d6d9  #969da6       1.88:1         4.454         2.738  yuzey+metin  [metin esigi alti]

--- ikincil dugme (dolgusuz) ---
durum           yuzey    metin    metin/yuzey  yuzey ayrimi  metin ayrimi  tasiyan kanal
varsayilan      #ffffff  #275ea5       6.50:1         1.000         1.000  -
uzerine gelme   #dee9f7  #1e4980       7.37:1         1.228         1.393  yuzey+metin
basili          #bdd3ef  #15335b       8.29:1         1.530         1.950  yuzey+metin
devre disi      #ffffff  #969da6       2.74:1         1.000         2.374  metin  [metin esigi alti]

--- sonuc listesi satiri ---
durum           yuzey    varsayilana karsi  uzerine gelmeye karsi
varsayilan      #ffffff              1.000                  1.071
uzerine gelme   #f7f7f8              1.071                  1.000
secili          #dee9f7              1.228                  1.147

uzerine gelme adayi  varsayilana karsi  secili duruma karsi
notr-050                         1.071                 1.147
notr-100                         1.204                 1.020
notr-200                         1.459                 1.189
```

Dolgulu düğmede üzerine gelme ve basılı durumları eşiği geçiyor (1.393 ve 1.950) ve ikisi de
tek kanalda, yüzeyde duruyor. Bu kabul edilebilir, çünkü ikisi de geçici durumlardır ve
bilgi taşımazlar.

Metin kontrastı her durumda korunuyor ve hatta yükseliyor: 6.50, 9.05, 12.68. Bu, yön
seçiminin sonucudur; dolgu koyulaştıkça beyaz metnin kontrastı artar. Ters yön seçilseydi
basılı durumda metin eşiği kaçırabilirdi.

Düz düğmede iki durum da iki kanalda birden ayrılıyor. Nedeni, dolgusuz düğmede yüzey
ayrımının zayıf kalmasıdır: 1.228, eşiğin hemen üstünde. Metin kanalının eşlik etmesi bu
zayıflığı karşılıyor.

Devre dışı durumu her iki düğmede de metin eşiğinin altında kalıyor. Karşıtlık ve
Erişilebilirlik dersinde görüldüğü gibi etkin olmayan bileşenler 1.4.3 kapsamı dışındadır,
yani bu bir ihlal değil. Ancak orada verilen karar burada da geçerlidir: kullanıcının
düğmenin ne yaptığını okuması gerekiyorsa, düğme devre dışı bırakılmaz.

## Üzerine Gelme ile Seçili Olma Aynı Kanalı Paylaşamaz

Üçüncü tablo, sonuç listesi satırında iki ayrı sorunu birden gösteriyor.

Birincisi, üzerine gelme yüzeyi nötr 050'de duruyor ve varsayılana karşı yalnızca 1.071
kontrast üretiyor. Eşik 1.2, dolayısıyla bu durum ölçülebilir bir değişiklik üretmiyor.

İkincisi ve daha ağırı, seçili durumun üzerine gelme durumuna karşı 1.147 kontrast
taşıması. İki durum birbirinden ayrılmıyor: kullanıcı bir satırın seçili mi yoksa imlecin
altında mı olduğunu ayırt edemiyor.

Dördüncü tablo, sorunun yüzey kanalı içinde çözülemeyeceğini gösteriyor. Nötr 100 varsayılana
karşı eşiği geçiyor (1.204) ama seçili duruma karşı 1.020'ye düşüyor — iki durum tümüyle
birleşiyor. Nötr 200 varsayılana karşı rahat geçiyor (1.459) ama seçili duruma karşı 1.189
ile hâlâ eşiğin altında. Üç adayın hiçbiri iki koşulu birden sağlamıyor.

Bunun nedeni yapısaldır: iki durum da aynı eksende, yüzey açıklığında kodlanıyor ve iki
değer bir tarafta varsayılandan, diğer tarafta birbirinden ayrılmak zorunda. Eksen bu kadar
yükü taşımıyor.

Çözüm, iki durumu ayrı kanallara dağıtmaktır. Seçili olma kalıcı ve bilgi taşıyan bir
durumdur; satırın başına konan ve yüzeye karşı 3.0 eşiğini geçen dikey bir çubukla
işaretlenir. Üzerine gelme geçicidir; yüzey kanalında kalır ve nötr 100 basamağına
taşınarak eşiği geçer. İki durum farklı eksenlerde olduğu için aynı anda oluştuklarında da
ayırt edilebilirler. Karşıtlık ve Erişilebilirlik dersindeki seçili satır bulgusu aynı
ikinci kanalı istiyordu.

## Odak Göstergesi Kaldırılamaz

Odak durumu diğer dördünden ayrılır, çünkü tek başına bir uygunluk koşuluna bağlıdır.
2.4.7 Odak Görünürlüğü ölçütü, klavyeyle kullanılabilen her ögenin görünür bir odak
göstergesi taşımasını ister. Gösterge kaldırılamaz; yalnızca değiştirilebilir.

Göstergenin nasıl olacağı iki ölçüye bağlıdır. Kontrast ölçüsü 1.4.11'den gelir: gösterge
komşu renklerinden en az 3:1 ile ayrılmalıdır. Alan ölçüsü 2.4.13 Odak Görünümü ölçütünden
gelir: göstergenin kapladığı alan, bileşenin 2 piksel kalınlığındaki çevresinin alanı kadar
olmalıdır.

```js
// odak.mjs — odak gostergesinin alan ve kontrast olcutlerine gore denetimi

function hslRgb(h, s, l) {
  s /= 100; l /= 100;
  const k = (n) => (n + h / 30) % 12;
  const a = s * Math.min(l, 1 - l);
  const f = (n) => l - a * Math.max(-1, Math.min(k(n) - 3, Math.min(9 - k(n), 1)));
  return [f(0), f(8), f(4)].map((v) => Math.round(v * 255));
}
const onaltilik = (rgb) => "#" + rgb.map((v) => v.toString(16).padStart(2, "0")).join("");
function kanal(v) {
  const s = v / 255;
  return s <= 0.03928 ? s / 12.92 : Math.pow((s + 0.055) / 1.055, 2.4);
}
const parlaklik = ([r, g, b]) => 0.2126 * kanal(r) + 0.7152 * kanal(g) + 0.0722 * kanal(b);
function kontrast(a, b) {
  const [x, y] = [parlaklik(a), parlaklik(b)].sort((p, q) => q - p);
  return (x + 0.05) / (y + 0.05);
}

// Alan olcutu: gosterge alani, bilesenin 2 px kalinliginda cevresi kadar olmali.
const gereken = (w, h) => (w + 4) * (h + 4) - w * h;

// Halka alani: kalinlik k, bosluk (offset) o
function halkaAlani(w, h, k, o) {
  const disW = w + 2 * (o + k), disH = h + 2 * (o + k);
  const icW = w + 2 * o, icH = h + 2 * o;
  return disW * disH - icW * icH;
}

const BILESENLER = [
  { ad: "odunc al dugmesi", w: 132, h: 44 },
  { ad: "simge dugmesi", w: 24, h: 24 },
];
const ADAYLAR = [
  { ad: "1px, bosluksuz", k: 1, o: 0 },
  { ad: "2px, bosluksuz", k: 2, o: 0 },
  { ad: "2px, 2px bosluk", k: 2, o: 2 },
  { ad: "3px, 1px bosluk", k: 3, o: 1 },
];

for (const b of BILESENLER) {
  const g = gereken(b.w, b.h);
  console.log(`\n--- ${b.ad} (${b.w}x${b.h} px) --- gereken en kucuk alan: ${g} px2`);
  console.log("gosterge          alan (px2)  gereken alana orani  sonuc");
  for (const a of ADAYLAR) {
    const alan = halkaAlani(b.w, b.h, a.k, a.o);
    console.log(
      `${a.ad.padEnd(17)} ${String(alan).padStart(10)} ${(alan / g).toFixed(3).padStart(20)}  ${alan >= g ? "gecti" : "KALDI"}`
    );
  }
}

// Kontrast olcutu: halka hem sayfa yuzeyinden hem bilesenin dolgusundan ayrilmali.
const ACIKLIK = { "000": 100, 100: 92, 500: 50, 600: 40, 700: 31, 900: 14 };
const TON = { notr: [214, 8], ana: [214, 62] };
const renk = (aile, b) => hslRgb(TON[aile][0], TON[aile][1], ACIKLIK[b]);

const YUZEY = renk("notr", "000");
const DOLGU = renk("ana", "600");
console.log("\nhalka rengi   yuzeye karsi  dolguya karsi  ikisi de >=3.0");
for (const [aile, bas] of [["ana", "500"], ["ana", "700"], ["notr", "900"], ["notr", "500"]]) {
  const h = renk(aile, bas);
  const ky = kontrast(h, YUZEY);
  const kd = kontrast(h, DOLGU);
  console.log(
    `${(aile + "-" + bas).padEnd(13)} ${ky.toFixed(2).padStart(12)}  ${kd.toFixed(2).padStart(13)}  ${ky >= 3 && kd >= 3 ? "gecti" : "KALDI"}`
  );
}

// Iki katmanli halka: ic katman yuzey renginde, dis katman koyu.
console.log("\niki katmanli halka (ic: yuzey, dis: notr-900)");
const ic = YUZEY, dis = renk("notr", "900");
console.log(`ic katman / dolgu : ${kontrast(ic, DOLGU).toFixed(2)}:1`);
console.log(`dis katman / yuzey: ${kontrast(dis, YUZEY).toFixed(2)}:1`);
console.log(`dis katman / ic   : ${kontrast(dis, ic).toFixed(2)}:1`);
console.log(`alan (132x44, ic 2px + dis 2px): ${halkaAlani(132, 44, 4, 0)} px2, gereken ${gereken(132, 44)} px2`);
```

```
--- odunc al dugmesi (132x44 px) --- gereken en kucuk alan: 720 px2
gosterge          alan (px2)  gereken alana orani  sonuc
1px, bosluksuz           356                0.494  KALDI
2px, bosluksuz           720                1.000  gecti
2px, 2px bosluk          752                1.044  gecti
3px, 1px bosluk         1116                1.550  gecti

--- simge dugmesi (24x24 px) --- gereken en kucuk alan: 208 px2
gosterge          alan (px2)  gereken alana orani  sonuc
1px, bosluksuz           100                0.481  KALDI
2px, bosluksuz           208                1.000  gecti
2px, 2px bosluk          240                1.154  gecti
3px, 1px bosluk          348                1.673  gecti

halka rengi   yuzeye karsi  dolguya karsi  ikisi de >=3.0
ana-500               4.59           1.41  KALDI
ana-700               9.05           1.39  KALDI
notr-900             15.74           2.42  KALDI
notr-500              4.11           1.58  KALDI

iki katmanli halka (ic: yuzey, dis: notr-900)
ic katman / dolgu : 6.50:1
dis katman / yuzey: 15.74:1
dis katman / ic   : 15.74:1
alan (132x44, ic 2px + dis 2px): 1472 px2, gereken 720 px2
```

Alan tablosu tek satırlık bir sonuç veriyor: bir piksellik halka ölçütün yarısını
karşılıyor. Oran her iki bileşende de yaklaşık aynı — 0.494 ve 0.481 — çünkü ölçüt zaten
bileşenin çevresine oranlıdır. İki piksellik halka ölçütü tam olarak karşılıyor; boşluk
eklendiğinde alan biraz daha büyüyor.

Kontrast tablosu daha sert bir sonuç veriyor. Dört halka rengi adayının **hiçbiri** iki
koşulu birden sağlamıyor. Nedeni, halkanın iki farklı komşusu olmasıdır: dışarıda açık
sayfa yüzeyi, içeride koyu düğme dolgusu. Yüzeyden ayrılmak için koyu olmak gerekiyor,
dolgudan ayrılmak için açık — tek bir renk ikisini birden yapamıyor.

Son blok çözümü veriyor. Halka iki katmanlı çizilir: içteki katman sayfa yüzeyi renginde,
dıştaki katman koyu. İç katman düğmenin dolgusuyla 6.50, dış katman sayfa yüzeyiyle 15.74
kontrast taşıyor; iki koşul da sağlanıyor. Toplam kalınlık 4 piksel olduğunda alan 1472
piksel kare, gereken 720'nin iki katından fazla.

Bu çözümün bir yan sonucu var: zemin ne olursa olsun katmanlardan biri mutlaka komşusundan
ayrılır. Odak göstergesini bileşen bileşen ayarlamak yerine tek kural olarak yazmayı bu
özellik mümkün kılar.

## Durum Tablosu Bileşenin Sözleşmesidir

Bir bileşenin tasarımı, tek bir görünümle değil durum tablosuyla tamamlanır. Tablonun her
satırı bir durum, her sütunu bir kanaldır; boş bırakılan hücre, o durumun o kanalda
değişmediğini söyler.

Tablonun eksiksiz olması, tasarımın eksiksiz olması demektir. En sık atlanan satırlar odak
ve devre dışıdır; ikisi de bir etkileşim gerektirdiği için tasarım gözden geçirilirken
ekranda görünmez. Tablonun yazılı olması bu atlanmayı önler.

Tablodan çıkan ikinci sonuç, durumların **bileşene değil role** tanımlanmasıdır. Aynı durum
tanımı arama düğmesinde, filtre uygulama düğmesinde ve iade uzatma düğmesinde de geçerlidir;
rol düzeyinde tanımlandığında yeni bir düğme için karar yeniden verilmez.

## Özet

- Etkileşimli bileşenlerin beş durumu vardır ve her biri farklı bir bilgi bildirir; üzerine
  gelme yalnızca imleçli girdide oluştuğu için taşıyıcı bilgi yüklenemez.
- Durum değişikliği ölçülebilir olmalıdır; varsayılandan ayrım bir eşiğe bağlanır ve hangi
  kanalda gerçekleştiği yazılır.
- Dolgu koyulaştırılarak kurulan durum geçişleri metin kontrastını yükseltir; ters yön
  seçildiğinde metin eşiği kaçırabilir.
- Üzerine gelme ile seçili olma aynı eksende kodlanamaz; yüzey açıklığı iki ayrımı birden
  taşıyamadığı için kalıcı durum ikinci bir kanala taşınır.
- Odak göstergesi kaldırılamaz; alan ölçütü bileşenin iki piksellik çevresi kadar alan,
  kontrast ölçütü ise komşularından 3:1 ayrım ister.
- Tek renkli bir halka iki farklı komşuyu birden karşılayamaz; iki katmanlı halka her zemin
  üzerinde çalışır ve tek kural olarak yazılabilir.

## Sonraki Adım

Beş durumun tamamı bileşenin **hazır** olduğu varsayımına dayanıyordu. Ancak katalog
arayüzü verinin gelmesini bekliyor olabilir, arama hiçbir sonuç döndürmemiş olabilir ya da
kullanıcı henüz hiçbir şey aramamış olabilir. Bu üç durumda ekranda gösterilecek bir bileşen
yoktur ve tasarlanacak şey beklemenin ve boşluğun kendisidir. Sonraki ders yükleme
göstergesinin hangi süre eşiklerinde değiştiğini, iskelet gösteriminin ne zaman yanıltıcı
olduğunu ve boş durumun neden bir hata iletisi olmadığını ele alır.
