Actualizado 15 de julio de 2026

Design tokens vs variables CSS: ¿cuál es la diferencia?

Dos archivos abiertos lado a lado. tokens.json dice "brand-600": { "$value": "#2563eb", "$type": "color" }; variables.css dice --color-brand-600: #2563eb;. El mismo valor, casi el mismo nombre — y la pregunta natural es cuál de los dos se supone que debes escribir.

La respuesta: no son competidores, son fuente y salida. Los design tokens son la fuente — decisiones de diseño guardadas en un archivo neutral respecto a herramientas. Las propiedades personalizadas de CSS son una exportación — las mismas decisiones renderizadas para los navegadores. Una analogía útil viene de los compiladores, y es una analogía: el archivo de tokens es código fuente, la hoja de estilos es un objetivo de compilación, y las Figma Variables o los recursos nativos son objetivos hermanos generados a partir de la misma fuente. La distinción suena académica y no lo es; decide qué puede consumir tus decisiones, qué herramientas pueden comprobarlas y quién revisa qué. El lado de la fuente lo cubrimos a lo largo de nuestra guía de design tokens — este artículo trata de la frontera en sí.

¿A qué pueden llegar los tokens que las variables CSS no?

A lo que no son navegadores. Una propiedad personalizada es una característica de CSS: llega a todo lo que alcanza una hoja de estilos y nada más. Las decisiones de un producto llegan más lejos — el mismo azul y el mismo espaciado tienen que mantenerse en el archivo de Figma, en las apps de iOS y Android, en las plantillas de correo, en la presentación de diapositivas que exporta el equipo de ventas. Si variables.css es la fuente de verdad, cada uno de esos consumidores se alimenta por transcripción manual, y las copias hechas a mano derivan.

Un archivo de tokens los alimenta a todos como vistas generadas: propiedades personalizadas para la web, Figma Variables para el diseño, recursos de plataforma para el nativo. El día en que aparece un segundo consumidor es el día en que la diferencia deja de ser teórica — con un solo consumidor los dos enfoques son casi indistinguibles; con dos, solo uno de ellos tiene una fuente.

¿Qué sabe un archivo de tokens que una hoja de estilos no?

Significado. Para CSS, --brand-600 es un valor sin tipo que se sustituye allí donde se usa; nada en el lenguaje sabe que es un color, y una errata dentro falla en silencio en el momento de usarlo. Un archivo de tokens sabe más: $type dice que el valor es un color, $description dice para qué sirve, y una referencia registra que accent está definido como {color.brand.600} en lugar de ser igual a él por casualidad.

Ese conocimiento es lo que hace funcionar a las herramientas. Una compilación puede validar el archivo — rechazar un color mal formado o una referencia a un token que no existe — antes de que nada se publique. La documentación se puede generar en lugar de escribir. Las transformaciones se pueden aplicar mecánicamente: px a rem, hex a OKLCH, una sola fuente renderizada según las convenciones de cada objetivo. Nada de esto está disponible para una hoja de estilos pelada, porque la hoja de estilos guarda respuestas sin sus preguntas.

¿Cómo se convierte un token en una variable CSS?

Mecánicamente. Tres tokens como fuente DTCG:

{
  "color": {
    "brand": { "600": { "$value": "#2563eb", "$type": "color" } }
  },
  "spacing": {
    "4": { "$value": "23px", "$type": "dimension" }
  },
  "semantic": {
    "accent": { "$value": "{color.brand.600}", "$type": "color" }
  }
}

Y el bloque :root generado a partir de ellos:

:root {
  --color-brand-600: #2563eb;  /* oklch(0.546 0.215 262.9) */
  --spacing-4: 23px;
  --color-accent: var(--color-brand-600);
}

Los nombres se convierten en nombres de propiedad, los valores se trasladan y — el detalle que vale la pena notar — la referencia sobrevive como var(): la exportación preserva la estructura de la decisión, no solo su respuesta actual. Los componentes consumen entonces la salida con normalidad:

.card {
  padding: var(--spacing-4);
  background: var(--color-accent);
}

Mira la fuente y las exportaciones lado a lado en Scale Composer — el archivo DTCG en un lado y los mismos nombres renderizados como propiedades personalizadas de CSS, un tema de Tailwind v4 y Figma Variables en el otro; edita la fuente y las tres salidas se mueven juntas.

Scale Composer mostrando una fuente de tokens DTCG junto a sus exportaciones generadas: propiedades personalizadas de CSS, tema de Tailwind v4 y Figma Variables que llevan los mismos nombres

¿Tienen los tokens y las variables ciclos de vida distintos?

Sí, y la diferencia se nota en la revisión de código. Los tokens son decisiones de diseño: se proponen, se revisan, se versionan y se comparan en diffs — un pull request que cambia accent de un primitivo a otro es un cambio de diseño con forma de diff revisable, y tanto diseñadores como desarrolladores tienen legitimidad para comentar. El variables.css generado es detalle de implementación: un artefacto de compilación que se regenera, no se edita. Editar a mano una hoja de estilos generada tiene la misma vida útil que editar a mano cualquier salida compilada — hasta la siguiente compilación.

La regla práctica que se desprende: revisa la fuente, genera el objetivo, y no dejes entrar en la hoja de estilos ningún valor que no haya pasado por la fuente.

¿Cuándo bastan honestamente las variables CSS por sí solas?

Cuando hay un solo consumidor y puede que nunca haya más que uno. Un producto web de una sola plataforma sin handoff a Figma, mantenido por quienes lo escribieron, pierde poco declarando sus propiedades personalizadas directamente — el archivo es más simple, la cadena de herramientas más corta, y un bloque :root disciplinado con propiedades nombradas por rol captura buena parte del beneficio de los nombres sin ninguna infraestructura de tokens. Esa es una elección legítima, no una inferior.

La capa de tokens justifica su coste cuando los consumidores se multiplican: la primera biblioteca de Figma que debe coincidir con el código, la primera superficie nativa, el primer segundo tema. Adoptar la maquinaria antes de eso es pagar por un alcance que aún no usas — razonable como preparación, pero no obligatorio.

¿Qué añaden las variables CSS en tiempo de ejecución?

Una cosa que los tokens por sí solos no pueden: la re-resolución en vivo en el navegador. Las propiedades personalizadas se resuelven a través de la cascada — la mecánica está documentada en la guía de MDN sobre propiedades personalizadas de CSS — así que redeclararlas bajo un ámbito cambia todos los consumidores a la vez, sin recompilar nada:

[data-theme="dark"] {
  --color-accent: oklch(0.70 0.14 262.9);  /* valor oscuro re-derivado */
}

Cada var(--color-accent) de la página se vuelve a resolver en el momento en que el atributo aparece. Esto es una propiedad del formato de salida, no de la fuente — una razón por la que la exportación a CSS es el objetivo correcto incluso cuando los tokens son la fuente, y el mecanismo sobre el que se construyen los sistemas de temas. Qué valores debe tener el tema oscuro es un tema aparte; aquí basta con que el cambio cueste un solo bloque de declaración.

Genera tus variables a partir de una fuente

La frontera se ve más clara cuando la cruzas a propósito. Exporta propiedades personalizadas de CSS a partir de una fuente de tokens — cambia una decisión en el lado de la fuente (un color semilla, un paso de la escala), vuelve a exportar y lee el diff en el lado del CSS: las variables se actualizan, la estructura de referencia se mantiene, y nada necesitó edición a mano.

Seguir leyendo

  • ¿Qué son los design tokens?

    ¿Qué son los design tokens? Decisiones de diseño con nombre —brand-600 contiene un azul exacto— compuestas mediante referencias y exportadas a CSS, Figma y código nativo.

  • El formato de tokens DTCG explicado

    El formato DTCG explicado: $value y $type en cada token, grupos, referencias y tipos compuestos, además de lo que contiene un archivo de design tokens generado de verdad.