Açık gri yazı, beyaz arka plana çok şık görünür; ofis bilgisayarında, retina ekranda, parlak ışıkta gayet okunaklı sanılır. Ama otobüste güneş ekrana vururken telefon kullanan birinin gözünden bakıldığında o yazı kaybolmuş, sayfa boş bir kağıda dönmüştür. axe-core'un color-contrast kuralı işte bu görünmeyen kullanıcılar için var.
1. color-contrast hatası nedir?
Bu kural, sayfadaki yazıların arka planlarına göre yeterli kontrasta sahip olup olmadığını ölçer. Kontrast oranı, yazı rengi ile arka plan renginin parlaklık farkını anlatan tek bir sayıdır: 1:1 (aynı renk, görünmez) ile 21:1 (saf siyah / saf beyaz) arasında değişir. WCAG'ın belirlediği eşikler şunlardır:
- AA — Normal yazı: en az 4.5:1
- AA — Büyük yazı (18pt veya 14pt+ kalın): en az 3:1
- AAA — Normal yazı: en az 7:1
- AAA — Büyük yazı: en az 4.5:1
- UI bileşenleri ve odak halkaları (1.4.11): en az 3:1
axe-core, tarayıcının render ettiği gerçek pikselleri okur, yazıyı arka planının üzerine yerleştirir ve bu eşiklerin hangisini kaçırdığını rapor eder. Sayfada bir tek satır bile eşiğin altında kalsa, kural kırılmış sayılır.
2. Neden bu kadar önemli?
Çevrenize bakın: gözlüklü her dört kişiden biri, 50 yaş üstü neredeyse herkes, renk körü olan her on iki erkekten biri sayfanızda yeterli kontrast olmadığında kelimeleri okuyamaz. Sayıyı bütün topluma yaydığımızda toplam ziyaretçilerinizin yüzde 8 ila 12'si düşük kontrastla mücadele ediyor demektir. Bu kişiler erişilebilirlik aracı kullanmıyor — yalnızca yazınızı okuyamıyor ve sayfayı kapatıp gidiyor.
color-contrast, axe-core taramalarında en sık karşılaşılan hata sırasını bırakmıyor. Keysonar tarayıcısının yakın zamanda gezdiği sitelerde toplam erişilebilirlik ihlallerinin neredeyse üçte biri bu tek kuraldan geliyor. Sebep tek başına markaların açık gri tipografi sevdası: #999, #aaa, #ccc tonlarındaki yazılar tasarım rehberlerine girip her yere yayılıyor.
3. Hangi durumlarda tetiklenir?
Tarama verilerinde tekrar tekrar gördüğümüz altı tipik hata kalıbı:
- Beyaz üstüne açık gri gövde metni:
#888ile beyaz arasındaki kontrast yalnızca 3.54:1, yani AA'yı kaçırıyor. Bu en yaygın ihlal. - Renkli arka plan üstünde aynı renkten daha açık yazı: Mor butonun üstünde lavanta renginde yazı tipik bir “ton-içi-ton” tasarım hatası.
- Görsel üstüne yerleştirilmiş yazı: Hero görselin parlak alanına denk gelen başlık. Aynı yazı, görselin koyu kısmında okunaklı, açık kısmında kaybolmuş olur.
- Devre dışı buton metni: Tasarımcılar “disabled” durumunu solgun göstermek için çoğu zaman
#bbb,#ccckullanıyor; sonuç oranlar AA'nın çok altında. - Placeholder yazısı: Form alanlarındaki ipucu metni, kullanıcı yazı yazana kadar görünür kalır ve onun da kontrastı 4.5:1'in üzerinde olmak zorundadır.
- Linkler ile gövde metni arasında ayırt edilebilirlik yok: Maviye yakın bir renk seçilmiş ama gövde metniyle karşılaştırıldığında kontrast oranı 3:1'in altında kalıyorsa, okuyucu hangi kelimenin tıklanabilir olduğunu anlayamıyor.
4. Doğru çözümler
4.1 Açık gri tipografi sorunu
En sık görülen problem: tasarımcının “daha sakin görünsün” diye gövde metnini #888 olarak ayarlaması. Bunu #595959'a indirmek hem WCAG AA'yı geçirir hem de görsel hiyerarşiyi bozmaz.
.body-text {
color: #888;
background: #fff;
}.body-text {
color: #595959;
background: #fff;
}4.2 Marka renginin üstünde okunaklı yazı
Sarı, açık yeşil, fıstık yeşili gibi parlak marka renkleri beyaz yazıyla eşleşmeye direnir. Çözüm; marka rengini ya yazının arka planı için biraz koyulaştırmak ya da o yüzeylerde sistemin koyu varyantını kullanmaktır.
<button style="background: #FFD400; color: #fff">
Sepete ekle
</button><button style="background: #FFD400; color: #1A1A40">
Sepete ekle
</button>4.3 Görsel üstüne yerleştirilen yazı
Hero görselin üstüne metin koyacaksanız, görselin tam metnin altına denk gelen kısmını yarı saydam bir koyu katmanla “perdelemek” en güvenli yöntemdir. Bu sayede arka plan ne kadar değişirse değişsin yazının arkasındaki taban hep aynı koyulukta kalır.
.hero {
position: relative;
background-image: url('/hero.jpg');
}
.hero::after {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(
to bottom,
rgba(0,0,0,0.55) 0%,
rgba(0,0,0,0.20) 70%
);
}
.hero h1 {
position: relative;
z-index: 1;
color: #fff;
}4.4 Tasarım sistemi seviyesinde çözüm
Renkleri tek bir kaynakta toplamak, kontrast hatalarının tek tek değil toplu olarak çözülmesini mümkün kılar. Tasarım token'ları kullanırken her token'ın hangi yüzeylerde kullanılabileceğini belgeleyin.
// tailwind.config.ts
export default {
theme: {
extend: {
colors: {
// Kullanım: yalnızca beyaz arka plan üstünde
ink: {
DEFAULT: '#1A1A1A', // 16.5:1 ✓
muted: '#595959', // 7.0:1 ✓
subtle: '#737373', // 4.6:1 ✓ (sınırda — 12px+ yazıda kullanma)
},
// Kullanım: yalnızca koyu arka plan üstünde
snow: {
DEFAULT: '#FFFFFF',
muted: '#D4D4D4', // 9.0:1 ✓ (#1A1A1A üstünde)
},
},
},
},
};4.5 Devre dışı durumlar
5. Kontrast oranı nasıl hesaplanır?
Tarayıcı ve axe-core, WCAG'ın tanımladığı bağıl parlaklık (relative luminance) formülünü uygular. Kabaca şöyle çalışır: her renk önce sRGB'den lineer ışığa çevrilir, ardından insan gözünün yeşile, kırmızıya ve maviye duyarlılığına göre ağırlıklandırılır:
function relativeLuminance({ r, g, b }) {
const channel = (c) => {
c = c / 255;
return c <= 0.03928
? c / 12.92
: Math.pow((c + 0.055) / 1.055, 2.4);
};
return 0.2126 * channel(r)
+ 0.7152 * channel(g)
+ 0.0722 * channel(b);
}
function contrastRatio(fg, bg) {
const L1 = relativeLuminance(fg);
const L2 = relativeLuminance(bg);
const [light, dark] = L1 > L2 ? [L1, L2] : [L2, L1];
return (light + 0.05) / (dark + 0.05);
}Bu formülün önemli bir özelliği, yeşil kanalın (0.7152) çok daha ağır basmasıdır. Yani yeşil tonlu yazılar, eşit RGB değerlerine sahip mavi tonlu yazılara göre çok daha parlak algılanır. Renk tonu seçimi yaparken bunu unutmamak gerekir.
6. Gözden kaçan durumlar
- Hover ve focus durumları: Tasarımcılar genelde varsayılan durumun kontrastını ölçer; ama buton üzerine gelince yazı rengi soluyorsa o durum da AA'yı geçmek zorundadır.
- Yarı saydam katmanlar: rgba ile katman üst üste koyduğunuzda gerçek renk ekrana ulaşan birleşik renktir. axe-core bu birleşimi hesaplayamayabilir, manuel kontrol gerekir.
- Karanlık mod: Aydınlık modda kusursuz çalışan paletin koyu versiyonu otomatik geçerli olmaz. Dark mode için ayrı bir kontrast denetimi yapılmalıdır.
- Markanın ana rengi: Marka kimliği için zorunlu görünen sarı/turuncu/açık yeşil tonları metin renginde değil, yalnızca arka plan veya dekoratif öge olarak kullanılmalıdır. Logo metni WCAG'dan muaftır; gövde metni değil.
- Canvas / SVG'ye yazılmış yazı: axe-core HTML metnini denetler, canvas'a piksel olarak çizilen yazıyı göremez. Grafik içindeki yazıların kontrastını elle kontrol edin.
7. Nasıl test edilir?
- Chrome DevTools » Renk seçici: Element panelinde renk değerine tıkladığınızda otomatik olarak AA / AAA badge'leri görünür. Bu, geliştirme sırasında anlık geri bildirim almanın en hızlı yoludur.
- WebAIM Contrast Checker: İki rengi tek tek girip oranı görmek için en pratik web aracı. Renk gradyanlarında orta tonu test ederken işe yarar.
- Stark (Figma eklentisi): Tasarım aşamasında her bileşenin tüm renk kombinasyonlarını otomatik tarar. “Geliştirmeden önce yakalama” stratejisinin merkezindedir.
- Keysonar SEO Tools: Sitenin tamamını tek seferde tarar, hangi sayfalarda color-contrast hatası bulunduğunu listeler ve zaman içindeki gerilemeleri takip eder. Bu özellikle de düzinelerce sayfaya yayılmış küçük tonlama hatalarını yakalamak için paha biçilemezdir.
8. Hızlı kontrol listesi
- Gövde yazısı, beyaz arka planda en az 4.5:1 kontrast oranını sağlıyor.
- Buton yazıları (özellikle marka renkli) AA seviyesini geçiyor.
- Placeholder yazısının kontrastı, gerçek kullanıcı metniyle aynı eşikleri sağlıyor.
- Hover, focus ve active gibi etkileşim durumlarında da kontrast 4.5:1 üzerinde kalıyor.
- Görsel üzerine konan yazıların altında scrim veya degrade katman var.
- Linkler, çevresindeki gövde metninden 3:1 oranında ayırt edilebiliyor (renk tek başına yeterli değilse altı çizili).
- Tasarım sistemi token'larında her renk-yüzey eşleşmesinin oranı belgelenmiş.
- Karanlık mod, aydınlık moddan ayrı olarak test edildi.
9. Referanslar
- WCAG 2.1 SC 1.4.3 — Contrast (Minimum) — AA
- WCAG 2.1 SC 1.4.6 — Contrast (Enhanced) — AAA
- WCAG 2.1 SC 1.4.11 — Non-text Contrast — AA
- W3C: Web Content Accessibility Guidelines — Contrast Ratio
- WebAIM: Understanding the Contrast Algorithm