Dinamik arka plan renkleriyle metinlerin okunabilirliğini sağlama

Web özellikleri: contrast-color()

Yeniden kullanılabilir kullanıcı arayüzü bileşenleri (ör. rozetler veya düğmeler) oluştururken ya da dinamik temaları desteklerken, metnin öngörülemeyen bir arka plan renginde okunabilir olmasını sağlamak zor olabilir. contrast-color() CSS işlevi, black veya white olarak çözümlenerek belirtilen arka plan rengine göre kontrast oranını en üst düzeye çıkarır.

En uygun metin rengini belirleme

Bir öğenin değişken veya dinamik olarak eklenen bir arka plan rengi varsa en güvenli metin rengini hesaplamak için tarayıcıyı kullanabilirsiniz.

ZORUNLU: Arka plan rengini (veya özel niteliğini) bağımsız değişken olarak ileterek contrast-color() işlevini kullanarak color özelliğini ayarlayın.

.badge {
  /* Define the background color as a custom property */
  --badge-bg: #e02424;
  background-color: var(--badge-bg);
  /* MANDATORY: Dynamic contrasting color */
  color: contrast-color(var(--badge-bg));
}

YANLIŞ: background-color için contrast-color() kullanmayın. Bu işlev, ön plan renklerinin (metin veya kenarlıklar gibi) belirli bir arka plan rengiyle kontrast oluşturması için özel olarak tasarlanmıştır.

Temayla entegre etme

contrast-color(), CSS özel özellikleri de dahil olmak üzere tüm geçerli <color> değerlerini kabul ettiğinden tasarım sistemlerinde özellikle güçlüdür. Arka plan temalarınızı değişken olarak merkezileştirerek ön plan içeriğinin, tema değiştiğinde (kullanıcı tarafından belirlenen renklere geçildiğinde bile) kontrastını otomatik olarak güncellemesini sağlarsınız.

DO: Uygulamanız genelinde senkronizasyonu garanti etmek için contrast-color() içindeki paylaşılan arka plan değişkenlerine referans verin.

.theme-card {
  background-color: var(--theme-surface-color);
  color: contrast-color(var(--theme-surface-color));
}

.theme-container[data-theme="light"] {
  --theme-surface-color: #f4f4f4;
}
.theme-container[data-theme="dark"] {
  --theme-surface-color: #1a1a1a;
}
.theme-container[data-theme="custom"] {
  --theme-surface-color: var(--user-custom-theme);
}

YAPMAYIN: Arka plan dinamik olduğunda her etkileşim durumu için ayrı bir metin rengini sabit kodlamayın. Bunu yapmak, contrast-color() özelliğinin önlemek için tasarlandığı uyumsuzluğu yeniden ortaya çıkarır.

Yedek stratejiler

contrast-color() içermeyen tarayıcıları desteklemek için bir yedek sağlamanız gerekir. Arka plan rengi biliniyor ve sabitse sabit kodlu bir kontrast renk kullanın. Rengin bilinmediği dinamik arka planlar için aşağıdaki tablodan kullanıcı arayüzü gereksinimlerinize ve tarayıcı destek hedeflerinize göre bir strateji seçin.

Strateji Şu içerikler için ideal: Dikkat edilmesi gereken noktalar
Göreceli renk söz dizimi Yalnızca CSS'ye özel otomatik ve yüksek kaliteli kontrast hesaplaması. En yüksek kalitede yalnızca CSS yedek.
Metin gölgesi Her arka planda okunabilirliği hızla artırın. "Kirli" veya "parlak" görünebilir; tüm tasarımlara uymayabilir.
Metin Konturu Kenar kontrastını sağlarken yazı tipi kalınlığını koruma. Mümkünse harf biçimlerinin incelmesini önlemek için paint-order kullanın.
Yarı Saydam Yer Paylaşımı Metnin arkasında minimum kontrast alanı sağlama. Metnin altındaki arka plan renginin görünümünü değiştirir. Ayrı bir metin öğesi gerektirir.
SVG filtreleri Arka plan değiştikçe güncellenen reaktif kontrast. Ayrı bir metin öğesi gerektirir; geçici bir çözümdür.

RCS, destekleyen tarayıcılarda dinamik renkler için en güçlü otomatik yedekleme çözümünü sunar.

@supports (color: oklch(from red l c h)) {
  .badge {
    /* Highest threshold that passes WCAG. Higher values may be more legible. */
    --threshold: 0.623;
    --l: max(0, sign(var(--threshold) - l));
    color: oklch(from var(--badge-bg) var(--l) 0 h);
  }
}

@supports (color: contrast-color(red)) {
  .badge {
    color: contrast-color(var(--badge-bg));
  }
}

Alternatif CSS Yedekleri

DO: RCS yeterli değilse veya desteklenmiyorsa tasarım kısıtlamalarınıza en uygun yedek seçeneği belirleyin.

1. seçenek: Metin konturu

.badge--stroke {
  -webkit-text-stroke: 4px black;
}

2. seçenek: Harf şekillerini korumak için paint-order ile metin konturu

.badge--stroke {
  -webkit-text-stroke: 4px black;
  paint-order: stroke fill;
}

3. seçenek: Yarı saydam arka plan yer paylaşımı

.badge--overlay {
  position: relative;
  color: #fff;
  overflow: hidden;
}
.badge--overlay::before {
  content: "";
  position: absolute;
  inset: 0;
  background-color: rgb(0 0 0 / 0.4);
  z-index: 0;
}
.badge--overlay span {
  position: relative;
  z-index: 1;
}

4. seçenek: Metin gölgesi

.badge--shadow {
  text-shadow: 0 1px 3px rgb(0 0 0 / 0.8);
}

5. seçenek: SVG filtreleri

  1. Bu SVG filtre tanımını yükleyin. Filtreler için harici ve veri URL'si referanslarını engelleyen bu WebKit hatasından etkilenen Safari sürümlerini desteklemeniz gerekiyorsa doğrudan HTML belgesine eklenmelidir. Aksi takdirde, harici bir dosyadan (SVG dosyası veya CSS'de satır içi) yüklenmelidir.

    <!-- Technique from https://miunau.com/posts/dynamic-text-contrast-in-css/ -->
    <svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="0" style="display: none;">
      <defs>
        <filter id="contrast-filter" color-interpolation-filters="sRGB">
          <feColorMatrix type="matrix"
            values="0.2126 0.7152 0.0722 0 0
              0.2126 0.7152 0.0722 0 0
              0.2126 0.7152 0.0722 0 0
              0 0 0 1 0"/>
          <feMorphology operator="dilate" radius="2"/>
          <feComponentTransfer>
            <feFuncR type="linear" slope="-255" intercept="128"/>
            <feFuncG type="linear" slope="-255" intercept="128"/>
            <feFuncB type="linear" slope="-255" intercept="128"/>
          </feComponentTransfer>
          <feComposite operator="in" in2="SourceGraphic"/>
        </filter>
      </defs>
    </svg>
    
  2. Metni <span> içine alın.

    <div class="badge--svg">
      <span>Badge content</span>
    </div>
    
  3. Filtreyi <span> öğesine uygulayın.

.badge--svg span{
  color: var(--badge-bg);
  filter: url(#contrast-filter);
}