Guía de implementación de imágenes para modo oscuro - Cambio con el elemento picture y CSS

· 9 min de lectura

El modo oscuro y el problema de las imágenes - Por qué hay que adaptar las imágenes

Con la difusión del modo oscuro, crece la necesidad de adaptar al modo oscuro no solo el texto y el color de fondo, sino también las imágenes. Si muestras tal cual en modo oscuro una imagen creada para el modo claro, surgen varios problemas.

Problemas que surgen:

  • Deslumbramiento: las imágenes con fondo blanco y las capturas de pantalla destacan dentro de una interfaz oscura y cansan la vista
  • Pérdida de contraste: los gráficos y diagramas diseñados pensando en el modo claro pierden visibilidad en modo oscuro
  • Incoherencia de marca: los colores de logotipos e iconos no armonizan con la paleta del modo oscuro
  • Problemas con imágenes transparentes: el texto y las líneas de un PNG transparente se confunden con el color de fondo del modo oscuro y dejan de verse

No es necesario adaptar todas las imágenes al modo oscuro. En muchos casos las fotos y las ilustraciones pueden quedarse como están, pero conviene plantearse la adaptación de las imágenes de las siguientes categorías.

  • Logotipos / iconos (sobre todo los de un solo color)
  • Capturas de pantalla (capturas de la interfaz)
  • Diagramas / diagramas de flujo / gráficos
  • Ilustraciones pensadas para un fondo blanco
  • Imágenes con fondo transparente cuyo color de primer plano se confunde con un fondo oscuro

El método de adaptación depende del tipo de imagen. En SVG es fácil cambiar el estilo de forma dinámica, pero las imágenes rasterizadas (JPEG, PNG, WebP) pueden requerir preparar una versión aparte.

Cambio de imagen con el elemento picture - Cómo lograrlo solo con HTML

Con el elemento <picture> de HTML y el atributo media, puedes servir imágenes distintas para el modo oscuro sin JavaScript. El origen de imagen adecuado se selecciona automáticamente según la evaluación de las media queries que hace el navegador.

Implementación básica:

<picture>
<source srcset="diagram-dark.png" media="(prefers-color-scheme: dark)">
<source srcset="diagram-light.png" media="(prefers-color-scheme: light)">
<img src="diagram-light.png" alt="Diagrama de arquitectura del sistema">
</picture>

La ventaja de este método es que no depende de CSS ni de JavaScript y se resuelve solo con HTML. El navegador descarga únicamente la imagen necesaria para mostrarla, así que no se transfieren imágenes innecesarias.

Combinación con imágenes responsivas:

<picture>
<source srcset="hero-dark-800.webp 800w, hero-dark-1600.webp 1600w" media="(prefers-color-scheme: dark)" type="image/webp">
<source srcset="hero-light-800.webp 800w, hero-light-1600.webp 1600w" media="(prefers-color-scheme: light)" type="image/webp">
<img src="hero-light-800.jpg" alt="Imagen principal" sizes="100vw">
</picture>

Si cambias a la vez el formato (WebP/AVIF) y el modo oscuro, aumenta el número de elementos <source>, pero el navegador solo descarga el primer origen que coincide, así que no hay impacto en el rendimiento.

Advertencia: prefers-color-scheme consulta la configuración del sistema. No sirve para un interruptor de modo oscuro propio del sitio (el sistema que cambia el modo con JavaScript). Para admitir un interruptor propio del sitio, necesitas un cambio mediante variables CSS o JavaScript.

Adaptación de imágenes al modo oscuro con CSS - Uso de filtros y variables

Con CSS puedes adaptar el mismo archivo de imagen al modo oscuro. Como no hace falta preparar una versión aparte de la imagen, es un método con un costo de mantenimiento bajo.

Ajuste de brillo / contraste con filtros CSS:

@media (prefers-color-scheme: dark) {
.screenshot { filter: brightness(0.8) contrast(1.1); }
.diagram { filter: invert(1) hue-rotate(180deg); }
}

La combinación invert(1) hue-rotate(180deg) es una técnica que invierte los colores de la imagen y a la vez gira el tono 180 grados, de modo que invierte la luminosidad manteniendo el matiz de los colores. Es eficaz en diagramas y gráficos, pero en fotos da un resultado poco natural, así que evita usarla con ellas.

Cambio de imágenes de fondo con variables CSS:

:root { --logo-url: url('/images/logo-light.svg'); }
@media (prefers-color-scheme: dark) {
:root { --logo-url: url('/images/logo-dark.svg'); }
}
.logo { background-image: var(--logo-url); }

Uso de mix-blend-mode: con mix-blend-mode: difference o mix-blend-mode: exclusion puedes ajustar automáticamente cómo se ve la imagen según el color de fondo. Sin embargo, el resultado puede ser difícil de prever, así que limita su uso a casos concretos.

Ajuste de opacity: en modo oscuro, bajar la opacidad de las imágenes al 80-90% mejora su armonía con el fondo oscuro. Es eficaz sobre todo en fotos e ilustraciones: reduce el deslumbramiento y el contenido sigue viéndose con suficiente claridad.

@media (prefers-color-scheme: dark) {
img:not(.no-dim) { opacity: 0.85; }
img:not(.no-dim):hover { opacity: 1; }
}

Adaptación de SVG al modo oscuro - Cambio dinámico de color con currentColor y variables CSS

SVG es el formato de imagen más adecuado para el modo oscuro. Como su estilo se puede cambiar de forma dinámica con CSS, un solo archivo sirve tanto para el modo claro como para el modo oscuro.

Uso de currentColor: si en fill o stroke de un SVG indicas currentColor, hereda la propiedad color del elemento padre.

<svg viewBox="0 0 24 24">
<path fill="currentColor" d="M12 2L2 7l10 5 10-5-10-5z"/>
</svg>

Si el color del texto ya está adaptado al modo oscuro con CSS, los iconos SVG lo siguen automáticamente. Funciona tanto con SVG en línea como con referencia a un archivo, pero el CSS no se aplica a un SVG externo cargado con la etiqueta <img>, así que úsalo como SVG en línea o como imagen de fondo de CSS.

SVG de varios colores con variables CSS:

<svg>
<rect fill="var(--svg-bg, #ffffff)" />
<text fill="var(--svg-text, #333333)">Label</text>
</svg>

:root { --svg-bg: #ffffff; --svg-text: #333333; }
@media (prefers-color-scheme: dark) {
:root { --svg-bg: #1a1a2e; --svg-text: #e0e0e0; }
}

prefers-color-scheme dentro de SVG: también es posible incrustar un elemento <style> dentro del archivo SVG y escribir en él la media query. Así el SVG resuelve por sí solo la adaptación al modo oscuro, sin depender de CSS externo. Esta técnica es especialmente eficaz en la versión SVG del favicon (favicon.svg).

Capturas de pantalla y diagramas en modo oscuro - Flujo de trabajo práctico

Las capturas de pantalla y los diagramas son la categoría que más trabajo exige al adaptarse al modo oscuro. Ordenamos qué partes se pueden automatizar y cuáles requieren trabajo manual, y construimos un flujo de trabajo eficiente.

Enfoques para las capturas de pantalla:

  • Enfoque A: preparar 2 versiones: tomar capturas de pantalla en modo claro y en modo oscuro y cambiarlas con el elemento <picture>. Es el de mayor calidad, pero cada actualización requiere el doble de trabajo
  • Enfoque B: adaptar con filtros CSS: aplicar filter: brightness(0.8) a la captura del modo claro. Es sencillo, pero solo la oscurece y no es una verdadera adaptación al modo oscuro
  • Enfoque C: integrar con esquinas redondeadas y sombra: aplicar border-radius y box-shadow a la captura para suavizar el borde con el fondo oscuro. No cambia el contenido, pero reduce la sensación visual de desajuste

Adaptación de diagramas / diagramas de flujo: si creas diagramas con herramientas como Mermaid, Draw.io o Figma, resulta eficiente definir de antemano un tema de colores para el modo oscuro. Mermaid puede generar diagramas para el modo oscuro mediante la configuración del tema.

Enfoque de automatización: con Playwright o Puppeteer puedes automatizar la toma de capturas de pantalla en modo oscuro. Puedes emular el modo oscuro con page.emulateMediaFeatures y construir un script que genere automáticamente la versión clara y la oscura de la misma página. Si lo integras en una canalización de CI/CD, las dos versiones se generan automáticamente cada vez que se actualiza la documentación.

Consideraciones de rendimiento y accesibilidad

Al implementar imágenes para modo oscuro, hay que tener en cuenta tanto el rendimiento como la accesibilidad.

Optimización del rendimiento:

  • Evitar la carga de imágenes innecesarias: con el elemento <picture>, el navegador descarga únicamente la imagen necesaria para mostrarla. Si cambias la imagen con background-image de CSS, tampoco se descargan las imágenes del modo que no se usa
  • Gestión del tamaño de las imágenes: si preparas versiones aparte para el modo oscuro, el uso de almacenamiento del servidor se duplica. Ten en cuenta el costo de almacenamiento de la CDN y selecciona con cuidado las imágenes que de verdad necesitan una versión aparte
  • Carga de GPU de los filtros CSS: la propiedad filter se procesa en la GPU, pero aplicarla a muchas imágenes puede aumentar el consumo de batería en dispositivos móviles

Garantizar la accesibilidad:

  • Mantener la relación de contraste: mantén también en modo oscuro una relación de contraste conforme al criterio WCAG AA (4,5:1). Hay que comprobar que, al bajar el brillo con filtros CSS, no haya empeorado la legibilidad de las imágenes que contienen texto
  • Coherencia del texto alt: aunque muestres imágenes distintas en modo claro y en modo oscuro, haz que el texto alt transmita el mismo contenido
  • Control de las animaciones: ten en cuenta también la media query prefers-reduced-motion y permite desactivar las transiciones al cambiar de modo

Cómo probar: en el panel Rendering de Chrome DevTools puedes emular prefers-color-scheme. Comprueba cómo se muestran todas las imágenes mientras cambias rápidamente entre el modo claro y el modo oscuro. También se recomienda ejecutar la auditoría de accesibilidad de Lighthouse en ambos modos.

Artículos relacionados

Guía de implementación de imágenes responsivas - Guía completa de srcset, sizes y el elemento picture

Guía completa de implementación de imágenes responsivas. Cubre el atributo srcset, el atributo sizes, la dirección artística con el elemento picture y la generación automatizada en el pipeline de construcción.

Comparación de formatos de imagen - Características y casos de uso de JPEG/PNG/WebP/AVIF/GIF/BMP

Comparación completa de las características, eficiencia de compresión y casos de uso de los principales formatos de imagen. Desde formatos tradicionales hasta la nueva generación, con una guía de selección óptima según el uso.

Guía completa de creación de favicon - ICO, SVG y PNG explicados

Aprende cómo funcionan los favicons, las características de los formatos ICO, SVG y PNG, soporte de modo oscuro y compatibilidad de navegadores para implementación moderna de favicon.

Fundamentos de SVG y uso práctico - De los conceptos vectoriales a la animación

Guía completa de SVG desde la estructura básica hasta aplicaciones prácticas. Aprende rutas, formas, texto, filtros, implementación de animaciones y técnicas de optimización.

Vectorial vs Rasterizado - Guía para elegir el formato de imagen correcto

Diferencias esenciales entre imágenes vectoriales y rasterizadas, sus características y mejores casos de uso. Incluye implementación en desarrollo web y métodos de conversión entre formatos.

Cómo crear mapas de imagen HTML y alternativas modernas - Guía de implementación de mapas clicables

Aprende a implementar mapas de imagen con los elementos map y area de HTML. Cubre los desafíos del diseño responsivo y alternativas modernas con SVG y CSS, con ejemplos de código prácticos.

Términos relacionados