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

# Kullanıcı Tercihleri

Renk şeması, kontrast, zorunlu renkler ve hareket azaltma tercihlerinin sorgulanması, koyu paletin kontrast denetimi, tercihlerin birlikte çözülmesi ve hareket azaltmanın neyi kapsadığı.

Buraya kadar biçem hep ortamın ölçülebilir niteliklerine uyarlandı: görüntü alanının genişliği,
kabın ölçüsü, aygıtın piksel oranı. Bunların hepsi aygıtın özellikleriydi.

Kullanıcının kendisi de bir tercih bildirir. İşletim sistemi ya da tarayıcı ayarlarında koyu bir
renk şeması seçmiş, kontrastın artırılmasını istemiş ya da hareketin azaltılmasını istemiş
olabilir. Bu tercihler aynı sorgu yazımıyla okunur ve sayfa bunlara uyar.

## Tercih Bir Ortam Özelliğidir

Dört ortam özelliği kullanıcı tercihini bildirir.

`prefers-color-scheme` açık ya da koyu bir yüzey tercihini verir; değerleri `light`, `dark` ve
`no-preference`. `prefers-contrast` kontrastın artırılması ya da azaltılması isteğini bildirir.
`prefers-reduced-motion` hareketin azaltılması isteğini taşır ve tek anlamlı değeri `reduce`.
`forced-colors` ise ayrı bir durumu bildirir: kullanıcı, sayfanın renklerinin yerine kendi
belirlediği sınırlı bir palete zorlanmasını istemiştir.

Dördü de ortam sorgularıyla aynı biçimde yazılır ve aynı basamaklama kurallarına uyar. Ayrım
soruda değil öznededir: genişlik aygıtın, tercih kullanıcınındır.

Bir tasarım kararı hemen ortaya çıkar. Tercih sorguları biçemi **eklemeli** yazılmaya zorlar:
taban biçem `no-preference` durumunu tarif eder, sorgu bloğu yalnız değişeni yazar. Ters yönde
yazıldığında — koyu şema taban alınıp açık şema sorguyla geri alındığında — tercih bildirmemiş
bir kullanıcı, tasarımın istisnası olur.

## Koyu Şemanın Kontrast Denetimi

Koyu şema, açık şemanın renklerinin ters çevrilmesi değildir. Renklerin bağıl parlaklıkları
doğrusal olmadığı için, zeminin değişmesi ön plandaki her rengin oranını yeniden hesaplamayı
gerektirir.

CSS ile Görsel Sunum kursunda tanıtılan **kontrast oranı**, iki rengin bağıl parlaklıklarından
hesaplanır. Aşağıdaki program istasyon paletini iki şemada denetliyor.

```js
// kontrast.mjs — acik ve koyu renk semasinin kontrast oranlarinin denetimi
// Bagil parlaklik ve kontrast orani WCAG tanimina gore hesaplanir.

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)];
}

function bagilParlaklik([r, g, b]) {
  const d = (c) => (c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4));
  return 0.2126 * d(r) + 0.7152 * d(g) + 0.0722 * d(b);
}

function oran(renk1, renk2) {
  const l1 = bagilParlaklik(renk1), l2 = bagilParlaklik(renk2);
  const [buyuk, kucuk] = l1 > l2 ? [l1, l2] : [l2, l1];
  return (buyuk + 0.05) / (kucuk + 0.05);
}

// acik sema: CSS ile Gorsel Sunum kursunda kurulan palet
const ACIK = {
  zemin: [203, 18, 97],
  metin: [211, 29, 16],
  metinSoluk: [211, 12, 45],
  uyari: [0, 66, 33],
  cizgi: [207, 15, 86],
};

// koyu sema, yalniz zemin ve ana metin degistirilmis; kalanlar oldugu gibi birakilmis
const KOYU_EKSIK = {
  zemin: [211, 22, 12],
  metin: [211, 20, 92],
  metinSoluk: ACIK.metinSoluk,
  uyari: ACIK.uyari,
  cizgi: ACIK.cizgi,
};

const HEDEF = { metin: 4.5, metinSoluk: 4.5, uyari: 4.5, cizgi: 3 };

function tablo(baslik, sema) {
  console.log(`\n--- ${baslik} ---`);
  console.log(`zemin: hsl(${sema.zemin.join(" ")})`);
  console.log("on plan      hsl           hedef   oran   sonuc");
  for (const ad of ["metin", "metinSoluk", "uyari", "cizgi"]) {
    const o = oran(hslRgb(...sema[ad]), hslRgb(...sema.zemin));
    console.log(
      `${ad.padEnd(11)}  ${("hsl(" + sema[ad].join(" ") + ")").padEnd(14)}` +
        `${(HEDEF[ad] + ":1").padStart(6)}  ${o.toFixed(2).padStart(5)}  ${(o >= HEDEF[ad] ? "gecer" : "KALIR").padStart(5)}`,
    );
  }
}

tablo("acik sema", ACIK);
tablo("koyu sema: yalniz zemin ve metin degistirilmis", KOYU_EKSIK);

// duzeltme: her on plan icin hedefi saglayan en dusuk aydinlik degeri aranir
console.log("\n--- koyu semada gereken aydinlik degerleri ---");
console.log("on plan      su anki L  gereken L  su anki oran  duzeltilmis oran");
for (const ad of ["metin", "metinSoluk", "uyari", "cizgi"]) {
  const [h, s, l] = KOYU_EKSIK[ad];
  let gereken = l;
  while (gereken <= 100 && oran(hslRgb(h, s, gereken), hslRgb(...KOYU_EKSIK.zemin)) < HEDEF[ad]) {
    gereken += 0.5;
  }
  console.log(
    `${ad.padEnd(11)}  ${l.toFixed(1).padStart(9)}  ${gereken.toFixed(1).padStart(9)}  ` +
      `${oran(hslRgb(h, s, l), hslRgb(...KOYU_EKSIK.zemin)).toFixed(2).padStart(12)}  ` +
      `${oran(hslRgb(h, s, gereken), hslRgb(...KOYU_EKSIK.zemin)).toFixed(2).padStart(16)}`,
  );
}
```

```
--- acik sema ---
zemin: hsl(203 18 97)
on plan      hsl           hedef   oran   sonuc
metin        hsl(211 29 16) 4.5:1  13.93  gecer
metinSoluk   hsl(211 12 45) 4.5:1   4.59  gecer
uyari        hsl(0 66 33)   4.5:1   8.56  gecer
cizgi        hsl(207 15 86)   3:1   1.30  KALIR

--- koyu sema: yalniz zemin ve metin degistirilmis ---
zemin: hsl(211 22 12)
on plan      hsl           hedef   oran   sonuc
metin        hsl(211 20 92) 4.5:1  13.90  gecer
metinSoluk   hsl(211 12 45) 4.5:1   3.42  KALIR
uyari        hsl(0 66 33)   4.5:1   1.83  KALIR
cizgi        hsl(207 15 86)   3:1  12.08  gecer

--- koyu semada gereken aydinlik degerleri ---
on plan      su anki L  gereken L  su anki oran  duzeltilmis oran
metin             92.0       92.0         13.90             13.90
metinSoluk        45.0       53.0          3.42              4.54
uyari             33.0       61.0          1.83              4.53
cizgi             86.0       86.0         12.08             12.08
```

Açık şemada üç metin rengi de 4,5:1 ölçütünü karşılıyor. Ayraç çizgisi 1,30 oranıyla 3:1
ölçütünün altında — bu bir kusur değil, kapsam sorusudur. WCAG 1.4.11 ölçütü metin dışı
kontrastı arayüz bileşenlerinin ve durum göstergelerinin sınırları için ister; bir çizelgedeki
satır ayracı süsleyicidir. Aynı renk bir girdi kenarlığı ya da odak göstergesi olarak
kullanılacaksa ölçütü karşılamaz ve koyulaştırılması gerekir.

Koyu şemada tablo tersine dönüyor. Zemin ve ana metin değiştirilmiş; ikisi arasında 13,90 oran
var ve sorun görünmüyor. Ama değiştirilmemiş iki renk düşüyor: soluk metin 3,42, uyarı rengi
1,83. Uyarı rengi, kullanıcıyı uyarması gereken renktir ve koyu zeminde neredeyse okunamaz.

Üçüncü blok düzeltmeyi hesaplıyor. Soluk metnin aydınlık değeri 45'ten 53'e, uyarı renginin 33'ten
61'e çıkarıldığında ölçüt karşılanıyor. Uyarı renginde gereken 28 puanlık artış, doğrudan
çevirmenin neden yetmediğini gösteriyor: kırmızının bağıl parlaklığı düşüktür, koyu zeminde
ayırt edilmesi için çok daha açık bir tona çıkması gerekir.

Kural şudur: koyu şema, açık şemanın **her** renginin yeniden hesaplanmasıdır. Değiştirilmeyen
renk, sessizce ölçüt dışına düşen renktir.

## Tercihlerin Birlikte Çözülmesi

Kullanıcı birden çok tercihi aynı anda bildirebilir. Sorgular birbirinden bağımsız olduğu için
sonuç, eşleşen bütün blokların basamaklamadaki birleşimidir.

```js
// tercih.mjs — kullanici tercihi sorgularinin cozulmesi ve sonucun belirlenmesi

// Kurallar kaynak sirasinda; kosulu dogru olanlarin sonuncusu kazanir.
const KURALLAR = [
  { kosul: null, deger: { zemin: "acik", cizgi: "ince", gecis: "200ms", kaydirma: "yumusak" } },
  { kosul: "prefers-color-scheme: dark", deger: { zemin: "koyu" } },
  { kosul: "prefers-contrast: more", deger: { cizgi: "kalin" } },
  { kosul: "prefers-reduced-motion: reduce", deger: { gecis: "1ms", kaydirma: "ani" } },
  { kosul: "forced-colors: active", deger: { zemin: "sistem", cizgi: "sistem" } },
];

const PROFILLER = [
  { ad: "varsayilan", "prefers-color-scheme": "light", "prefers-contrast": "no-preference", "prefers-reduced-motion": "no-preference", "forced-colors": "none" },
  { ad: "koyu sema", "prefers-color-scheme": "dark", "prefers-contrast": "no-preference", "prefers-reduced-motion": "no-preference", "forced-colors": "none" },
  { ad: "koyu + az hareket", "prefers-color-scheme": "dark", "prefers-contrast": "no-preference", "prefers-reduced-motion": "reduce", "forced-colors": "none" },
  { ad: "yuksek kontrast", "prefers-color-scheme": "light", "prefers-contrast": "more", "prefers-reduced-motion": "no-preference", "forced-colors": "none" },
  { ad: "zorunlu renkler", "prefers-color-scheme": "dark", "prefers-contrast": "more", "prefers-reduced-motion": "reduce", "forced-colors": "active" },
];

function eslesir(kosul, profil) {
  if (kosul === null) return true;
  const [ozellik, deger] = kosul.split(":").map((s) => s.trim());
  return profil[ozellik] === deger;
}

function coz(profil) {
  const sonuc = {};
  const eslesen = [];
  for (const k of KURALLAR) {
    if (!eslesir(k.kosul, profil)) continue;
    eslesen.push(k.kosul ?? "taban");
    Object.assign(sonuc, k.deger);
  }
  return { sonuc, eslesen };
}

console.log("kurallar:");
for (const k of KURALLAR) {
  console.log(`  ${(k.kosul ?? "(taban)").padEnd(32)} ${JSON.stringify(k.deger)}`);
}

console.log("\nprofil             zemin    cizgi    gecis  kaydirma  eslesen kural sayisi");
for (const p of PROFILLER) {
  const { sonuc, eslesen } = coz(p);
  console.log(
    `${p.ad.padEnd(17)}  ${sonuc.zemin.padEnd(7)}  ${sonuc.cizgi.padEnd(7)}  ` +
      `${sonuc.gecis.padStart(5)}  ${sonuc.kaydirma.padEnd(8)}  ${String(eslesen.length).padStart(19)}`,
  );
}

// color-scheme bildirimi: tarayici denetimleri ve kaydirma cubugu hangi semayi kullanir
console.log("\n--- color-scheme bildiriminin tarayici denetimlerine etkisi ---");
console.log("kullanici tercihi  color-scheme bildirimi  denetimler  sayfa    uyumlu mu");
for (const tercih of ["light", "dark"]) {
  for (const bildirim of ["normal", "light", "light dark"]) {
    const destekli = bildirim.split(" ").includes(tercih);
    const denetim = destekli ? tercih : bildirim === "normal" ? "light" : bildirim.split(" ")[0];
    const sayfa = tercih;   // sayfanin kendi renkleri sorguyla zaten uyarlanmis
    console.log(
      `${tercih.padEnd(17)}  ${bildirim.padEnd(22)}  ${denetim.padEnd(10)}  ${sayfa.padEnd(7)}  ` +
        `${(denetim === sayfa ? "evet" : "HAYIR").padStart(9)}`,
    );
  }
}

// hareket azaltma neyi azaltir: ozellik turune gore politika
console.log("\n--- hareket azaltma tercihinde ozellik turlerine gore sure ---");
const HAREKETLER = [
  { ad: "translate/scale", tur: "yer degistirme", taban: 300 },
  { ad: "rotate", tur: "yer degistirme", taban: 400 },
  { ad: "opacity", tur: "gorunurluk", taban: 200 },
  { ad: "background-color", tur: "renk", taban: 150 },
  { ad: "surekli donen bant", tur: "surekli hareket", taban: 8000 },
];
console.log("ozellik                 tur               taban   azaltilmis  karar");
for (const h of HAREKETLER) {
  const kapatilir = h.tur === "yer degistirme" || h.tur === "surekli hareket";
  const yeni = kapatilir ? 0 : h.taban;
  const karar = kapatilir ? "kaldirilir" : "korunur";
  console.log(
    `${h.ad.padEnd(22)}  ${h.tur.padEnd(16)}  ${String(h.taban + "ms").padStart(6)}  ` +
      `${String(yeni + "ms").padStart(10)}  ${karar.padStart(11)}`,
  );
}
```

```
kurallar:
  (taban)                          {"zemin":"acik","cizgi":"ince","gecis":"200ms","kaydirma":"yumusak"}
  prefers-color-scheme: dark       {"zemin":"koyu"}
  prefers-contrast: more           {"cizgi":"kalin"}
  prefers-reduced-motion: reduce   {"gecis":"1ms","kaydirma":"ani"}
  forced-colors: active            {"zemin":"sistem","cizgi":"sistem"}

profil             zemin    cizgi    gecis  kaydirma  eslesen kural sayisi
varsayilan         acik     ince     200ms  yumusak                     1
koyu sema          koyu     ince     200ms  yumusak                     2
koyu + az hareket  koyu     ince       1ms  ani                         3
yuksek kontrast    acik     kalin    200ms  yumusak                     2
zorunlu renkler    sistem   sistem     1ms  ani                         5

--- color-scheme bildiriminin tarayici denetimlerine etkisi ---
kullanici tercihi  color-scheme bildirimi  denetimler  sayfa    uyumlu mu
light              normal                  light       light         evet
light              light                   light       light         evet
light              light dark              light       light         evet
dark               normal                  light       dark         HAYIR
dark               light                   light       dark         HAYIR
dark               light dark              dark        dark          evet

--- hareket azaltma tercihinde ozellik turlerine gore sure ---
ozellik                 tur               taban   azaltilmis  karar
translate/scale         yer degistirme     300ms         0ms   kaldirilir
rotate                  yer degistirme     400ms         0ms   kaldirilir
opacity                 gorunurluk         200ms       200ms      korunur
background-color        renk               150ms       150ms      korunur
surekli donen bant      surekli hareket   8000ms         0ms   kaldirilir
```

Birinci tablo, tercihlerin birbirini engellemediğini gösteriyor. Koyu şema ve hareket azaltma
birlikte bildirildiğinde ikisi de uygulanır; her sorgu kendi özelliğini yazar, birbirinin
yazdığını ezmez.

Son satır bir istisnayı işaretliyor. Zorunlu renkler etkinken sayfanın renk bildirimlerinin
çoğu yok sayılır ve yerine sistemin belirlediği sınırlı bir palet konur. Bu, kullanıcı için
kesin bir gereksinimdir; sayfanın yapması gereken, renk yerine **başka** bir ayrım aracı
bırakmaktır. Yalnız renkle ayrılan bir durum — örneğin eksik ölçümü kırmızıyla göstermek —
zorunlu renklerde tamamen kaybolur; aynı bilgi bir simge ya da metinle de verilmelidir.

## Tarayıcının Kendi Parçaları

İkinci tablo, sayfanın renklerini değiştirmenin yetmediği bir alanı gösteriyor.

Kaydırma çubuğu, form denetimlerinin varsayılan görünümü, metin seçimi rengi — bunlar tarayıcının
çizdiği parçalardır ve sayfanın renk bildirimlerinden etkilenmezler. Hangi şemayı kullanacaklarını
`color-scheme` bildirimi söyler.

Bildirim yazılmadığında ya da yalnız `light` yazıldığında, kullanıcı koyu şema tercih etse bile
denetimler açık kalır: koyu bir sayfada parlak beyaz bir kaydırma çubuğu ve açık zeminli girdiler
görünür. `color-scheme: light dark` bildirimi iki şemayı da desteklediğini bildirir ve denetimler
kullanıcının tercihini izler.

Bildirimin ikinci bir sonucu daha vardır: `light-dark()` fonksiyonu ancak bir şema seçili
olduğunda çalışır. Fonksiyon iki değer alır ve etkin şemaya göre birini seçer; koyu şema
kurallarını ayrı bir sorgu bloğuna yazmak yerine değer düzeyinde ayırmayı sağlar.

## Hareket Azaltma Neyi Azaltır

Üçüncü tablo, bu dersin bıraktığı asıl soruya geliyor.

`prefers-reduced-motion` tercihinin adı yanıltıcı olabilir: tercih, **animasyonun kapatılmasını**
değil hareketin azaltılmasını ister. Ayrım, hangi özelliğin değiştiğine bakılarak yapılır.

Bir ögenin **yer değiştirmesi** — kayması, dönmesi, ölçeklenmesi — göz için bir devinim
üretir. Vestibüler duyarlılığı olan kullanıcılarda büyük ya da beklenmedik devinimler baş
dönmesi ve mide bulantısına yol açabilir. Tercihi bildiren kullanıcı bu devinimden kaçınmak
ister.

Bir ögenin **görünürlüğünün** ya da **renginin** değişmesi devinim üretmez. Bir düğmenin
üzerine gelindiğinde arka planının 150 milisaniyede değişmesi, hareket azaltma tercihinde de
korunabilir; hatta korunmalıdır, çünkü bu geçiş durum değişikliğinin okunmasını kolaylaştırır.

Tablodaki karar sütunu bu ayrımı uyguluyor: yer değiştirme üreten ve sürekli tekrarlanan
hareketler kaldırılıyor, görünürlük ve renk geçişleri korunuyor. Bütün geçişleri tek bir kuralla
sıfırlamak — evrensel seçiciye sıfır süre yazmak — kolay bir çözümdür ama arayüzü ani ve okunması
zor hâle getirir.

WCAG 2.3.3 ölçütü bu politikayı doğrudan tarif eder: etkileşimle tetiklenen hareket
animasyonları, işlev için gerekli değilse kapatılabilmelidir.

```css
/* duzen.css — 12. adım: kullanıcı tercihleri */
:root {
  color-scheme: light dark;

  --zemin:       hsl(203 18% 97%);
  --metin:       hsl(211 29% 16%);
  --metin-soluk: hsl(211 12% 45%);
  --uyari:       hsl(0 66% 33%);
  --cizgi:       hsl(207 15% 86%);
  --gecis-suresi: 200ms;
}

@media (prefers-color-scheme: dark) {
  :root {
    --zemin:       hsl(211 22% 12%);
    --metin:       hsl(211 20% 92%);
    --metin-soluk: hsl(211 12% 53%);
    --uyari:       hsl(0 66% 61%);
    --cizgi:       hsl(207 15% 30%);
  }
}

@media (prefers-contrast: more) {
  :root {
    --metin-soluk: var(--metin);
    --cizgi: var(--metin);
  }
}

@media (prefers-reduced-motion: reduce) {
  :root { --gecis-suresi: 1ms; }
  html { scroll-behavior: auto; }
}

@media (forced-colors: active) {
  .olcum-cizelgesi .eksik { forced-color-adjust: none; }
  .olcum-cizelgesi .eksik::before { content: "! "; }
}
```

Beş blok, beş ayrı soru. Taban blok açık şemayı ve varsayılan süreyi tanımlıyor; kalan dördü
yalnız değişen özel özellikleri yazıyor. Koyu şemadaki aydınlık değerleri yukarıdaki hesabın
sonucu: soluk metin 53, uyarı 61. Zorunlu renkler bloğu ise renk yerine metin ayrımı ekliyor —
eksik ölçüm, renk kaybolduğunda da bir işaretle görünür kalıyor.

Bütün bildirimler özel özellikler üzerinden geçtiği için bileşen kuralları hiç değişmiyor. Bir
kart, bir çizelge satırı ya da bir düğme `var(--metin)` yazdığında dört tercihin bileşimi zaten
çözülmüş olur.

## Özet

- Dört ortam özelliği kullanıcı tercihini bildirir: renk şeması, kontrast, hareket azaltma ve
  zorunlu renkler; hepsi ortam sorgularıyla aynı biçimde yazılır.
- Taban biçem tercih bildirmemiş kullanıcıyı tarif eder; sorgu blokları yalnız değişeni yazar ve
  hiçbirini geri almaz.
- Koyu şema, açık şemanın çevrilmesi değildir: zemin değiştiğinde her ön plan renginin oranı
  yeniden hesaplanır; istasyon paletinde uyarı renginin aydınlık değeri 33'ten 61'e çıkmak
  zorundadır.
- Tercihler birbirinden bağımsızdır ve birlikte bildirildiklerinde hepsi uygulanır; zorunlu
  renkler etkinken yalnız renkle verilen ayrımlar kaybolur ve metin ya da simge yedeği gerekir.
- `color-scheme` bildirimi tarayıcının kendi çizdiği parçaların hangi şemayı izleyeceğini söyler;
  yazılmadığında koyu bir sayfada açık denetimler kalır.
- Hareket azaltma tercihi yer değiştirme üreten ve sürekli tekrarlanan hareketleri kaldırır;
  görünürlük ve renk geçişleri korunur, çünkü devinim üretmezler.

## Sonraki Adım

Son tablo bir ayrım kurdu ama tanımı yapmadan kullandı: "yer değiştirme üreten" özellik hangisi?
Bir ögeyi kaydıran, döndüren ve ölçekleyen bildirimlerin ortak bir adı ve ortak bir matematiği
vardır; ikisini de görmeden hangi hareketin azaltılacağına karar vermek sezgiye kalır. Sonraki
konu buradan başlar: bir öge kendi kutusunu bozmadan nasıl ötelenir, ölçeklenir ve döndürülür,
bu işlemler hangi sırayla uygulanır ve sıra neden sonucu değiştirir?
