
A partir de la versión 15, Safari admite la theme-color
<meta>
etiqueta tanto en macOS como en iOS. Esas son buenas noticias porque ahora el primer navegador de escritorio es compatible con este <meta>
etiqueta y también admite la media
atributo y el prefers-color-scheme
función multimedia.
Realmente nunca tomé mucha nota de la theme-color
metaetiqueta, pero ahora es un buen momento para conocer sus características y limitaciones y tratar de descubrir algunos casos de uso interesantes.
¡Aviso! Safari eliminó el soporte para theme-color
metaetiqueta en Safari Technology Preview (127). Eso fue solo temporal, comenzando con la versión 128, lo admite nuevamente.
Características y limitaciones
Así es como he estado usando el theme-color
metaetiqueta de los últimos años: solo un buen código hexadecimal para el content
atributo.
<meta name="theme-color" content="#319197">
Según las pruebas que hice a principios de este año, esto funciona en Chrome, Brave y Samsung Internet en Android, instalé PWA en Chrome y ahora también en Safari Technology Preview.
La compatibilidad con colores hexadecimales es excelente en todos los navegadores compatibles.
Soporte de color CSS
Una de las primeras preguntas que me vino a la mente fue “¿Podemos utilizar palabras clave de color, hsl()
, rgb()
, ¿también?” Según la especificación HTML, el valor del atributo puede ser cualquier color CSS. He creado esto theme-color
probando CodePen para verificar eso.
<meta name="theme-color" content="hsl(24.3, 97.4%, 54.3%)">
El
theme-color
Las metaetiquetas admiten colores CSS en cualquier forma: palabras clave, rgb()
, hsl()
o código hexadecimal.
Mirando Chrome 90 en un Android Galaxy S20
Todos los navegadores compatibles también admiten hsl()
y rgb()
. Esto es asombroso porque nos permite hacer cosas muy interesantes con JavaScript. Hablaremos de eso más tarde, pero primero veamos algunas limitaciones.
Transparencia
Códigos HEX, rbg()
, hsl()
y las palabras clave están bien y de forma consistente, pero los colores que incluyen transparencia: no tanto. En realidad, son compatibles con la mayoría de los navegadores, pero los resultados no son muy consistentes y, a veces, inesperados.
transparent
es un color CSS y se utiliza en el theme-color
metaetiqueta la mayoría de los navegadores hacen lo que cabría esperar. Todos los navegadores móviles normales no cambian de color y muestran la barra de pestañas predeterminada, pero Safari en macOS y Chrome Canary PWA en macOS hacen que la barra de pestañas sea negra. La PWA en Android se remonta a theme-color
definido en el manifest.json
, del que hablaremos en un momento.
Navegador con un transparente
theme-color
metaetiqueta
Todos los navegadores interpretan hsla()
y rgba()
, pero establecen el valor alfa en 1. La única excepción es Safari en macOS; interpreta la transparencia, pero parece que el color transparente tiene una línea de base negra. Esto tiene el efecto de que el color naranja claro parece naranja oscuro.
hsla()
aplicado a la theme-color
metaetiqueta
Nuevas funciones de color
Safari 15 es el primer navegador que admite lab()
, lch()
, y hwb()
funciones de color. Estas funciones funcionan si las usa en CSS, pero no si las usa en el theme-color
metaetiqueta.
Las tres declaraciones funcionan bien en Safari 15:
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);
}
Si usa alguna de las nuevas funciones de color en el theme-color
metaetiqueta, Safari no los interpreta y recurre a su propio algoritmo para elegir el color. Es probable que Safari use el color de fondo de tu <body>
Para el theme-color
, lo que significa que puede obtener el resultado esperado sin definir el theme-color
explícitamente.
<meta name="theme-color" content="lab(29.2345% 39.3825 20.0664)">
Tenga en cuenta que, en el momento de redactar este documento, Safari 15 es el único navegador que admite estas nuevas funciones de colores.
currentColor
Si se admiten colores CSS, currentColor
también debería funcionar, ¿verdad? No, lamentablemente no en ningún navegador. Probablemente sea un caso de uso poco común, pero esperaría que podamos configurar el theme-color
al color actual del <body>
o <html>
elemento.
<style>
body {
color: blue;
}
</style>
<meta name="theme-color" content="currentColor">
Encontré un ticket en el rastreador de errores de WebKit titulado “<meta name="theme-color" content="...">
también debería ser compatible con CSS currentcolor
. ” El soporte puede cambiar en el futuro, si alguien recoge el boleto.
Colores prohibidos
Cuando estaba probando palabras clave de color CSS, usé el color red
y no funcionó. Primero, pensé que las palabras clave no eran compatibles, pero blue
, hotpink
, y green
funcionó bien. Como resulta, hay un gama reducida de colores que Safari no admite, colores que obstaculizarían el uso de la interfaz. red
no funciona porque visualmente está demasiado cerca del color de fondo del botón de cierre en la barra de pestañas. Esta limitación es específica de Safari, en todos los demás navegadores compatibles cualquier color parece funcionar bien.
Si configura el
theme-color
a red
, Safari usa cualquier color que considere apropiado.
Propiedades personalizadas
No sé lo suficiente sobre los aspectos internos de los navegadores y las propiedades personalizadas y si es posible acceder a las propiedades personalizadas en el <head>
, pero lo intenté de todos modos. Desafortunadamente, no funcionó en ningún navegador.
<style>
:root {
--theme: blue;
}
</style>
<meta name="theme-color" content="var(--theme)">
Eso es prácticamente todo lo que quería saber sobre el soporte básico del theme-color
metaetiqueta. A continuación, veamos cómo y cómo no implementar el modo oscuro para la barra de pestañas.
Modo oscuro
Safari 15 es el primer navegador de escritorio compatible con media
atributo y el prefers-color-scheme
función multimedia en theme-color
metaetiquetas. A partir de la versión 93, Chrome también lo admite, pero solo para aplicaciones web progresivas instaladas.
Según la página de manifiesto de la aplicación web en web.dev, si define varios theme-color
metaetiquetas, los navegadores eligen la primera etiqueta que coincida.
<meta name="theme-color" content="#872e4e" media="(prefers-color-scheme: dark)">
Estaba ansioso por saber qué sucede en los navegadores que no son compatibles con media
atributo. Creé una página de demostración para probar el modo oscuro que incluye las metaetiquetas anteriores y también le permite instalar el sitio como PWA. El webmanifest.json
incluye otra definición de color para el color del tema.
{
"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%)"
}
Así es como los navegadores compatibles muestran la barra de pestañas en modo claro. No importa si un navegador admite el atributo de medios o no, interpretará la primera metaetiqueta independientemente.
Así es como se ve la barra de pestañas en la misma página en modo oscuro. Estos resultados son más interesantes porque varían un poco. Canary PWA y Safari son compatibles y muestran el color oscuro. Todos los navegadores móviles usan su estilo de barra de pestañas oscura predeterminado, excepto Samsung Internet, que usa el estilo claro porque no es compatible con prefers-color-scheme
función multimedia. (TIL: Esto debería cambio en el futuro cercano.)
Hice una última prueba. Quería ver qué sucede si solo defino un color de tema para el modo oscuro, pero accedo a la página en modo claro.
<meta name="theme-color" content="#872e4e" media="(prefers-color-scheme: dark)">
Estos resultados me sorprendieron más porque esperaba que todos los navegadores móviles ignoraran el atributo de medios y solo usaran el color oscuro en la metaetiqueta independientemente, pero Chrome Canary normal ignora por completo toda la metaetiqueta, a pesar de que no es compatible con el media
atributo. Como era de esperar, ambos PWA de Canary recurren al color definido en el archivo de manifiesto.
La otra cosa interesante es que Safari muestra un theme-color
aunque no he definido uno para el modo de luz. Eso es porque Safari elegirá un color por sí solo, si no proporciona un theme-color
. En este caso, usa el color de fondo de la página, pero también puede usar el color de fondo del <header>
elemento, por ejemplo.
Si desea definir un color de tema para el modo claro y oscuro, lo mejor que puede hacer es definir ambos colores y usar la primera metaetiqueta como alternativa para los navegadores que no admiten la función multimedia.
<meta name="theme-color" content="#319197" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#872e4e" media="(prefers-color-scheme: dark)">
Safari ha demostrado que theme-color
también funciona muy bien en navegadores de escritorio. Estoy seguro de que los diseñadores y desarrolladores encontrarán muchas formas creativas de usar esta metaetiqueta, especialmente considerando que el valor se puede cambiar a través de JavaScript. He recopilado y creado algunas demostraciones interesantes para su inspiración.
Demostraciones y casos de uso
Tematización
poolsuite.net proporciona diferentes temas para el sitio y cambia el color del tema en consecuencia.
Max Böck también cambia el theme-color
en su sitio web cuando cambia el tema.
Temas de página
La mayoría de los sitios web no ofrecen temas personalizados, pero aun así puedes darle a tus páginas algo. Dave usa diferentes colores clave en las publicaciones de su blog para obtener enlaces e íconos, y ahora también en la barra de pestañas.
Gradientes
Si está utilizando degradados en su página, puede resaltar su estilo haciendo que el degradado abarque todo el navegador. El theme-color
La metaetiqueta no admite degradados, pero puede usar el mismo color para la metaetiqueta y el color de inicio del degradado del fondo de su página.
<meta name="theme-color" content="rgb(0, 235, 255)">
<style>
body {
background: linear-gradient(rgb(0, 235, 255), #08124a);
}
</style>
Validación de formularios
Construí esta prueba de concepto de una forma que cambia theme-color
en la validación del formulario. Comienza con una barra de pestañas azul que se vuelve roja si los datos enviados no son válidos o verde si son válidos.
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)
});
Modo disco
No digo que debas, pero puedes poner tu sitio en 💃 Modo Disco 🕺 combinando setInterval
y hsl()
colores.
/*
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)
Desplazamiento
Stuart tuvo una gran idea, sugirió cambiar el color del tema en el desplazamiento. Construí este prototipo rápido, nuevamente usando hsl()
colores.
Solo haga esto si no afecta negativamente al rendimiento.
Max construyó una demostración en la que cambia el theme-color
según el color de fondo de la sección actual en la ventana gráfica utilizando Intersection Observer.
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)
})
}
Extrayendo color
Otra idea interesante es extraer el color dominante o medio de las imágenes de tu encabezado automáticamente y usarlo como theme-color
.
<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="https://css-tricks.com/amy-humphries-2M_sDJ_agvs-unsplash.jpg" alt="A sea star on blue sand." />
Eso es solo un puñado de ideas, pero ya me gusta a dónde va y estoy seguro de que se le ocurrirán formas aún más creativas de usar el theme-color
metaetiqueta.
Recursos
theme-color
especificación- Diseño para Safari 15
- Modo oscuro en Samsung Internet