concepto CSS vigente

var()

Custom properties

Función CSS que consume el valor de una custom property: var(--nombre) inyecta el valor donde se usa, y var(--nombre, fallback) provee un valor de respaldo si la propiedad no está definida en ese ámbito.

var() es la función CSS que consume el valor de una custom property y lo inyecta en el lugar donde aparece. Si --color-acento: #0d9488 está declarada en el ámbito del elemento, escribir color: var(--color-acento) es equivalente a escribir color: #0d9488 — con la diferencia de que si el valor de la variable cambia (por cascada, por herencia, por JavaScript), todas las declaraciones que usen var(--color-acento) se actualizan automáticamente sin tocar el CSS de los componentes.

La función acepta una sintaxis de dos formas: var(--nombre) y var(--nombre, fallback). La segunda forma provee un valor de respaldo que el navegador usa cuando la propiedad referenciada no está definida en el ámbito del elemento. El fallback puede ser cualquier valor CSS válido para esa propiedad — incluso otra llamada a var(), lo que permite cadenas de fallback. Esta combinación de consumo y respaldo hace que var() sea la pieza central del sistema de tokens de diseño en CSS moderno: los componentes siempre tienen un valor sensato aunque el tema no haya definido la variable.

Desde el punto de vista del parser de CSS, var() es una función de valor que puede aparecer en cualquier lugar donde se espere un valor en una declaración: background-color, width, padding, font-size, transform, etc. No puede aparecer como nombre de propiedad ni como parte de un selector. Cuando el navegador resuelve la declaración, sustituye textualmente var(--nombre) por el valor almacenado en la custom property, y recién entonces evalúa si el resultado es válido para esa propiedad concreta — lo que da lugar al gotcha de IACVT explicado más abajo.

color: var(--color, navy) el navegador evalúa ¿--color está definida en este ámbito? usa el valor de --color color: #0d9488 no usa el fallback color: navy sin fallback y sin definición → valor inicial o heredado de la propiedad

Cómo funciona

Sintaxis básica

/* forma simple: consume la custom property */
color: var(--color-texto);

/* con fallback: si --color-texto no está definida, usa #1e293b */
color: var(--color-texto, #1e293b);

/* el fallback puede ser cualquier valor válido para esa propiedad */
font-size: var(--tamanio-fuente, 1rem);
padding: var(--espacio-interno, 8px 16px);

Para consumir la variable, el navegador sigue estos pasos:

  1. Busca --color-texto en el ámbito del elemento (el elemento mismo y sus ancestros, por herencia).
  2. Si la encuentra, sustituye var(--color-texto) por su valor y evalúa si el resultado es válido para la propiedad destino.
  3. Si no la encuentra y hay un fallback, usa el fallback.
  4. Si no la encuentra y no hay fallback, la declaración se trata como si tuviera el valor initial o el heredado de la propiedad.

Cadena de fallback

El fallback puede ser otra llamada a var(), lo que crea una cadena de resolución:

/* prueba --color-acento; si no existe, prueba --color-base; si tampoco, usa gray */
color: var(--color-acento, var(--color-base, gray));

El navegador evalúa de adentro hacia afuera: primero --color-acento, luego --color-base, por último gray. Esta cadena se usa en sistemas de tokens donde los componentes tienen variables específicas que caen sobre variables globales.

El gotcha del fallback — sólo actúa si la propiedad no está definida

El error más común al empezar con var() es pensar que el fallback protege contra valores inválidos. No lo hace. El fallback sólo se usa cuando la custom property no está definida en el ámbito del elemento. Si la propiedad está definida pero su valor es inválido para la propiedad destino, el fallback se ignora — entra en juego el comportamiento IACVT.

:root {
  --ancho: "esto no es un número"; /* valor definido, pero inválido para width */
}

.elemento {
  /* el fallback 200px NO se usa: --ancho está definida */
  /* en cambio, la propiedad toma el valor inicial de width */
  width: var(--ancho, 200px);
}

IACVT — “Invalid at Computed-Value Time”

Cuando var() resuelve a un valor que es inválido para la propiedad que lo contiene, se produce lo que la especificación llama “invalid at computed-value time” (IACVT). La declaración no usa el fallback: en cambio, la propiedad toma el valor inicial si no se hereda (por ejemplo width: auto), o el valor heredado del padre si la propiedad se hereda (como color).

:root {
  --color-error: 42px; /* válido como custom property, inválido como color */
}

p {
  /* IACVT: "42px" no es un color válido */
  /* color toma el valor heredado del padre, no el fallback */
  color: var(--color-error, black);
}

Esto es diferente de un error de sintaxis normal en CSS, donde el navegador puede ignorar sólo la declaración inválida y mantener la anterior. Con IACVT, la declaración “existe” pero resuelve a algo inútil para esa propiedad.

var() sólo va en el valor, no en el nombre de propiedad

var() inyecta un valor, no puede construir el nombre de una propiedad ni un selector:

/* ❌ inválido: var() no puede ser el nombre de la propiedad */
var(--mi-propiedad): 10px;

/* ✅ correcto: var() en el valor */
width: var(--mi-ancho);

Ejemplo realista

Un sistema de botones donde todos los estilos se definen en variables y se puede cambiar el tema del botón redefiniendo las variables en una clase modificadora:

:root {
  --btn-fondo: #1d4ed8;
  --btn-texto: #ffffff;
  --btn-radio: 4px;
  --btn-padding: 0.5rem 1rem;
}

.boton-peligro {
  --btn-fondo: #dc2626;
}

.boton-exito {
  --btn-fondo: #16a34a;
}

button {
  background-color: var(--btn-fondo);
  color: var(--btn-texto);
  border-radius: var(--btn-radio);
  padding: var(--btn-padding);
  border: none;
}

Notas, gotchas e interacción

  • El fallback sólo cubre el caso “propiedad no definida”, no “valor inválido”. Ver el gotcha IACVT arriba. Si necesitás protección contra valores inválidos, tenés que validarlos vos mismo o usar @property con tipos.
  • var() dentro de calc() es un patrón muy frecuente: font-size: calc(var(--ratio) * 1rem). El valor de la variable se inyecta textualmente antes de que calc() evalúe la expresión. Ver calc().
  • El valor almacenado puede tener espacios y comas: --sombra: 0 2px 8px rgba(0,0,0,.2) es válido; box-shadow: var(--sombra) lo inyecta completo.
  • var() no se puede usar en media queries: @media (max-width: var(--breakpoint)) no funciona. Las custom properties sólo resuelven dentro de reglas de estilo. Para esto existen las Container Queries con @container o se controlan desde JavaScript.
  • Interacción con herencia: si --color se hereda de un ancestro, var(--color) lo encuentra aunque no esté declarada en el propio elemento. Si el ancestro la redefine, el descendiente ve el valor redefinido. Ver Herencia CSS.
  • Diagnóstico en DevTools: en la pestaña Computed de Chrome/Firefox, las custom properties aparecen en la sección de propiedades. Podés ver el valor resuelto de cada variable para un elemento específico.

Vigente / legacy

var() está vigente y con soporte Baseline widely — es la única forma estándar de consumir custom properties. IE11 no soporta var() ni custom properties: en ese entorno, las declaraciones que las usen se ignoran silenciosamente. Si necesitás soportar IE11, el patrón habitual es declarar un valor hardcodeado previo como fallback de CSS (no el fallback de var()):

/* IE11 ignora la segunda línea y usa el valor hardcodeado */
color: #0d9488;
color: var(--color-acento);