Implementa temas claro/oscuro con variables CSS sin usar librerías

Vibrant multicolored source code displayed on a computer screen, depicting programming and web development concepts.
Foto de Markus Spiske en Pexels

En los últimos años el dark mode se ha convertido en una expectativa casi obligada para cualquier aplicación web. Lo mejor es que no necesitas librerías pesadas ni frameworks para implementarlo: con CSS variables y un pequeño fragmento de JavaScript puedes lograr un cambio de tema fluido y mantenible.

¿Por qué usar variables CSS?

Las variables, o custom properties, permiten definir valores reutilizables que pueden ser sobrescritos en cualquier nivel del árbol DOM. Esto las hace perfectas para gestionar colores, fuentes o cualquier propiedad que varíe entre un tema claro y uno oscuro.

Estructura básica de los temas

Primero definimos los valores por defecto (el tema claro) en :root. Después, creamos una regla que sobrescriba esas variables cuando el atributo data-theme del html tenga el valor dark.

:root {
  --bg-color: #ffffff;
  --text-color: #222222;
  --link-color: #0066cc;
}

[data-theme="dark"] {
  --bg-color: #111111;
  --text-color: #e0e0e0;
  --link-color: #66aaff;
}

Con esas variables definidas, el resto del CSS simplemente hace referencia a ellas:

body {
  background-color: var(--bg-color);
  color: var(--text-color);
  font-family: system-ui, sans-serif;
}

a {
  color: var(--link-color);
}

El pequeño script que cambia el tema

El único JavaScript necesario es el que modifica el atributo data-theme del elemento raíz. Puedes guardarlo en localStorage para que la preferencia persista entre visitas.

function toggleTheme() {
  const root = document.documentElement;
  const current = root.dataset.theme === 'dark' ? 'light' : 'dark';
  root.dataset.theme = current;
  localStorage.setItem('theme', current);
}

function initTheme() {
  const saved = localStorage.getItem('theme');
  if (saved) {
    document.documentElement.dataset.theme = saved;
  }
}

document.addEventListener('DOMContentLoaded', initTheme);
document.getElementById('theme-switch').addEventListener('click', toggleTheme);

En el HTML sólo necesitas un botón que invoque la función:

<button id="theme-switch">Cambiar tema</button>

Mejoras y buenas prácticas

  • Preferencia del sistema: usa window.matchMedia('(prefers-color-scheme: dark)') para detectar la elección del usuario y aplicarla automáticamente.
  • Transiciones suaves: añade una transición a background-color y color para que el cambio no sea brusco.
    body {
      transition: background-color 0.3s ease, color 0.3s ease;
    }
  • Variables estructurales: además de colores, puedes definir variables para sombras, bordes o incluso tamaños que varíen entre temas.

Conclusión

Con apenas unas líneas de CSS y JavaScript tienes un sistema de temas claro/oscuro totalmente independiente de librerías externas. La clave está en centralizar los valores en variables y cambiar sólo una pequeña pieza del DOM. De esta forma tu código permanece limpio, fácil de mantener y, lo más importante, rápido para el usuario.