CSS Custom Properties

Variables de CSS

Las propiedades personalizadas son valores que defines una vez y reutilizas en cualquier lugar. A diferencia de las variables de los preprocesadores, viven en el navegador y pueden cambiar en tiempo de ejecución.

intermediate13 min readUpdated 15 sept 2026
theme.css
css
/* theme.css */
:root {
  --color-bg: #ffffff;
  --color-text: #0f172a;
  --space: 1rem;
}

[data-theme="dark"] {
  --color-bg: #0b0d0c;
  --color-text: #e5e7eb;
}

body {
  background: var(--color-bg);
  color: var(--color-text);
  padding: var(--space);
}
Sintaxis
--name: value
Lectura con
var(--name)
Alcance
Cascada y herencia
Runtime
Modificable con JS
Fallback
var(--x, red)
Tipado
@property

Por que importa

Por qué importan las propiedades personalizadas

Una única fuente de verdad

Define un color, espacio o radio una sola vez y referéncialo en todas partes, para que los cambios ocurran en un único lugar.

Cambios en tiempo de ejecución

Las propiedades personalizadas viven en el DOM, por lo que JavaScript, las media queries y los atributos de datos pueden cambiarlas en vivo.

Tematización simplificada

Intercambia un conjunto de variables en la raíz o en un componente y todo el subárbol cambiará de tema instantáneamente.

La imagen completa

Las tres ideas detrás de las propiedades personalizadas

Declara un valor, léelo con var() y deja que la cascada decida qué declaración se aplica.

Declarar

Definir

Un nombre de propiedad que comienza con -- almacena cualquier valor que quieras reutilizar.

Usar

Referenciar

var() lee el valor, con un fallback opcional si este no está definido.

Cascada

Resolver

La declaración más cercana gana, que es lo que hace que el alcance y la tematización funcionen.

Variables de CSS de un vistazo

El núcleo de las propiedades personalizadas

Declaración

--name: value, usualmente en :root para tokens globales.

var()

Lee una propiedad personalizada, opcionalmente con un valor de respaldo (fallback).

Herencia

Las propiedades personalizadas se heredan, por lo que los hijos ven los valores de sus padres.

Tematización

Sobrescribe variables en un selector para cambiar todo un subárbol.

Valores dinámicos

Establécelos desde JavaScript con style.setProperty.

@property

Registra una propiedad con un tipo para animación y validación.

Una breve historia

De los preprocesadores al CSS nativo

  1. 2007

    Variables de Sass

    Los preprocesadores popularizan los valores reutilizables, resueltos en tiempo de compilación.

    07
  2. 2012

    Propuesta de variables CSS

    Se diseña un equivalente nativo y de tiempo de ejecución para CSS.

    12
  3. 2016

    Soporte de navegadores

    Las propiedades personalizadas llegan a todos los navegadores principales.

    16
  4. 2020

    Design tokens

    Los sistemas de diseño adoptan las propiedades personalizadas como la capa de tokens.

    20
  5. 2024

    Propiedades tipadas

    @property permite animaciones fluidas y la validación de propiedades personalizadas.

    24

La guia completa

Variables de CSS: Todo lo que necesitas saber

¿Qué son las variables de CSS?

Las variables de CSS, llamadas correctamente custom properties, son valores que defines una sola vez y haces referencia a ellos en cualquier lugar. Se parecen a las propiedades ordinarias pero comienzan con --, y se leen mediante la función var().

/* tokens.css */
:root {
  --color-brand: #2563eb;
  --radius: 0.5rem;
  --space-4: 1rem;
}

.button {
  background: var(--color-brand);
  border-radius: var(--radius);
  padding: var(--space-4) calc(var(--space-4) * 1.5);
}

La diferencia clave con una variable de preprocesador es que las custom properties son parte de la cascada del navegador. Se heredan, pueden tener un alcance (scope) definido y pueden cambiar en tiempo de ejecución. Esto las convierte en la capa natural para implementar temas (theming) y design tokens.

Declaración y uso

Declara una propiedad personalizada con un nombre que comience con dos guiones y cualquier valor válido.

/* declare.css */
:root {
  --gap: 1.5rem;
  --shadow: 0 1px 2px rgb(0 0 0 / 0.08);
  --font-sans: "Inter", system-ui, sans-serif;
}

.card {
  gap: var(--gap);
  box-shadow: var(--shadow);
  font-family: var(--font-sans);
}

Los valores pueden ser casi cualquier cosa: colores, longitudes, sombras, pilas de fuentes, degradados o incluso fragmentos de un valor. Debido a que se sustituyen antes de que la propiedad sea analizada, pueden combinarse con calc().

La cascada y la herencia

Las propiedades personalizadas siguen las reglas normales de CSS. Una declaración en un elemento es heredada por sus descendientes, y prevalece la declaración más cercana.

/* scope.css */
:root {
  --accent: #2563eb;
}

.sidebar {
  --accent: #f97316;
}

.sidebar a {
  color: var(--accent); /* orange inside the sidebar */
}

Esto es lo que hace que el alcance (scoping) sea tan potente: puedes cambiar el tema de un componente o de una sección sin tocar los tokens globales. También es la razón por la cual definir tokens en :root hace que estén disponibles en todas partes.

Fallbacks

var() acepta un fallback como segundo argumento, el cual se utiliza cuando la propiedad no existe o no es válida.

/* fallback.css */
.button {
  color: var(--button-color, #ffffff);
  background: var(--button-bg, var(--color-brand, #2563eb));
}

Los fallbacks son útiles para componentes reutilizables que deben funcionar incluso cuando los tokens no están definidos, y pueden anidarse. No obstante, utilízalos con moderación; si un token siempre debería existir, es mejor definirlo claramente en lugar de ocultar el problema.

Tematización

La tematización es el caso de uso estrella. Cambia un conjunto de variables y todo un subárbol se actualiza.

/* theme.css */
:root {
  --bg: #ffffff;
  --surface: #f8fafc;
  --text: #0f172a;
  --border: #e2e8f0;
}

[data-theme="dark"] {
  --bg: #0b0d0c;
  --surface: #14161a;
  --text: #e5e7eb;
  --border: #26292e;
}

body {
  background: var(--bg);
  color: var(--text);
}

.card {
  background: var(--surface);
  border: 1px solid var(--border);
}

Activa un atributo data-theme en el elemento raíz y toda la página cambia de tema instantáneamente, sin reglas duplicadas. También puedes limitar un tema a un componente, permitiendo que una tarjeta oscura esté dentro de una página clara.

Valores dinámicos con JavaScript

Debido a que las propiedades personalizadas residen en el DOM, puedes leerlas y escribirlas desde JavaScript.

// progress.js
const bar = document.querySelector(".progress");

function setProgress(percent) {
  bar.style.setProperty("--progress", `${percent}%`);
}

setProgress(72);
/* progress.css */
.progress__fill {
  width: var(--progress, 0%);
}

Así es como se suelen construir las barras de progreso, las interacciones de arrastre, los efectos de seguimiento del cursor y los selectores de tema. El valor permanece en CSS y JavaScript solo actualiza un número.

Propiedades tipadas con @property

Por defecto, las propiedades personalizadas son cadenas de texto sin tipo, por lo que el navegador no puede interpolarlas. La regla-at @property registra un tipo, un valor inicial y un comportamiento de herencia.

/* property.css */
@property --angle {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}

.spinner {
  background: conic-gradient(from var(--angle), #2563eb, transparent);
  animation: rotate 1s linear infinite;
}

@keyframes rotate {
  to { --angle: 360deg; }
}

Con un tipo registrado, la propiedad se vuelve animable y el navegador valida el valor, lo que evita toda una categoría de errores.

Mejores prácticas

  • Define tokens globales en :root y utilízalos en todas partes.
  • Nombra los tokens según su propósito (--color-text) y no según su apariencia (--gray-900).
  • Sobrescribe variables para temas y variantes de componentes en lugar de duplicar reglas.
  • Proporciona fallbacks para componentes reutilizables que puedan ejecutarse sin tokens.
  • Actualiza las variables desde JavaScript en lugar de escribir estilos inline en todas partes.
  • Registra las propiedades animables con @property.
  • Mantén el conjunto de tokens pequeño y consistente.

Errores comunes

  • Esperar que las propiedades personalizadas se comporten como variables de Sass en tiempo de compilación.
  • Usar nombres ambiguos que dificulten el mantenimiento del conjunto de tokens.
  • Definir cada valor como una variable, perdiendo así la legibilidad.
  • Olvidar que los valores no tienen tipo a menos que se registren con @property.
  • Sobrescribir tokens de forma global cuando solo debería cambiar un subárbol.
  • Almacenar secretos o datos de usuario en variables CSS, ya que son visibles en el DOM.

Próximos pasos

Las propiedades personalizadas son el tejido conectivo de una hoja de estilos mantenible. Aplícalas al diseño con Diseño Responsivo, anima las propiedades tipadas con Animaciones y Transiciones y comprende la cascada que hay detrás de ellas en la guía de CSS. Para variables de tiempo de compilación que las complementen, consulta Sass.

Tematización

Sobrescribe un pequeño conjunto de variables para cambiar el tema de todo un subárbol. Duplicar reglas para cada tema es propenso a errores.

Preferir
:root {
  --bg: #fff;
  --fg: #0f172a;
}

[data-theme="dark"] {
  --bg: #0b0d0c;
  --fg: #e5e7eb;
}

.card {
  background: var(--bg);
  color: var(--fg);
}
Evitar
.card {
  background: #fff;
  color: #0f172a;
}

[data-theme="dark"] .card {
  background: #0b0d0c;
  color: #e5e7eb;
}

Valores que cambian en runtime

Las propiedades personalizadas están vivas en el DOM, por lo que JavaScript puede actualizarlas sin reescribir las hojas de estilo.

Preferir
// update a theme token
document.documentElement.style
  .setProperty("--progress", "72%");
Evitar
/* a preprocessor variable is
   fixed at build time and
   cannot change per user */

Preguntas frecuentes

Preguntas frecuentes

Keep learning

Related topics from the roadmap.

$ comienza a aprender

Listo para aprender CSS Variables?

Nuestro tutorial interactivo te guia a traves de CSS Variables paso a paso — con quizzes y codigo real que puedes ejecutar en el navegador.