Ab Version 15 unterstützt Safari das theme-color <meta>-Tag sowohl unter macOS als auch unter iOS. Das sind aufregende Neuigkeiten, denn nun unterstützt der erste Desktop-Browser dieses <meta>-Tag und es unterstützt auch das media-Attribut und das prefers-color-scheme Media Feature.
Ich habe dem theme-color Meta-Tag nie viel Beachtung geschenkt, aber jetzt ist es ein guter Zeitpunkt, seine Funktionen und Einschränkungen kennenzulernen und einige interessante Anwendungsfälle zu entdecken.
Heads up! Safari hat die Unterstützung für das theme-color Meta-Tag in Safari Technology Preview (127) entfernt. Das war nur vorübergehend, ab Version 128 wird es wieder unterstützt.
Funktionen und Einschränkungen
So habe ich das theme-color Meta-Tag in den letzten Jahren verwendet: nur ein guter alter Hex-Code für das content-Attribut.
<meta name="theme-color" content="#319197">

Nach Tests, die ich Anfang des Jahres gemacht habe, funktioniert dies in Chrome, Brave und Samsung Internet unter Android, installierten PWAs in Chrome und jetzt auch in Safari Technology Preview.

CSS-Farbunterstützung
Eine der ersten Fragen, die mir in den Sinn kamen, war: "Können wir auch Farbschlüsselwörter, hsl(), rgb() verwenden?" Laut der HTML-Spezifikation kann der Wert des Attributs jede CSS-Farbe sein. Ich habe diesen theme-color Test-CodePen erstellt, um das zu überprüfen.
<meta name="theme-color" content="hsl(24.3, 97.4%, 54.3%)">

theme-color Meta-Tags unterstützen CSS-Farben in jeder Form: Schlüsselwörter, rgb(), hsl() oder Hex-Code.
Alle unterstützten Browser unterstützen auch hsl() und rgb(). Das ist großartig, weil es uns ermöglicht, einige ziemlich coole Dinge mit JavaScript zu tun. Wir werden später darüber sprechen, aber zuerst sehen wir uns einige Einschränkungen an.
Transparenz
HEX-Codes, rbg(), hsl() und Schlüsselwörter werden gut und konsistent unterstützt, aber Farben, die Transparenz enthalten: nicht so sehr. Eigentlich werden sie in den meisten Browsern unterstützt, aber die Ergebnisse sind nicht sehr konsistent und manchmal unerwartet.
transparent ist eine CSS-Farbe und wenn sie im theme-color Meta-Tag verwendet wird, machen die meisten Browser das Erwartete. Alle normalen mobilen Browser ändern keine Farbe und zeigen die Standard-Tab-Leiste an, aber Safari unter macOS und die Chrome Canary PWA unter macOS machen die Tab-Leiste schwarz. Die PWA unter Android greift auf theme-color zurück, das in manifest.json definiert ist, worüber wir gleich sprechen werden.

theme-color Meta-TagAlle Browser interpretieren hsla() und rgba(), aber sie setzen den Alpha-Wert auf 1. Die einzige Ausnahme ist Safari unter macOS; es interpretiert die Transparenz, aber es scheint, dass die transparente Farbe eine schwarze Basislinie hat. Dies hat zur Folge, dass die hellorange Farbe wie dunkles Orange aussieht.

hsla() angewendet auf das theme-color Meta-TagNeue Farbfunktionen
Safari 15 ist der erste Browser, der die Farbfunktionen lab(), lch() und hwb() unterstützt. Diese Funktionen funktionieren, wenn Sie sie in CSS verwenden, aber nicht, wenn Sie sie im theme-color Meta-Tag verwenden.
Alle drei Deklarationen funktionieren in Safari 15 einwandfrei
body {
background-color: hwb(27 10% 28%);
background-color: lch(67.5345% 42.5 258.2);
background-color: lab(62.2345% -34.9638 47.7721);
}
Wenn Sie eine der neuen Farbfunktionen im theme-color Meta-Tag verwenden, interpretiert Safari diese nicht und greift auf seinen eigenen Algorithmus zur Farbauswahl zurück. Es ist wahrscheinlich, dass Safari die Hintergrundfarbe Ihres <body> für die theme-color verwendet, was bedeutet, dass Sie möglicherweise das erwartete Ergebnis erhalten, ohne die theme-color explizit zu definieren.
<meta name="theme-color" content="lab(29.2345% 39.3825 20.0664)">

Bitte beachten Sie, dass Safari 15 zum Zeitpunkt der Erstellung der einzige Browser ist, der diese neuen Farbfunktionen unterstützt.
currentColor
Wenn CSS-Farben unterstützt werden, sollte currentColor auch funktionieren, oder? Nein, leider nicht in irgendeinem Browser. Es ist wahrscheinlich ein ungewöhnlicher Anwendungsfall, aber ich würde erwarten, dass wir die theme-color auf die aktuelle Farbe des <body>- oder <html>-Elements setzen können.
<style>
body {
color: blue;
}
</style>
<meta name="theme-color" content="currentColor">
Ich habe ein Ticket im WebKit-Bugtracker gefunden mit dem Titel "<meta name="theme-color" content="..."> sollte auch CSS currentcolor unterstützen." Die Unterstützung könnte sich in Zukunft ändern, wenn jemand das Ticket aufgreift.
Verbotene Farben
Als ich CSS-Farbschlüsselwörter testete, verwendete ich die Farbe red, und es funktionierte nicht. Zuerst dachte ich, dass Schlüsselwörter nicht unterstützt werden, aber blue, hotpink und green funktionierten einwandfrei. Wie sich herausstellt, gibt es einen engen Farbbereich, den Safari nicht unterstützt, Farben, die die Verwendung der Benutzeroberfläche beeinträchtigen würden. red funktioniert nicht, weil es optisch zu nahe an der Hintergrundfarbe des Schließknopfes in der Tab-Leiste liegt. Diese Einschränkung ist spezifisch für Safari, in allen anderen unterstützten Browsern scheint jede Farbe einwandfrei zu funktionieren.

theme-color auf red setzen, verwendet Safari jede Farbe, die es für angemessen hält.Benutzerdefinierte Eigenschaften
Ich weiß nicht genug über die Interna von Browsern und benutzerdefinierten Eigenschaften und ob es überhaupt möglich ist, auf benutzerdefinierte Eigenschaften im <head> zuzugreifen, aber ich habe es trotzdem versucht. Leider hat es in keinem Browser funktioniert.
<style>
:root {
--theme: blue;
}
</style>
<meta name="theme-color" content="var(--theme)">
Das ist ziemlich alles, was ich über die grundlegende Unterstützung des theme-color Meta-Tags wissen wollte. Als Nächstes sehen wir uns an, wie man den Dunkelmodus für die Tab-Leiste implementiert und wie nicht.
Dunkelmodus
Safari 15 ist der erste Desktop-Browser, der das media-Attribut und die prefers-color-scheme Media Feature auf theme-color Meta-Tags unterstützt. Ab Version 93 unterstützt Chrome dies ebenfalls, aber nur für installierte Progressive Web Apps.
Laut der Web-App-Manifest-Seite auf web.dev wählen Browser, wenn Sie mehrere theme-color Meta-Tags definieren, das erste Tag aus, das übereinstimmt.
<meta name="theme-color" content="#872e4e" media="(prefers-color-scheme: dark)">
Ich war gespannt darauf, herauszufinden, was in Browsern passiert, die das media-Attribut nicht unterstützen. Ich habe eine Demo-Seite zum Testen des Dunkelmodus erstellt, die die obigen Meta-Tags enthält und es Ihnen auch ermöglicht, die Website als PWA zu installieren. Die webmanifest.json enthält eine weitere Farbbestimmung für die theme-color.
{
"name": "My PWA",
"icons": [
{
"src": "https://via.placeholder.com/144/00ff00",
"sizes": "144x144",
"type": "image/png"
}
],
"start_url": "/theme-color-darkmode.html",
"display": "standalone",
"background_color": "hsl(24.3, 97.4%, 54.3%)",
"theme_color": "hsl(24.3, 97.4%, 54.3%)"
}
So zeigen unterstützte Browser die Tab-Leiste im Lichtmodus an. Es spielt keine Rolle, ob ein Browser das media-Attribut unterstützt oder nicht, er wird den ersten Meta-Tag unabhängig davon interpretieren.

So sieht die Tab-Leiste auf derselben Seite im Dunkelmodus aus. Diese Ergebnisse sind interessanter, da sie leicht variieren. Die Canary PWA und Safari unterstützen und zeigen die dunkle Farbe an. Alle mobilen Browser verwenden ihr Standard-Styling für die dunkle Tab-Leiste, mit Ausnahme von Samsung Internet, das das helle Styling verwendet, da es das prefers-color-scheme Media Feature nicht unterstützt. (TIL: Das sollte sich in naher Zukunft ändern.)

Ich habe einen letzten Test gemacht. Ich wollte sehen, was passiert, wenn ich nur eine Theme-Farbe für den Dunkelmodus definiere, aber die Seite im Lichtmodus aufrufe.
<meta name="theme-color" content="#872e4e" media="(prefers-color-scheme: dark)">

Diese Ergebnisse haben mich am meisten überrascht, da ich erwartet hatte, dass alle mobilen Browser das media-Attribut ignorieren und trotzdem die dunkle Farbe im Meta-Tag verwenden würden. Aber der normale Chrome Canary ignoriert die gesamte Meta-Tag, auch wenn er das media-Attribut nicht unterstützt. Wie erwartet, greifen beide Canary PWAs auf die in der Manifestdatei definierte Farbe zurück.
Das andere Interessante ist, dass Safari eine theme-color anzeigt, obwohl ich keine für den Lichtmodus definiert habe. Das liegt daran, dass Safari selbst eine Farbe auswählt, wenn Sie keine theme-color angeben. In diesem Fall verwendet es die Hintergrundfarbe der Seite, aber es könnte auch die Hintergrundfarbe des <header>-Elements verwenden, zum Beispiel.
Wenn Sie eine Theme-Farbe für Licht- und Dunkelmodus definieren möchten, ist es am besten, beide Farben zu definieren und den ersten Meta-Tag als Fallback für Browser zu verwenden, die das Media-Feature nicht unterstützen.
<meta name="theme-color" content="#319197" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#872e4e" media="(prefers-color-scheme: dark)">
Safari hat bewiesen, dass theme-color auch auf Desktop-Browsern hervorragend funktioniert. Ich bin sicher, dass Designer und Entwickler viele kreative Wege finden werden, dieses Meta-Tag zu nutzen, besonders da der Wert über JavaScript geändert werden kann. Ich habe einige interessante Demos zur Inspiration gesammelt und erstellt.
Demos und Anwendungsfälle
Theming
poolsuite.net bietet verschiedene Themes für die Website und ändert die theme-color entsprechend.

Max Böck ändert ebenfalls die theme-color auf seiner Website, wenn Sie das Theme wechseln.

Seiten-Theming
Die meisten Websites bieten keine benutzerdefinierten Themes, aber Sie können Ihren Seiten trotzdem das gewisse Etwas verleihen. Dave verwendet verschiedene Schlüsselfarben in seinen Blog-Posts für Links und Icons und jetzt auch in der Tab-Leiste.

Verläufe
Wenn Sie Verläufe auf Ihrer Seite verwenden, können Sie Ihr Styling hervorheben, indem Sie den Verlauf über den gesamten Browser spannen lassen. Das theme-color Meta-Tag unterstützt keine Verläufe, aber Sie können die gleiche Farbe für das Meta-Tag und die Startfarbe des Verlaufs des Hintergrunds Ihrer Seite verwenden.
<meta name="theme-color" content="rgb(0, 235, 255)">
<style>
body {
background: linear-gradient(rgb(0, 235, 255), #08124a);
}
</style>

Formularvalidierung
Ich habe diesen Proof of Concept eines Formulars, das die theme-color bei der Formularvalidierung ändert, gebaut. Es beginnt mit einer blauen Tab-Leiste, die rot wird, wenn die übermittelten Daten ungültig sind, oder grün, wenn sie gültig sind.

const email = document.querySelector('input')
const themeColor = document.querySelector('meta[name="theme-color"]')
const msg = document.querySelector('[aria-live]')
let color = '#FA0000'
let message = 'Error message'
document.querySelector('button').addEventListener('click', (e) => {
e.preventDefault()
email.reportValidity()
email.setAttribute('aria-invalid', true)
if (email.validity.valid) {
color = '#00FF00'
message = "Success message!"
email.setAttribute('aria-invalid', false)
}
msg.textContent = message
themeColor.setAttribute('content', color)
});
Disco-Modus
Ich sage nicht, dass Sie es tun sollten, aber Sie könnten Ihre Website im 💃 Disco Mode 🕺 im Kombination mit setInterval und hsl() Farben erstellen.
/*
Inspired by https://twitter.com/argyleink/status/1408184587885309952
*/
const motion = window.matchMedia("(prefers-reduced-motion: no-preference)");
// Check if users don't have a preference for reduced motion
if (motion.matches) {
let scheme = document.querySelector('meta[name="theme-color"]')
let hue = 0
let color
setInterval(() => {
color = `hsl(${hue+=5} 50% 30%)`
document.body.style.background = color;
scheme.setAttribute('content', color)
}, 50)
Scrollen
Stuart hatte eine großartige Idee, er schlug vor, die Theme-Farbe beim Scrollen zu ändern. Ich habe diesen schnellen Prototyp gebaut, wieder mit hsl()-Farben.
Bitte tun Sie dies nur, wenn es die Leistung nicht negativ beeinträchtigt.
Max hat eine Demo erstellt, in der er die theme-color basierend auf der Hintergrundfarbe des aktuellen Abschnitts im Viewport mittels Intersection Observer ändert.
const setThemeColor = (color) => {
const meta = document.querySelector('meta[name="theme-color"]')
if (meta) {
meta.setAttribute('content', color)
}
}
if ("IntersectionObserver" in window) {
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
const { isIntersecting, target } = entry
if (isIntersecting) {
const color = window.getComputedStyle(target).getPropertyValue("background-color");
setThemeColor(color)
}
})
}, {
root: document.getElementById('viewport'),
rootMargin: "1px 0px -100% 0px",
treshold: 0.1
})
document.querySelectorAll('.section').forEach(section => {
observer.observe(section)
})
}
Farbe extrahieren
Eine weitere interessante Idee ist, die dominante oder durchschnittliche Farbe aus Ihren Header-Bildern automatisch zu extrahieren und sie als theme-color zu verwenden.

<script type="module">
import fastAverageColor from "https://cdn.skypack.dev/[email protected]";
const fac = new fastAverageColor();
fac.getColorAsync(document.querySelector('img'))
.then(color => {
document.querySelector('meta[name="theme-color"]').setAttribute('content', color.rgba)
})
.catch(e => {
console.log(e);
});
</script>
<img src="/amy-humphries-2M_sDJ_agvs-unsplash.jpg" alt="A sea star on blue sand." />
Das ist nur eine Handvoll Ideen, aber ich mag bereits, wohin die Reise geht, und ich bin sicher, dass Sie sich noch kreativere Wege einfallen lassen werden, das theme-color Meta-Tag zu nutzen.
theme-color funktioniert bei mir auf Safari 15 auf Big Sur nicht. Passiert das noch jemandem?
Wie Miguel bereits erwähnt hat, haben sie die Unterstützung in der aktuellen Version von Safari TP (127) entfernt.
https://developer.apple.com/safari/technology-preview/release-notes/
Was mir seltsam vorkommt, ist, dass es anscheinend nur mit bestimmten Farben funktioniert, während ich das schreibe. Zum Beispiel funktioniert "#eac8df" nicht, aber "#9a702a" schon. Und das alles nur auf dem Desktop, auf iOS15 scheint es gut zu funktionieren. Ich bin hier etwas ratlos.
Macht es noch Sinn, so etwas
in den
headeinzufügen?Gute Frage! Ich hatte noch keine Gelegenheit, auf dem mobilen Safari zu testen, aber ich werde den Beitrag aktualisieren, sobald ich das getan habe.
Dies wurde in der letzten Safari Technology Preview-Aktualisierung (Release 127) entfernt, aber basierend auf ihrer Notiz zu Theme Color sieht es so aus, als wäre es vorübergehend.
https://developer.apple.com/safari/technology-preview/release-notes/
In Safari Technology Preview Release 128 (gestern) funktioniert dies wieder.
Danke für die Information, Anders. Ich habe den Beitrag aktualisiert!
Ich habe festgestellt, dass bei iOS PWA-Modus, wenn man die Theme-Farbe ändert, ein unerwarteter Übergangseffekt auftritt, aber auf dem mobilen Safari gibt es keinen solchen Effekt. Ich habe alle Übergänge für html- und body-Tags in CSS deaktiviert, aber der Übergangseffekt besteht immer noch. Wissen Sie, wie man das deaktivieren kann?
Was meinen Sie mit "Theme-Farbe ändern"? Wechseln vom Licht- zum Dunkelmodus? Und welche Art von unerwartetem Übergang? Haben Sie einen Link, den ich zum Testen verwenden kann?
Hier ist eine schöne Demo-Seite: https://roger.pub/theme-color-preview/
Es funktioniert nicht unter macOS 12.1 Safari 15.2. Aber es funktioniert unter iOS Safari.
Hallo! Ist es möglich, einen Effekt wie "black-translucent" zu erzielen? Ich habe im Grunde einen animierten Hintergrund auf meiner Website und möchte, dass er in den Bereich der Notch übergeht.
Aus irgendeinem seltsamen Grund beachtet Safari in iOS 16.0 den Wert #ffffff für theme-color nicht.
Wenn Sie zum Beispiel einen Header mit rotem Hintergrund haben, ersetzt Safari iOS die theme-color durch die gleiche Farbe wie das oberste Element, anstatt die in der Meta-Tag gesetzte zu verwenden.
Das liegt wahrscheinlich daran, dass es in Safari verbotene Farben gibt. Siehe: https://css-tricks.de/meta-theme-color-and-trickery/#aa-prohibited-colors
Tolle Übersicht, Manuel!
Gibt es eine gültige (konforme) Theme-Color-Methode in Sicht, die sowohl mit Licht- als auch mit Dunkelmodus funktioniert? Soweit ich weiß, gibt es keine Traktion für eine reine CSS-Lösung?
Update: Es scheint, dass das Konformitätsproblem ein Fehlalarm im HTML-Validator ist. Das macht die Unterstützung für Licht- und Dunkelmodus unter dem Gesichtspunkt der Wartbarkeit nicht attraktiv, aber zumindest ist es kein Fantasie-HTML.
Entschuldigung für die späte Antwort und danke für die Antwort. Das wusste ich nicht! :)