Favicon SVG y media query para modo oscuro: guía paso a paso

Subes un logo perfecto, activas el modo oscuro de tu sistema operativo y abres tu sitio... solo para ver cómo tu marca naranja brillante te devuelve la mirada desde una barra de pestañas oscura. Un favicon PNG plano no puede detectar el tema de tu sistema. Pero un favicon SVG con una media query prefers-color-scheme integrada sí puede.

Esta guía se centra en una técnica concreta: incrustar una media query de CSS directamente dentro de tu archivo .svg para que un único fichero cambie de colores automáticamente. Es un camino distinto al de intercambiar dos etiquetas <link> en HTML, y es el más limpio para la mayoría de los sitios.

Requisitos previos

Antes de empezar, necesitas tres cosas:

Si todavía no tienes un SVG, exporta uno desde tu herramienta de diseño o usa Mzu favicondl para extraer un vector limpio a partir de cualquier imagen.

Paso a paso: añade una media query dentro de tu favicon SVG

Paso 1: abre tu archivo SVG en un editor de texto

SVG no es más que XML. Haz clic derecho sobre cualquier archivo .svg y elige Abrir con → TextEdit o VS Code. Verás algo como:

<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'>
  <rect width='64' height='64' rx='12' fill='#ff7a00'/>
  <path d='M20 22 L32 44 L44 22' stroke='#fff' stroke-width='6' fill='none'/>
</svg>

Paso 2: añade un bloque <style> con la media query

Inserta un elemento <style> justo después de la etiqueta <svg> de apertura. Dentro, define los colores del tema claro y sobreescríbelos para el modo oscuro usando prefers-color-scheme: dark:

<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'>
  <style>
    .bg { fill: #ff7a00; }
    .stroke { stroke: #ffffff; }
    @media (prefers-color-scheme: dark) {
      .bg { fill: #1a1a1a; }
      .stroke { stroke: #ffb347; }
    }
  </style>
  <rect class='bg' width='64' height='64' rx='12'/>
  <path class='stroke' d='M20 22 L32 44 L44 22' stroke-width='6' fill='none'/>
</svg>

El navegador reevalúa prefers-color-scheme cada vez que cambia el tema de tu sistema operativo. Tu favicon se actualiza sin recargar la página en la mayoría de navegadores modernos.

Paso 3: enlázalo en el <head> de tu HTML

Según el HTML living standard de WHATWG, el tipo de link rel='icon' admite SVG cuando declaras el MIME type correcto con type='image/svg+xml':

<link rel='icon' href='/favicon.svg' type='image/svg+xml'>

Colócalo por encima de cualquier fallback PNG o ICO. Consulta nuestro cheat sheet de favicon en HTML para ver el stack moderno completo, incluidas las entradas de Apple Touch y web manifest.

Paso 4: ofrece un fallback raster

No todos los navegadores procesan CSS dentro de los favicons, sobre todo versiones antiguas de Safari y algunas vistas web embebidas. Sirve un PNG de 32×32 (o un ICO multitaría) para esos clientes:

<link rel='icon' href='/favicon.svg' type='image/svg+xml'>
<link rel='icon' href='/favicon.ico' sizes='32x32'>

Los navegadores usan la primera coincidencia, así que SVG gana donde tenga soporte.

Paso 5: prueba ambos esquemas de color

Fuerza una recarga completa (Ctrl/Cmd + Shift + R) y cambia el tema de tu sistema operativo. En Chrome, Edge y Firefox el icono de la pestaña debería cambiar en vivo. Si no ocurre nada, pasa a la sección de errores comunes.

Errores comunes

Error 1: olvidar el viewBox

Sin un viewBox, el SVG se renderiza a su tamaño intrínseco, que puede ser enorme o cero. Declara siempre uno: viewBox='0 0 64 64'.

Error 2: los atributos fill inline ganan a tu CSS

Si tus formas ya llevan fill='#ff7a00' como atributo, tu clase CSS perderá la batalla de especificidad. Mueve el color a una clase, o elimina el atributo inline por completo.

Error 3: caché de favicon demasiado agresiva

Los navegadores cachean los favicons más que casi cualquier otro archivo. Tras editar tu SVG, añade un query string durante las pruebas: /favicon.svg?v=2. Nuestra guía de cache busting cubre estrategias para producción.

Error 4: las pestañas ancladas de Safari ignoran las media queries

La función de pestaña anclada de Safari usa un safari-pinned-tab.svg monocromo aparte. Las media queries dentro de ese archivo no surten efecto. Diseñalo como una silueta de un solo color y omite el bloque <style>.

Error 5: el modo oscuro no es 'invertir los colores'

Elige una paleta para modo oscuro con contraste real frente al fondo real de la pestaña del navegador (a menudo #2b2a33 en Chrome, casi negro en Safari). Pasar tu icono por un comprobador de contraste una vez te ahorrará tickets de soporte más adelante.

Conclusión

El enfoque con media query dentro del SVG te da una única fuente de verdad: un archivo, dos temas, cero JavaScript. Es el valor por defecto correcto para cualquier sitio moderno que ya tenga un logo SVG, y funciona junto a —no en contra de— los fallbacks PNG e ICO que deberías seguir sirviendo para navegadores antiguos.

Consulta los requisitos documentados

El HTML Standard define rel='icon' como la relación de link para un icono que representa la página actual.