OKLCH vs Helmlab: Hangisi Daha İyi Renk Modeli?
OKLCH ve Helmlab renk uzaylarını STRESS, parametre sayısı ve algısal doğruluk açısından karşılaştırıyoruz. Hangisi insan görüşünü daha iyi modelliyor?
Son birkaç yilda CSS dünyasinda bir devrim yasandi: oklch() fonksiyonu CSS Color Level 4 ile birlikte standart haline geldi. Tasarimcilar ve frontend gelistiriciler, HSL'nin algisa aykiri davranislarindan kurtulup nihayet perceptual (algisal) bir renk uzayina kavustu. Peki oklch() yeterli mi? Yoksa insan görüsünü daha iyi modelleyen bir alternatif var mi?
Bu yazi, Oklab/OKLCH ve Helmlab renk uzaylarini derinlemesine karsilastiriyor. Her ikisinin de guclu ve zayif yanlarini, olculebilir performans farklarini ve pratik kod orneklerini inceliyoruz.
OKLCH Nedir ve Neden Onemli?
Bjorn Ottosson'un 2020'de yayinladigi Oklab, basit ama etkili bir perceptual renk uzayi. Oklch ise ayni uzayin silindirik (Lightness-Chroma-Hue) temsili. CSS'e entegre edilmesiyle birlikte, frontend gelistiricilerin dogal arac kutusunun bir parcasi haline geldi:
/* CSS ile OKLCH kullanimi */
.button-primary {
background: oklch(0.65 0.18 250); /* L=0.65, C=0.18, H=250 (mavi) */
}
.button-primary:hover {
background: oklch(0.55 0.18 250); /* Sadece lightness degisti */
}
.surface {
background: oklch(0.97 0.01 250); /* Cok acik mavi yuzey */
}Oklab'in onemli kazanimlari sunlar:
- Perceptual duzgunluk — HSL'den cok daha iyi. Farkli tonlarda ayni L degeri, benzer parlaklik hissi verir.
- Basitlik — 18 parametre: bir 3x3 matris ve kup kok. Anlasilmasi ve uygulanmasi kolay.
- CSS entegrasyonu —
oklch()tum modern tarayicilarda destekleniyor. - Ton kararliligi — Lightness degistirirken ton kaymasi, HSL'ye kiyasla cok daha az.
Oklab gercekten iyi bir adimdi. Ancak renk biliminin kapsadigi alan, 18 parametreyle modellenebileceginden cok daha genis.
Helmlab: 72 Parametre, 13 Asama
Helmlab, 64.000'den fazla insan renk-farki gozlemine dayanan, 72 serbest parametreli bir perceptual renk uzayi. Oklab'in "yeterince iyi" yaklasimi yerine, insan gorus sisteminin bilinen tum kaprisleri icin ozel asamalar icerir:
- Helmholtz-Kohlrausch etkisi — Doygun renkler daha parlak gorunur. Saf kirmizi, ayni luminanstaki bir griden daha "acik" algilanir. Helmlab bunu dogrudan L eksenine gomerek modeller. Oklab'da bu etki mevcut degil.
- Ton duzeltme — 4 harmonikli Fourier serisiyle, perceptual ton dairesi kalibrasyon sonrasi duzeltilir. Her ton bolgesi bagimsiz olarak ayarlanir.
- Notr duzeltme (NC) — Gri tonlarin a=b=0 olmasini matematiksel olarak garanti eder. Palet uretimi ve gamut mapping icin kritik.
- Rijit rotasyon — ab duzleminde -28.2 derece donusle, ton acilari sezgisel konumlara hizalanir — STRESS metrigini degistirmeden.
- Karanlik L sikistirma — Koyu renklerde ton bagimli ek duzeltme. Koyu maviler ve koyu sarilar farkli islenir.
- Minkowski mesafe metrigi — Basit Oklid mesafesi yerine, CIEDE2000 benzeri cift-bagimli agirliklar kullanir.
Tam pipeline su sekilde ilerler:
XYZ → M1 → power → M2 → hue_correction → H-K → cubic_L → dark_L → chroma_scale → chroma_power → L_chroma → NC → rotation
Her asama tam olarak terslenebilir. Lab'dan XYZ'ye geri donus, Newton iterasyonuyla gerceklestirilir.
STRESS Karsilastirmasi: Rakamlar Ne Diyor?
STRESS (Standardized Residual Sum of Squares), bir renk uzayindaki matematiksel mesafelerin insan algilamasiyla ne kadar uyustugunu olcer. Dusuk = daha iyi. Bu metrik, 64.000'den fazla insan gozlemine karsi hesaplanir.
Bu fark soyut bir rakam degil. Bootstrap guven araliklarinda Helmlab'in %95 CI'si [22.50, 23.93] iken CIEDE2000'in %95 CI'si [27.64, 30.84]. Dagilimlar birbiriyle kesismiyor bile — istatistiksel olarak anlamli bir fark.
Pratik Fark: Palet Uretimi
Rakamlar guzel ama asil soru su: bu fark pratikte ne anlama geliyor? En belirgin etki palet uretiminde ortaya cikiyor.
OKLCH ile Palet
OKLCH'de bir mavi paleti olusturmak icin lightness degerini degistirirsiniz:
/* OKLCH ile mavi paleti */
:root {
--blue-100: oklch(0.95 0.05 250);
--blue-300: oklch(0.75 0.12 250);
--blue-500: oklch(0.60 0.18 250);
--blue-700: oklch(0.40 0.18 250);
--blue-900: oklch(0.25 0.12 250);
}Bu yaklasim HSL'den cok daha iyi sonuc verir. Ancak iki sorun kalir:
- Helmholtz-Kohlrausch etkisi — Yuksek chroma degerlerinde, ayni lightness degeri farkli renkler icin farkli parlaklik hissi yaratir. OKLCH bunu telafi edemez.
- Adim esitligi — L=0.40 ile L=0.60 arasindaki algisal fark, L=0.75 ile L=0.95 arasindaki farktan her zaman farkli olabilir.
Helmlab ile Palet
Helmlab npm paketi, perceptual olarak esit aralikli paletleri otomatik olarak uretir:
import { Helmlab } from 'helmlab';
const hl = new Helmlab();
// Tek satirda Tailwind-tarzi semantik olcek
const scale = hl.semanticScale('#3B82F6');
// {
// '50': '#b3c7ff', // en acik
// '100': '#aabdff',
// '200': '#96aaff',
// '300': '#809aff',
// '400': '#628eff',
// '500': '#3b82f6', // temel renk
// '600': '#0263ca',
// '700': '#0048a2',
// '800': '#003179',
// '900': '#00184b',
// '950': '#000b2f', // en koyu
// }
// Adimlar arasi algisal mesafe esittir:
const d1 = hl.deltaE(scale['300'], scale['400']);
const d2 = hl.deltaE(scale['700'], scale['800']);
// d1 ve d2 birbirine yakin (±%5 icinde)Fark, Helmlab'in her adimda Helmholtz-Kohlrausch etkisini, karanlik bolge sikilamasini ve ton bagimli kroma olceklemesini hesaba katmasi. Sonuc: gozunuzun gordugu araliklar gercekten esit.
DeltaE Karsilastirmasi: Algisal Mesafe Dogrulugu
Renk uzaylarini degerlendirmenin en dolaysiz yolu, iki renk arasindaki "mesafe" tahminlerini insan deneyleriyle karsilastirmaktir. Asagidaki orneklerde, farkli renk ciftleri icin hem OKLCH hem Helmlab mesafelerini hesapliyoruz:
import { Helmlab } from 'helmlab';
const hl = new Helmlab();
// Renk ciftleri ve algisal mesafe karsilastirmasi
const pairs = [
{ name: 'Kirmizi vs Yesil', a: '#e74c3c', b: '#2ecc71' },
{ name: 'Mavi vs Turkuaz', a: '#3498db', b: '#1abc9c' },
{ name: 'Sari vs Turuncu', a: '#f1c40f', b: '#e67e22' },
{ name: 'Siyah vs Koyu Gri', a: '#000000', b: '#333333' },
{ name: 'Beyaz vs Acik Gri', a: '#ffffff', b: '#cccccc' },
];
for (const { name, a, b } of pairs) {
const lab1 = hl.fromHex(a);
const lab2 = hl.fromHex(b);
const dist = hl.deltaE(a, b);
console.log(`${name}: deltaE = ${dist.toFixed(3)}`);
}
// Helmlab mesafeleri, insan deneylerindeki
// "bu iki renk ne kadar farkli?" sorulariyla
// %16 daha uyumlu (Oklab'a kiyasla)Onemli olan mutlak degerler degil, siralamalar ve oranlar. Helmlab'in mesafe tahminleri, insan deneylerindeki oranlarla daha iyi orantili. Ornegin, kirmizi-yesil ciftinin sari-turuncu ciftinden cok daha farkli oldugunu her iki uzay da bilir, ama Helmlab'in orani insan deneylerindeki orana daha yakin.
Helmholtz-Kohlrausch Etkisi: OKLCH'nin Kor Noktasi
Bu efekt, renk biliminin en iyi bilinen ama en az modellenen fenomenlerinden biri. Temel ilke basit: yuksek doygunlukta renkler, ayni luminanstaki notr bir griden daha parlak gorunur.
Pratik etkileri buyuk:
- Ayni OKLCH lightness degerine sahip saf kirmizi ve orta gri, ekranda yan yana koyuldigunda farkli parlaklikte gorunur.
- Palet uretiminde, yuksek chroma degerlerinde aciklik degerleri "kayar" — 500 numarali renginiz beklenenden daha parlak gorunur.
- Kontrast hesaplamalarinda, doygun renklerin algilanan parlakligi yeterince hesaba katilmaz.
Helmlab bu etkiyi dogrudan pipeline'ina gomerek, chroma'ya bagimli bir L kaymasini her renk donusumunde uygular. Sonuc: L=0.5 olan bir doygun kirmizi ve L=0.5 olan bir gri, Helmlab koordinatlarinda gercekten ayni algisal parlakliga sahiptir.
Kod Ornekleri: Pratikte Kullanim
Helmlab Kurulumu
npm install helmlabsRGB Donusumleri
import { Helmlab } from 'helmlab';
const hl = new Helmlab();
// sRGB [0,1] araliginda dogrudan donusum
const lab = hl.fromSrgb([0.231, 0.510, 0.965]); // Tailwind blue-500
console.log(lab);
// [0.625, -0.084, -0.310] (L, a, b tuple)
// Hex donusumleri
const labFromHex = hl.fromHex('#3B82F6');
const backToHex = hl.toHex(labFromHex); // '#3b82f6'DeltaE ile Renk Farki Hesaplama
import { Helmlab } from 'helmlab';
const hl = new Helmlab();
// Iki renk arasindaki algisal mesafe
const distance = hl.deltaE('#3B82F6', '#2563EB');
console.log(`Delta E: ${distance.toFixed(4)}`);
// Ayni rengin farkli tonlari yakin mesafede olmali
const close = hl.deltaE('#3B82F6', '#60A5FA'); // ~0.15
const far = hl.deltaE('#3B82F6', '#EF4444'); // ~0.85
// Mesafe siralamalari insan algisiyla uyumlu:
// close < far (mavi tonlari birbirine yakin, mavi-kirmizi uzak)Semantik Olcek Uretimi
import { Helmlab } from 'helmlab';
const hl = new Helmlab();
// Tailwind CSS tarzi 50-950 olcegi
const blueScale = hl.semanticScale('#3B82F6');
// Ozel adimlarla olcek
const fiveStep = hl.semanticScale('#3B82F6', [100, 300, 500, 700, 900]);
// {
// '100': '#aabdff',
// '300': '#809aff',
// '500': '#3b82f6',
// '700': '#0048a2',
// '900': '#00184b'
// }
// Birden fazla renk icin olcek sistemi
const colors = {
blue: hl.semanticScale('#3B82F6'),
red: hl.semanticScale('#EF4444'),
green: hl.semanticScale('#22C55E'),
amber: hl.semanticScale('#F59E0B'),
};
// Her rengin her adimi algisal olarak tutarliWCAG Kontrast Kontrolu
import { Helmlab } from 'helmlab';
const hl = new Helmlab();
// Kontrast orani hesapla
const ratio = hl.contrastRatio('#3B82F6', '#ffffff');
console.log(`Kontrast: ${ratio.toFixed(2)}`); // 3.68
// AA standardini karsilayacak sekilde ayarla
const accessible = hl.ensureContrast('#3B82F6', '#ffffff', 4.5);
// Helmlab, lightness ekseninde ton ve chroma'yi koruyarak ayarlar
// WCAG seviyesi kontrolu
hl.meetsContrast('#000000', '#ffffff', 'AA'); // true
hl.meetsContrast('#3B82F6', '#ffffff', 'AA'); // false (3.68 < 4.5)
hl.meetsContrast('#1D4ED8', '#ffffff', 'AA'); // trueOKLCH mi Helmlab mi? Hangi Durumda Hangisi?
Bu iki uzay birbirinin rakibi degil — farkli katmanlarda yasiyorlar.
OKLCH su durumlarda idealdir:
- Saf CSS renk tanimlari — JavaScript gerektirmeden, CSS'te dogrudan perceptual renkler tanimlamak icin.
- Basit palet degisiklikleri — Lightness veya hue'yu kucuk miktarda kaydirmak icin.
- Tarayici uyumlulugu — Ek kutuphane veya build adimi olmadan calismasi gereken yerlerde.
- Ogrenme egrisi — Renk bilimine yeni baslayan gelistiriciler icin iyi bir giris noktasi.
Helmlab su durumlarda ustun gelir:
- Tasarim sistemi paletleri — 50-950 olceklerinde her adimin gercekten esit aralikli olmasi gerektiginde.
- Kontrast hesaplamalari — H-K etkisinin hesaba katilmasi gereken hassas erisilebirlik kontrollerinde.
- Renk farki karsilastirmalari — "Bu iki renk ne kadar benzer?" sorusuna dogru cevap verilmesi gerektiginde.
- Profesyonel renk isleme — Uretim kalitesinde renk dogrulugu gerektiren uygulamalarda.
- Gamut mapping — Renklerin sRGB veya Display P3 sinirlarinda dogru bicimde kesirlenmesi gerektiginde.
Birlikte Kullanim
Ideal yaklasim, her ikisini de kullanmaktir. CSS'te oklch() ile temel renkleri tanimlayin, ardından palet uretimi, mesafe hesaplamalari ve kontrast garantileri icin Helmlab'i kullanin:
import { Helmlab } from 'helmlab';
const hl = new Helmlab();
// 1. Temel rengi Helmlab ile tanimla ve dogrula
const brandBlue = '#3B82F6';
const info = hl.info(brandBlue);
console.log(`L: ${info.L.toFixed(3)}, C: ${info.C.toFixed(3)}, H: ${info.H.toFixed(1)}`);
// 2. Tum palet adimlarini Helmlab ile uret
const palette = hl.semanticScale(brandBlue);
// 3. Her adimin kontrastini kontrol et
for (const [level, hex] of Object.entries(palette)) {
const onWhite = hl.contrastRatio(hex, '#ffffff');
const onBlack = hl.contrastRatio(hex, '#000000');
console.log(`${level}: ${hex} | beyaz: ${onWhite.toFixed(1)} | siyah: ${onBlack.toFixed(1)}`);
}
// 4. CSS degiskenleri olarak cikti
const cssVars = Object.entries(palette)
.map(([k, v]) => ` --blue-${k}: ${v};`)
.join('\n');
console.log(`:root {\n${cssVars}\n}`);Teknik Karsilastirma Tablosu
Sonuc
OKLCH, CSS dunyasina perceptual renkleri tasimak icin atilmis onemli bir adimdi ve hala CSS icindeki en iyi yerlesik renk uzayi. Ancak 18 parametreli bir model, insan gorus sisteminin karmasikligini tam olarak yakalayamaz.
Helmlab, 64.000 insan gozlemine dayanan 72 parametresiyle, renk farki tahminlerinde OKLCH'ye gore %16, CIEDE2000'e gore %20 daha dogru. Helmholtz-Kohlrausch etkisi, notr duzeltme ve ton bagimli kalibrasyon gibi mekanizmalar, ozellikle palet uretimi ve kontrast hesaplamalarinda somut bir fark yaratiyor.
10.3 KB'lik npm paketiyle, herhangi bir JavaScript projesine birkaç satirda entegre edilebilir:
npm install helmlabKaynak kod: GitHub | Paket: npm
Bu yazi, Helmlab serisi 16 blog yazisinin ilkidir. Bir sonraki yazida: HSL vs Helmlab — HSL'nin neden tasarim sistemi paletleri icin yetersiz kaldigi.