01

Separar valores de funciones semánticas

Un token primitivo nombra un valor seleccionado o una posición de escala, por ejemplo --color-indigo-600. Un token semántico nombra una función de interfaz, por ejemplo --color-action. La asignación del token semántico al primitivo crea una única indirección controlada. Los componentes usan --color-action y no necesitan saber si el tema actual lo relaciona con índigo, azul u otro color revisado. La separación aclara auditorías: se revisan procedencia y conversiones en los primitivos, y contraste y significado de estados en las parejas semánticas. No expongas cada valor de paleta sin un uso concreto.

Semántico no significa un término subjetivo de marketing. Prefiere funciones verificables: surface, surface-raised, text, text-muted, border, focus-ring, action, on-action, danger y on-danger. Cada token de primer plano debe documentar los fondos admitidos. Un token light-gray no garantiza relaciones ni uso; text-muted puede disponer de un contrato que enumere superficies. No incluyas el tema actual en el nombre semántico. white-text o dark-surface dificultan un tema futuro y animan a los componentes a depender de la apariencia en vez del propósito.

02

Comprender cascada y herencia

Las propiedades personalizadas participan en la cascada y normalmente se heredan. Una declaración en :root queda disponible para descendientes, pero otra más cercana puede reemplazarla según las reglas normales. Los nombres distinguen mayúsculas, de modo que --color-text y --Color-text son propiedades diferentes. var() sustituye el valor calculado donde se utiliza. Esto facilita temas locales, pero genera dependencias ocultas si los componentes redefinen nombres globales sin control. Mantén el contrato global en una raíz o frontera temática documentada y usa prefijos propios para valores privados de componentes.

css
:root {
  --color-indigo-600: #4f46e5;
  --color-slate-950: #020617;
  --color-surface: #ffffff;
  --color-text: var(--color-slate-950);
  --color-action: var(--color-indigo-600);
}
03

Mantener pequeño el primer conjunto

Empieza por las funciones presentes en pantallas reales en lugar de generar cientos de niveles hipotéticos. Un producto pequeño suele necesitar dos o tres superficies, texto principal y atenuado, un borde, una pareja de acción, indicación de foco y pocas parejas de estado. Registra qué componentes consumen cada token. Si ninguno lo usa, quizá no pertenece al contrato inicial. Las rampas primitivas son útiles cuando sostienen decisiones semánticas reales. Un sistema reducido se prueba mejor en todos los temas y estados, y las adiciones pueden justificarse con evidencia en lugar de copiar una exportación arbitraria.

  • Parejas de superficie y texto utilizadas por diseños reales.
  • Colores action y on-action para controles con texto o iconos.
  • Borde y focus-ring con evidencia para cada estado.
  • Parejas de estado solo para estados que el producto comunica.
04

Nombrar por propósito y estado

Usa una jerarquía y vocabulario coherentes. Un patrón práctico es --color-<role> con modificadores de énfasis o estado, mientras los primitivos siguen --color-<hue>-<step>. La convención exacta importa menos que evitar primary, brand, accent y action como sinónimos del mismo trabajo. Crea tokens hover, active, disabled, focus o selected solo si el estado tiene un valor distinto demostrado. Una tabla que conecte token, fondo permitido, responsable y resultado de contraste aporta más que una cuadrícula visual. Mantén estable el nombre cuando solo cambie el valor subyacente.

CapaEjemploResponsabilidad
Primitiva--color-indigo-600Registrar un valor elegido
Semántica--color-actionDescribir una función de interfaz
Componente--button-backgroundAdaptar una función en un componente
Estado--color-action-hoverDescribir un estado demostrado
05

Preparar fallbacks y temas deliberados

El segundo argumento de var() es un fallback usado si la propiedad referenciada falta o es inválida durante la sustitución. No es un fallback general de soporte del navegador, y una coma puede pertenecer al valor alternativo. Úsalo en fronteras donde un componente podría ejecutarse sin tema anfitrión; no repitas valores crudos por el producto porque destruyes el control central. Un tema debe cambiar asignaciones semánticas en una frontera limitada. Una consulta de medios puede elegir la preferencia predeterminada y una clase o atributo representa la elección explícita con precedencia documentada. Por eso el ejemplo reemplaza conjuntamente la superficie oscura y su texto: forma una pareja explícita en vez de dejar texto oscuro sobre un fondo oscuro.

css
.button {
  color: var(--color-on-action, #ffffff);
  background: var(--color-action, #4f46e5);
  border: 1px solid var(--color-border, #cbd5e1);
}

@media (prefers-color-scheme: dark) {
  :root {
    --color-surface: #0f172a;
    --color-text: #f8fafc;
  }
}
06

Probar combinaciones, no muestras aisladas

Un token de color no es accesible de manera aislada. Prueba las parejas admitidas de primer plano y fondo tras la composición alfa y cubre hover, focus, active, disabled, selected y validation. El foco no debe comunicarse solo con una variación mínima de color. Capturar cadenas de tokens no demuestra contraste; las pruebas necesitan valores resueltos y reglas reales de emparejamiento. Comprueba forced-colors sin combatir sustituciones útiles del agente de usuario. Documenta si un token es decorativo, contiene texto o representa un objeto gráfico, porque los requisitos de accesibilidad aplicables son distintos.

  • Comprueba herencia y reemplazos locales en componentes anidados.
  • Resuelve cada combinación admitida de primer plano y fondo.
  • Prueba preferencia, tema explícito y comportamiento forced-colors.
  • Audita tokens sin uso, duplicados y obsoletos antes de añadir más.
07

Evolucionar sin romper consumidores

Trata los cambios de tokens como cambios de API. Localiza consumidores, actualiza documentación y capturas, mide las parejas afectadas y ofrece alias o migración al renombrar un token público. Elimina alias obsoletos únicamente cuando todos hayan migrado. Guarda la fuente canónica bajo control de versiones y genera salidas para otras plataformas solo con un proceso determinista y probado. No dupliques en JavaScript la tabla temática si CSS puede controlarla. Un registro breve permite distinguir un ajuste visual de un cambio que rompe supuestos de componentes.

S

Fuentes primarias

Las afirmaciones de este artículo se comprueban con estas especificaciones publicadas.

  1. W3C CSS Custom Properties for Cascading Variables Level 1