Wenn Sie wiederverwendbare UI-Komponenten wie Badges oder Buttons erstellen oder dynamische Designs unterstützen, kann es schwierig sein, dafür zu sorgen, dass Text vor einer unvorhersehbaren Hintergrundfarbe lesbar ist. Die CSS-Funktion contrast-color() wird zu black oder white aufgelöst, um das Kontrastverhältnis zum angegebenen Hintergrund zu maximieren.
Optimale Textfarbe bestimmen
Wenn ein Element eine variable oder dynamisch eingefügte Hintergrundfarbe hat, können Sie sich darauf verlassen, dass der Browser die sicherste Textfarbe berechnet.
OBLIGATORISCH: Legen Sie die Eigenschaft color mit der Funktion contrast-color() fest und übergeben Sie die Hintergrundfarbe (oder die benutzerdefinierte Eigenschaft) als Argument.
.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));
}
NICHT VERWENDEN: contrast-color() für background-color. Sie wurde speziell für Vordergrundfarben (wie Text oder Rahmen) entwickelt, die sich von einer bestimmten Hintergrundfarbe abheben sollen.
In das Design einbinden
Da contrast-color() jeden gültigen <color>-Wert akzeptiert, einschließlich benutzerdefinierter CSS-Eigenschaften, ist es in Designsystemen besonders nützlich. Wenn Sie Ihre Hintergrunddesigns als Variablen zentralisieren, wird der Kontrast des Vordergrundinhalts automatisch aktualisiert, wenn sich das Design ändert, auch bei benutzerdefinierten Farben.
EMPFOHLEN: Verweisen Sie in contrast-color() auf freigegebene Hintergrundvariablen, um die Synchronisierung in Ihrer Anwendung zu gewährleisten.
.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);
}
NICHT EMPFOHLEN: Eine separate Textfarbe für jeden Interaktionsstatus hartcodieren, wenn der Hintergrund dynamisch ist. Andernfalls wird die Abweichung, die contrast-color() verhindern soll, wieder eingeführt.
Fallback-Strategien
Wenn Sie Browser ohne contrast-color() unterstützen möchten, müssen Sie ein Fallback bereitstellen. Wenn die Hintergrundfarbe bekannt und fest ist, verwenden Sie eine hartcodierte Kontrastfarbe. Wählen Sie für dynamische Hintergründe, bei denen die Farbe unbekannt ist, eine Strategie aus der folgenden Tabelle aus, die Ihren UI-Anforderungen und Browser-Supportzielen entspricht.
| Strategie | OPTIMAL FÜR: | Hinweise |
|---|---|---|
| Relative Farbsyntax | Automatisierte, hochwertige Kontrastberechnung nur mit CSS. | Hochwertiges Fallback nur mit CSS. |
| Textschatten | Schnelle Verbesserung der Lesbarkeit auf jedem Hintergrund. | Kann „schmutzig“ oder „leuchtend“ wirken und passt möglicherweise nicht zu allen Designs. |
| Textstrich | Die Schriftstärke wird beibehalten, während der Kantenkontrast gewährleistet wird. | Verwenden Sie paint-order, um dünnere Buchstabenformen zu vermeiden, falls verfügbar. |
| Transluzentes Overlay | Sorgen Sie für einen Mindestkontrastbereich hinter dem Text. | Ändert die Hintergrundfarbe unter dem Text. Erfordert ein separates Textelement. |
| SVG-Filter | Reaktiver Kontrast, der sich an den Hintergrund anpasst. | Erfordert ein separates Textelement; unsaubere Implementierung. |
Empfohlen: Relative Color Syntax (RCS)
Für Browser, die RCS unterstützen, bietet es den zuverlässigsten automatischen Fallback für dynamische Farben.
@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));
}
}
Alternative Fallbacks für Preisvergleichsportale
RICHTIG: Wählen Sie die Fallback-Option aus, die am besten zu Ihren Designanforderungen passt, wenn RCS nicht ausreicht oder nicht unterstützt wird.
Option 1: Textkontur
.badge--stroke {
-webkit-text-stroke: 4px black;
}
Option 2: Textkontur mit paint-order, um die Buchstabenformen beizubehalten
.badge--stroke {
-webkit-text-stroke: 4px black;
paint-order: stroke fill;
}
Option 3: Transluzentes Hintergrund-Overlay
.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;
}
Option 4: Textschatten
.badge--shadow {
text-shadow: 0 1px 3px rgb(0 0 0 / 0.8);
}
Option 5: SVG-Filter
Diese SVG-Filterdefinition laden. Es muss direkt dem HTML-Dokument hinzugefügt werden, wenn Sie Safari-Versionen unterstützen müssen, die von diesem WebKit-Fehler betroffen sind, der externe und Daten-URL-Verweise für Filter verhindert. Andernfalls sollte es aus einer externen Datei geladen werden, entweder aus einer SVG-Datei oder inline in CSS.
<!-- 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>Fügen Sie den Text in ein
<span>-Element ein.<div class="badge--svg"> <span>Badge content</span> </div>Wenden Sie den Filter auf die
<span>an.
.badge--svg span{
color: var(--badge-bg);
filter: url(#contrast-filter);
}