Renk tekerleğinde birbirine tam karşı konumda duran iki renk, tamamlayıcı çift (complementary pair) oluşturur. Bu tanım basit görünür; ama uygulamada en sık yanlış kurulan renk ilişkisi de bu çiftlerdir. Yüksek kontrast yaratır diye seçilen kombinasyonlar bazen WCAG eşiğinin altında kalır, bazen de gözde titreme hissi (vibration effect) üretir. Renk teorisinin geometrik tanımı ile web performansındaki pratik davranış arasındaki mesafe çoğu tasarım kararında görmezden gelinen yerdir.
Renk tekerleğinde 180 derece
Geleneksel RYB (kırmızı-sarı-mavi) tekerleğinde ve dijital tasarımda kullanılan HSL modelinde tamamlayıcı çift, ton değerlerinin tam 180° fark ettiği iki renkten oluşur. Kırmızı (0°) ile yeşil-cyan arası (180°), turuncu (30°) ile mavi (210°), sarı (60°) ile mor (240°) klasik örneklerdir.
Her yüksek kontrast çifti tamamlayıcı değildir. Kontrast oranı, renk tekerleğindeki açısal konumdan değil; göreli parlaklık (relative luminance) hesabından türetilir. Siyah-beyaz çifti tamamlayıcı değildir; ama 21:1 kontrast oranıyla tüm renkli çiftlerin üzerinde durur. Tersine, saf kırmızı (hsl 0°, 100%, 50%) ile saf yeşil (hsl 120°, 100%, 50%) renk tekerleğinde 120° uzaklıkta olmasına rağmen WCAG 2.1 AA eşiğini karşılamaz çünkü göreli parlaklıkları arasındaki fark 1.28:1 civarındadır.
Split-complementary, tam tamamlayıcının yarattığı titreme sorununa pratik bir yanıt üretir. Bu düzenlemede bir rengin tam karşısındaki değil, o noktanın 30° sağı ve solundaki iki renk kullanılır. Vibration etkisi azalır, kontrast oranı çoğu durumda artar. Analogous çiftler ise tekerleğin aynı bölgesinden (30-60° aralık) gelir; uyum yüksek ama kontrast düşüktür, dolayısıyla birincil metin-zemin kombinasyonu olarak kullanılamaz. Triadic düzen (tekerleği 3 eşit parçaya bölen renkler, yani 120° araları) ise tamamlayıcı değildir; üç rengi dengede tutar ama ikili kontrast ilişkisi kurmaz.
Kontrast oranı ve WCAG 2.1 eşiği
WCAG 2.1 Başarı Kriteri 1.4.3, normal metin için 4.5:1, büyük metin (18pt+ veya 14pt bold) için 3:1 kontrast oranı zorunlu kılar. AAA seviyesinde bu eşikler 7:1 ve 4.5:1'e yükselir. Tamamlayıcı çiftlerin bu eşikleri karşılayıp karşılamadığı ton değerinden değil, lightness değerinden belirlenir.
Somut örnek: hsl(210, 80%, 50%) (mavi) ile hsl(30, 80%, 50%) (turuncu) tam tamamlayıcıdır. Kontrast oranı 1.85:1 civarındadır; AA eşiğinin çok altında. Aynı tonu koruyarak lightness değerlerini ayarladığında, örneğin hsl(210, 80%, 25%) (koyu mavi) ile hsl(30, 80%, 75%) (açık turuncu) kombinasyonu 7.4:1 oranına ulaşır ve AAA uyumlu hale gelir. Tamamlayıcılık ilişkisi korunmuş, ton sabittir; yalnızca parlaklık farkı değişmiştir.
Gözden kaçan nokta şu: tamamlayıcı ton çiftleri, eşit lightness değerlerinde neredeyse hiç WCAG AA eşiğini karşılamaz. Çünkü eşit parlaklıktaki iki rengin göreli luminance farkı sınırlıdır. Bu yüzden "tamamlayıcı = yüksek kontrast" kabulü tasarım kararı olarak hatalıdır.
Kontrast oranını hesaplamak için rengi farklı formatlar arasında dönüştürmek ilk adımdır; çünkü WCAG formülü göreli luminance üzerinden çalışır ve luminance hesabı lineerleştirilmiş RGB bileşenlerine dayanır. HSL veya hex değerinden doğrudan kontrast oranı çıkmaz; ara dönüşüm zorunludur.
Göreli luminance hesabı, ham RGB değerlerini 0-1 aralığına normalleştirir, ardından lineerleştirme eşiği (0.04045) üzerindeyse üs fonksiyonu uygular. Sonuç elde edilen R, G, B değerleri sırasıyla 0.2126, 0.7152 ve 0.0722 ağırlıklarıyla çarpılarak toplanır. İnsan gözünün yeşile daha duyarlı olması, bu ağırlık farkını açıklar; ve tamamlayıcı çiftlerde yeşil bileşenin payı kontrast oranını tahmin edilenden farklı çıkarır.
Vibration effect: göz yorgunluğunun teknik açıklaması
Sorun saturasyonda değil, eşit saturasyonda. İki tamamlayıcı renk aynı saturasyon ve lightness değerindeyken, yani hsl(0, 80%, 50%) kırmızı ile hsl(180, 80%, 50%) camgöbeği yan yana geldiğinde, retinadaki kırmızı ve yeşil koni hücreleri eş zamanlı yüksek uyarım alır. Beyin bu iki sinyali net bir derinlik kararına dönüştüremez; sınır hattı titriyor gibi algılanır. Bu fenomene optik titreme veya vibration effect denir ve Josef Albers'in "Interaction of Color" çalışmalarında detaylandırılmıştır.
Çözüm, tonu koruyup parlaklık veya saturasyon farkı yaratmaktır. Pratikte kullanılan yöntem: biri lightness: 35%, diğeri lightness: 75% olarak ayarlamak. Bu fark retinal sinyaller arasına yeterli luminance gradyanı koyar, titreme algısı kaybolur. Alternatif olarak saturasyon farkı da işe yarar; biri saturation: 90%, diğeri saturation: 40% gibi. Ancak saturasyonu düşürmek rengin canlılığını azaltır; lightness farkı daha az ödün verir.
Eşit saturasyon sorunu logo tasarımında da karşıya çıkar. Kırmızı-yeşil eşit canlılıkta bir logo, düşük çözünürlüklü ekranlarda veya renk körlüğü (deuteranopia) olan kullanıcılarda birbirinden ayrışmaz. Titreme etkisi ortadan kalkar; ama ayrıştırılabilirlik de kaybolur. Renk körlüğü simülatörleri bu riski görünür kılar.
CSS custom properties ile dinamik tamamlayıcı paleti
HSL renk modelinin avantajı şudur: tamamlayıcı rengi hesaplamak için yalnızca H (ton) bileşenine 180 eklemek yeterlidir. CSS calc() fonksiyonu bunu doğrudan destekler.
:root {
--ana-ton: 210;
--ana-renk: hsl(var(--ana-ton), 75%, 40%);
--tamamlayici: hsl(calc(var(--ana-ton) + 180), 75%, 60%);
}
Burada --ana-ton değişkeni tek noktadan yönetilir. Ton değeri değiştiğinde tamamlayıcı otomatik güncellenir. Saturation ve lightness ise farklı tutulmuştur: ana renk 40%, tamamlayıcı 60% lightness almış. Bu asimetri vibration etkisini engeller ve WCAG gerekliliklerine uygun bir fark yaratır.
Dark mode için lightness değerlerini tersine çevirmek yeterlidir:
@media (prefers-color-scheme: dark) {
:root {
--ana-renk: hsl(var(--ana-ton), 75%, 70%);
--tamamlayici: hsl(calc(var(--ana-ton) + 180), 75%, 35%);
}
}
Light modda koyu olan ana renk, dark modda açılır; light modda açık olan tamamlayıcı, dark modda koyulaşır. Ton sabit kalır, kontrast yönü korunur. CSS custom properties bu mantığı tek değişkeni güncelleyerek tüm bileşenlere yayar; hardcode edilmiş hex değerleriyle aynı işlemi yapmak her rengi tek tek değiştirmeyi gerektirir.
Modern CSS'te color-mix() fonksiyonu da bu ilişkiyi farklı bir açıdan ele alır. İki rengi belirli bir renk uzayında karıştırmak, tamamlayıcı geçişlerde yumuşak ara tonlar üretmeye yarar. Ancak color-mix() şu an tüm tarayıcılarda tam destek görmez; üretim ortamında @supports ile koşullu kullanılmalı ve calc() tabanlı HSL yöntemi varsayılan olarak korunmalıdır.
Bir arayüzde hem metin-zemin hem de vurgu-ikon için bu çifti kullanmak isteyenler, HSL modelinde hue, saturation ve lightness değerlerinin birbirini nasıl etkilediğini doğru anlamak zorundadır; çünkü tasarım araçları çoğunlukla hex verir ve CSS hesaplamalarında HSL gerekir.
Renk formatları arasında tamamlayıcı hesaplaması
RGB modelinde tamamlayıcı hesaplamak doğrudan mümkün değildir. RGB, rengi kırmızı-yeşil-mavi bileşenlerinde ifade eder ve bu bileşenler arasında "180° karşılık" gibi bir kavram yoktur. Tamamlayıcıyı bulmak için önce HSL'e dönüştürme, H değerine 180 ekleme, sonra tekrar RGB veya hex'e çevirme gerekir.
Bu dönüşüm zincirinde yuvarlama hataları birikir. Örneğin #3a7bd5 (hex) değeri RGB'ye çevrildiğinde rgb(58, 123, 213) olur. HSL'e dönüşümü hsl(213.5°, 61.5%, 53.1%) verir. Tona 180 eklenince 33.5° çıkar; turuncu bölgesi. Tekrar hex'e çevrildiğinde #d58e3a yerine araç implementasyonuna göre #d58d39 veya #d48f3b çıkabilir. 1-2 birimlik bu fark çoğu durumda görsel olarak algılanmaz; ama programatik renk karşılaştırması yapan sistemler için hata kaynağı oluşturur.
Sorun özellikle düşük saturasyonlu renklerde belirginleşir. Gri tonlarına yakın renklerde (saturation %10-15 altında) ton değeri hesaplama belirsizleşir; bazı kütüphaneler 0° döndürür, bazıları son hesaplanan değeri korur. Bu renklerde tamamlayıcı kavramı matematiksel olarak geçerliliğini yitirir çünkü gri rengin "karşısında" anlamlı bir ton yoktur.
CSS'te renk karşılaştırması yapan veya programatik palet üreten sistemlerde farklı renk formatları arasında dönüşüm yaparak ara değerleri doğrulamak bu sapmaları erkenden yakalar. Özellikle tasarım token'larının koda taşındığı süreçlerde renk değerlerinin format tutarsızlıklardan kaynaklandığı görsel farklar gözden kaçar; kontrastı etkiler.
Tamamlayıcı renk çiftleri renk teorisinin en temel aracı olmayı sürdürür. Ama bu araç, geometrik sezginin yarattığı güvenle değil; kontrast oranı hesabı, vibration analizi ve format dönüşüm tutarlılığıyla birlikte çalışır. Ton eksenindeki 180° fark başlangıç noktasıdır; son karar her zaman sayılara dayanır.