Color y trucos del meta tema | Programar Plus

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%)">

Página web en blanco con encabezado naranja.El theme-color Las metaetiquetas admiten colores CSS en cualquier forma: palabras clave, rgb(), hsl() o código hexadecimal.
Página web en blanco con un encabezado de color rosa intenso.  Hay controles a la derecha de la página web para probar el navegador.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.

Ejemplos de la misma página web en blanco con encabezados blancos u oscuros con el proveedor del navegador etiquetado encima de cada uno.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.

Misma comparación de navegador pero todos con encabezados naranjas, excepto Safari, que es de un marrón más 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)">

Página web verde con encabezado verde.

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.

Página web de Wbite con un selector de color establecido en rojo.  El encabezado del navegador es blanco.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