Karanlık Mod Uygulaması: Kapsamlı CSS Rehberi

CSS değişkenleri, prefers-color-scheme, localStorage ile kalıcı tercih, açılışta yanlış renk yanıp sönmesini önleme ve görseller, kod blokları ve formlar için karanlık mod ayarları.

Karanlık Mod Uygulaması: Kapsamlı CSS Rehberi, jekcms blog kapağı

CSS değişkenleri, prefers-color-scheme, localStorage ile kalıcı tercih, açılışta yanlış renk yanıp sönmesini önleme ve görseller, kod blokları ve formlar için karanlık mod ayarları.

Karanlık Mod Neden Önemli

Akşam saatlerinde siteye gelen ziyaretçilerin önemli bir kısmı işletim sisteminde karanlık modu açık kullanıyor. Gece parlak beyaz bir sayfa açmak gözü yoruyor; OLED ekranlarda her beyaz piksel ayrı bir ışık kaynağı olduğu için bu daha da belirgin. Bu rehberde bir temaya karanlık modu nasıl düzgün eklediğimizi, CSS değişken yapısından form elemanlarına kadar adım adım anlatıyoruz.

CSS Değişkenleriyle Başlayın

Bakımı kolay bir karanlık mod sisteminin temeli CSS özel değişkenleri. Ayrı stil dosyaları ya da tek tek elemanlara sınıf eklemek bir süre sonra içinden çıkılmaz hâle geliyor.

Temel kural şu: her rengi :root üzerinde bir değişken olarak tanımlayın ve karanlık mod açıkken bu değişkenlerin değerini değiştirin. Stil dosyasındaki elemanlar doğrudan renk değeri değil, hep değişken kullansın.

:root {
  /* Yüzey renkleri */
  --color-bg-primary: #ffffff;
  --color-bg-secondary: #f5f5f5;
  --color-bg-tertiary: #e8e8e8;
  --color-bg-elevated: #ffffff;

  /* Metin renkleri */
  --color-text-primary: #1a1a1a;
  --color-text-secondary: #555555;
  --color-text-tertiary: #888888;
  --color-text-inverse: #ffffff;

  /* Kenarlık renkleri */
  --color-border-default: #d0d0d0;
  --color-border-subtle: #e5e5e5;

  /* Marka renkleri */
  --color-accent: #2563eb;
  --color-accent-hover: #1d4ed8;
  --color-accent-text: #ffffff;

  /* Anlamsal renkler */
  --color-success: #16a34a;
  --color-warning: #ca8a04;
  --color-error: #dc2626;

  /* Gölge */
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
  --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.07);
  --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1);

  /* Geçişler */
  --transition-colors: color 0.2s ease, background-color 0.2s ease, border-color 0.2s ease;
}

Değişkenlere --dark-bg ya da --light-text gibi adlar vermemeye dikkat edin. Adı görünüşe göre değil göreve göre verin: --color-bg-primary ana arka plandır, beyaz ya da koyu gri olması fark etmez.

Karanlık Değerler

Koyu tema aynı değişkenlerin değerlerini değiştiriyor. Bunun için bir CSS sınıfı yerine <html> elemanında [data-theme="dark"] özniteliği kullanıyoruz; öznitelik bir stili değil bir durumu anlattığı için daha anlaşılır.

[data-theme="dark"] {
  --color-bg-primary: #0f0f0f;
  --color-bg-secondary: #1a1a1a;
  --color-bg-tertiary: #262626;
  --color-bg-elevated: #1f1f1f;

  --color-text-primary: #e5e5e5;
  --color-text-secondary: #a3a3a3;
  --color-text-tertiary: #737373;
  --color-text-inverse: #0f0f0f;

  --color-border-default: #333333;
  --color-border-subtle: #262626;

  --color-accent: #60a5fa;
  --color-accent-hover: #93c5fd;
  --color-accent-text: #0f0f0f;

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
  --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.4);
  --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.5);
}

Koyu arka plan saf siyah (#000000) değil, #0f0f0f. Saf siyah metinle fazla kontrast oluşturup göz yoruyor; OLED ekranlarda kaydırma sırasında hafif bir iz bırakma etkisi de yaratabiliyor. #0f0f0f ya da #121212 gibi çok koyu bir gri iki sorunu da önlüyor.

Vurgu rengi de #2563eb'den #60a5fa'ya açılıyor. Koyu maviler koyu zeminde yeterince okunmuyor; vurgu renklerini renk skalasında iki üç adım açmak gerekiyor.

Sistem Tercihine Uymak

Bir değiştirme düğmesi yapmadan önce ziyaretçinin işletim sistemindeki tercihe uyun. prefers-color-scheme medya sorgusu sistemde karanlık modun açık olup olmadığını söylüyor.

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --color-bg-primary: #0f0f0f;
    --color-bg-secondary: #1a1a1a;
    /* ... tüm koyu değerler ... */
  }
}

Buradaki :root:not([data-theme="light"]) seçicisi önemli: sistem karanlık modu istiyorsa uygula, ama ziyaretçi bu sitede açıkça açık modu seçtiyse uygulama. Böylece üç durum ortaya çıkıyor: sistemi takip et, her zaman açık, her zaman koyu.

Tema Değiştirici

Değiştirici üç iş yapmalı: görünümü hemen değiştirmek, seçimi localStorage'a kaydetmek ve sayfa açılırken kaydedilen seçimi uygulamak.

class ThemeSwitcher {
  constructor() {
    this.STORAGE_KEY = 'jekcms-theme';
    this.theme = this.getSavedTheme();
    this.applyTheme(this.theme);
    this.bindToggle();
  }

  getSavedTheme() {
    const saved = localStorage.getItem(this.STORAGE_KEY);
    if (saved === 'light' || saved === 'dark') return saved;
    return 'auto';
  }

  getEffectiveTheme() {
    if (this.theme !== 'auto') return this.theme;
    return window.matchMedia('(prefers-color-scheme: dark)').matches
      ? 'dark' : 'light';
  }

  applyTheme(theme) {
    this.theme = theme;
    const effective = this.getEffectiveTheme();
    document.documentElement.setAttribute('data-theme', effective);
    localStorage.setItem(this.STORAGE_KEY, theme);
    this.updateToggleIcon(effective);
  }

  cycle() {
    const order = ['auto', 'light', 'dark'];
    const current = order.indexOf(this.theme);
    const next = order[(current + 1) % order.length];
    this.applyTheme(next);
  }

  bindToggle() {
    const btn = document.querySelector('[data-theme-toggle]');
    if (!btn) return;
    btn.addEventListener('click', () => this.cycle());

    window.matchMedia('(prefers-color-scheme: dark)')
      .addEventListener('change', () => {
        if (this.theme === 'auto') this.applyTheme('auto');
      });
  }

  updateToggleIcon(effective) {
    const btn = document.querySelector('[data-theme-toggle]');
    if (!btn) return;
    const icons = { auto: '◔', light: '☀', dark: '☾' };
    btn.textContent = icons[this.theme];
    btn.setAttribute('aria-label', 'Tema: ' + this.theme);
  }
}

document.addEventListener('DOMContentLoaded', () => new ThemeSwitcher());

Üç durumlu döngü (otomatik, açık, koyu) iki durumlu bir düğmeden daha kullanışlı, çünkü ziyaretçi sistem ayarının ne olduğunu hatırlamak zorunda kalmadan "sistemimi takip et" seçeneğine dönebiliyor.

Açılışta Yanlış Renk

Karanlık modda en çok şikâyet edilen şey, JavaScript çalışmadan önce bir anlığına beyaz sayfanın görünmesi. Ziyaretçi koyu modu seçmişse ve sayfa önce beyaz açılıp sonra kararıyorsa, bu gece özellikle rahatsız edici.

Çözüm, stil dosyaları yüklenmeden önce <head> içine konan kısa bir satır içi betik:

<script>
(function() {
  var saved = localStorage.getItem('jekcms-theme');
  var theme = saved || 'auto';
  var effective = theme;
  if (theme === 'auto') {
    effective = window.matchMedia('(prefers-color-scheme: dark)').matches
      ? 'dark' : 'light';
  }
  document.documentElement.setAttribute('data-theme', effective);
})();
</script>

Betik tarayıcı sayfayı çizmeden önce çalıştığı için doğru tema ilk kareden itibaren uygulanıyor.

Geçiş Efekti

Renklerin bir anda değişmesi bozuk görünüyor. Kısa bir geçiş, değişimin bilerek yapıldığını hissettiriyor:

*,
*::before,
*::after {
  transition: var(--transition-colors);
}

0,2 saniye fark edilecek kadar uzun, yavaş hissettirmeyecek kadar kısa. Bu seçici sayfadaki bütün elemanlara uygulandığı için çok kalabalık sayfalarda geçişi yalnızca ana kapsayıcılarla sınırlamak daha iyi olabilir.

Görseller

Görseller karanlık modun en çok atlanan kısmı. Fotoğraflara dokunmayın: bir gün batımı fotoğrafı iki modda da aynı görünmeli. Fotoğrafın kenarı koyu zeminden ayrılsın diye ince bir kenarlık ya da gölge eklemek yeterli.

Beyaz zeminli şemalar ve ekran görüntüleri koyu sayfada parlayan dikdörtgenler gibi duruyor. En iyisi <picture> elemanıyla iki ayrı sürüm sunmak. Ayrı sürüm yoksa bir CSS filtresi parlaklığı renkleri ters çevirmeden azaltabilir:

[data-theme="dark"] .diagram img {
  filter: brightness(0.85) contrast(1.1);
}

currentColor kullanan SVG ikonlar kendiliğinden uyum sağlıyor. Şeffaf zeminli bir logo ise koyu zemin için açık renkli ikinci bir sürüm isteyebilir.

Kod Blokları

Sitede kod blokları varsa sözdizimi renklerinin de iki tema için ayrı tanımlanması gerekiyor:

:root {
  --code-bg: #f6f8fa;
  --code-text: #24292e;
  --code-keyword: #d73a49;
  --code-string: #032f62;
  --code-comment: #6a737d;
  --code-function: #6f42c1;
}

[data-theme="dark"] {
  --code-bg: #161b22;
  --code-text: #c9d1d9;
  --code-keyword: #ff7b72;
  --code-string: #a5d6ff;
  --code-comment: #8b949e;
  --code-function: #d2a8ff;
}

Form Elemanları

Tarayıcılar form elemanlarına kendi stillerini uyguladığı için girdi kutuları, metin alanları ve seçim kutuları ayrıca ayarlanmazsa karanlık modda beyaz kalıyor.

input,
textarea,
select {
  background-color: var(--color-bg-elevated);
  color: var(--color-text-primary);
  border: 1px solid var(--color-border-default);
}

/* Karanlık modda otomatik doldurma zeminini düzelt */
[data-theme="dark"] input:-webkit-autofill {
  -webkit-text-fill-color: var(--color-text-primary);
  -webkit-box-shadow: 0 0 0px 1000px var(--color-bg-elevated) inset;
  transition: background-color 5000s ease-in-out 0s;
}

Otomatik doldurma için kullanılan gölge hilesi şık değil ama gerekli: Chrome otomatik doldurulan alanlara normal CSS ile değiştirilemeyen opak bir arka plan uyguluyor ve gölge bu zemini tema rengiyle örtüyor.

Tarayıcı Farkları

  • Chrome ve Edge: prefers-color-scheme sistem ayarını izliyor. Otomatik doldurma zemini için gölge hilesi gerekiyor.
  • Firefox: Karanlık modu desteklemeyen sayfalarda kendi koyu renklerini uygulayabiliyor. Sitenin kendi karanlık modu varsa Firefox buna karışmıyor.
  • Safari: macOS ve iOS'ta prefers-color-scheme tercihine uyuyor. color-scheme özelliği burada özellikle önemli.
:root {
  color-scheme: light;
}

[data-theme="dark"] {
  color-scheme: dark;
}

color-scheme özelliği tarayıcıya sayfanın hangi renk şemalarını desteklediğini söylüyor. Tarayıcı buna göre açılıştaki varsayılan zemin rengini, kaydırma çubuğunu ve form kontrollerinin renklerini ayarlıyor.

Erişilebilirlik

Karanlık mod yalnızca bir görünüm tercihi değil; ışığa duyarlılığı, migreni ya da bazı görme sorunları olan kişiler için bir erişilebilirlik özelliği. Koyu temanın WCAG AA kontrast oranlarını karşıladığından emin olun: normal metin için 4.5:1, büyük metin için 3:1. Geliştirme sırasında WebAIM gibi bir kontrast denetleyiciyle iki temadaki metin ve zemin çiftlerini tek tek kontrol edin.

Tema değiştirici klavyeyle kullanılabilmeli; bunun için <button> elemanı kullanın. Düğmenin aria-label değeri de seçili modu söyleyecek şekilde güncellenmeli ki ekran okuyucular durumu duyurabilsin.

Yazar

Celil Uyanıkoğlu

25 yılı aşkın süredir bilgi işlem sektöründe çalışan bir bilgisayar mühendisi. jekcms'i geliştiriyor ve kendi yayın ağındaki sitelerin tamamını jekcms üzerinde çalıştırıyor - burada yayımlanan her rehber önce o canlı kurulumlarda denenir.

Tüm yazılarını gör →

Lisansınızı Seçin

İlk yıl indirimli yıllık lisans; güncelleme ve destek dahil. Kurulum 30 dakika.

Fiyatlara Bak
  • 30 dakikada kurulum ve yayın
  • 14 profesyonel tema
  • AVIF/WebP görsel optimizasyonu
  • Otomatik SEO - Sitemap, Schema.org
  • ZeroTrack çerezsiz analitik

Yeniliklerden ilk sen haberdar ol

Yeni özellikler, sürüm notları ve CMS rehberleri. Ayda birkaç e-posta gönderiyoruz.