Variables CSS: el motor de los sistemas de diseño modernos
Las variables SASS mueren en el momento de la compilación. Las variables CSS viven en el navegador. Una guía técnica sobre capas semánticas, temáticas dinámicas y aislamiento de componentes.
Durante una década, SASS fue el rey.
Definimos €brand-color: #ff0000;. Lo compilamos.
Pero las variables SASS tienen un defecto fatal: Mueren en el momento de la compilación.
Una vez que el CSS llega al navegador, la variable desaparece. Es sólo un código hexadecimal estático.
No puedes cambiarlo con JavaScript. No puede limitarlo a un nodo DOM específico.
Ingrese Propiedades personalizadas de CSS (variables).
--color-marca: #ff0000;.
Éstas no son sólo “variables”. Son propiedades del DOM. Caen en cascada. Están vivos.
En Maison Code Paris, los utilizamos como capa fundamental de cada sistema de diseño que construimos.
Por qué Maison Code habla de esto
En Maison Code Paris, actuamos como la conciencia arquitectónica de nuestros clientes. A menudo heredamos stacks “modernos” construidos sin una comprensión fundamental de la escala.
Discutimos este tema porque representa un punto de inflexión crítico en la madurez de la ingeniería. Implementarlo correctamente diferencia un MVP frágil de una plataforma resistente de nivel empresarial.
1. La estrategia de capas semánticas
Los principiantes asignan variables directamente a los colores.
--azul: #0000ff;
Los expertos asignan variables a Intención.
Utilizamos una arquitectura de 3 capas:
Capa 1: Primitivas (La Paleta)
Esta es tu caja de pintura en bruto. No tiene significado, sólo valores.
:raíz {
--paleta-azul-100: #ebf8ff;
--paleta-azul-500: #4299e1;
--paleta-azul-900: #2a4365;
--palette-neutral-900: #1a202c;
--paleta-blanca: #ffffff;
}
Capa 2: Semántica (El Token)
Esto asigna la paleta a un propósito específico.
:raíz {
--bg-primary: var(--paleta-blanco);
--bg-secundario: var(--palette-blue-100);
--text-body: var(--palette-neutral-900);
--acción-primaria: var(--palette-blue-500);
--action-primary-hover: var(--palette-blue-900);
}
Capa 3: Componente (El Uso)
Comprobando un componente.
.btn-primario {
color de fondo: var(--acción-primaria);
color: var(--bg-primario);
}
¿Por qué? Si la marca decide que “la acción principal ahora es violeta”, cambia una línea en la capa 2. No buscas/sed todo el código base.
2. Tematización dinámica (modo oscuro)
Debido a que las variables CSS se resuelven en tiempo de ejecución, implementar el modo oscuro es trivial. Simplemente redefine la Capa 2 dentro de un atributo de datos.
[tema-datos="oscuro"] {
--bg-primary: var(--palette-neutral-900);
--bg-secundario: var(--paleta-negro);
--text-body: var(--palette-white);
}
Cuando alterna el atributo en <cuerpo>, todo el sitio se vuelve a pintar instantáneamente (a 60 fps) porque el navegador simplemente intercambia los punteros. No es necesario recargar la hoja de estilo.
3. Alcance y aislamiento
Las variables obedecen a la Cascada. Esto permite un poderoso Estilo Contextual. Imagine una “Sección Oscura” en medio de una página clara.
.sección-invertida {
--text-body: var(--palette-white);
--bg-primary: var(--palette-neutral-900);
}
Cualquier componente (Tarjeta, Botón, Texto) colocado dentro de .section-inverted adoptará inherentemente los valores “Oscuros”, incluso si el resto de la página es Claro.
El código del componente no cambia. Simplemente consume la variable de su padre más cercano.
4. Interacción de JavaScript: seguimiento del mouse
Puede leer/escribir variables desde JS. Esto permite efectos de interfaz de usuario de alto rendimiento sin renderizaciones de React.
El efecto de foco “Seguir el cursor”:
document.addEventListener('mousemove', (e) => {
const x = e.clienteX;
const y = e.clienteY;
document.body.style.setProperty('--mouse-x', `${x}px`);
document.body.style.setProperty('--mouse-y', `${y}px`);
});
.foco {
fondo: gradiente radial (
círculo en var(--mouse-x) var(--mouse-y),
rgba(255, 255, 255, 0,2),
transparente 150px
);
}
Esto se ejecuta completamente en el hilo de CSS Compositor (principalmente).
5. Integración con Tailwind CSS
Nos encanta Tailwind. Pero codificar valores hexadecimales en tailwind.config.js es un antipatrón.
Vincula Tailwind a tu capa semántica.
// viento de cola.config.js
módulo.exportaciones = {
tema: {
colores: {
// Usa la variable CSS, no la hexadecimal
primario: 'var(--acción-primaria)',
fondo: 'var(--bg-primary)',
texto: 'var(--cuerpo-texto)',
}
}
}
Ahora bg-primary genera .bg-primary {color de fondo: var(--action-primary) }.
Obtiene el flujo de trabajo de la utilidad, pero mantiene la flexibilidad del tiempo de ejecución.
6. Errores de rendimiento
- Cambios de alcance de raíz: cambiar una variable en
:rootactiva un nuevo cálculo de estilo para el árbol DOM completo. Es rápido, pero hacerlo en un evento de “desplazamiento” es arriesgado. Prefiere cambios de alcance a contenedores específicos. - calc() Complejidad:
width: calc(var(--a) * var(--b) + 10px)obliga al navegador a hacer cálculos en cada cuadro si las variables cambian. Úselo con moderación.
7. El rendimiento de calc() frente a lo precalculado
Browser Math es rápido, pero no gratuito.
width: calc(var(--a) * var(--b)) se ejecuta en cada recálculo de diseño.
Si tiene 10.000 nodos haciendo esto, 60 fps se reducen a 30 fps.
Optimización: si el valor es estático para un componente, compálelo previamente en JS o SASS si es posible.
Utilice variables CSS para Valores que cambian en tiempo de ejecución (Tema, Dimensiones, configuración de usuario).
No los utilices sólo para evitar escribir números.
8. Uso de variables para estados de animación
En lugar de animar “transformar”, anime una variable.
.tarjeta {
transformar: traducirY(var(--y, 0)) escala(var(--s, 1));
transición: --y 0,2s, --s 0,2s;
}
.card: flotar {
--y: -10px;
--s: 1,05;
}
Esto es más limpio que redefinir toda la cadena “transformar”.
También permite animaciones independientes (por ejemplo, JS actualiza --y mientras CSS actualiza --s).
Reduce la sobrecarga del “análisis de cadenas CSS” para el navegador.
9. Estrategias alternativas
Para las bibliotecas críticas, proporcione siempre un recurso alternativo.
color: var(--cuerpo-texto, negro);
Si el usuario carga su componente pero se olvida de incluir el CSS del sistema de diseño, aún se mostrará en negro, no invisible.
9. Consultas de contenedor: variables contextuales
Consultas de medios (@media (ancho mínimo: 768 px)) consultan la Pantalla.
Consultas de contenedor (@container (min-width: 300px)) consultan el Parent.
Esto cambia nuestra forma de pensar sobre las variables.
Una tarjeta puede decir:
“Si mi contenedor es pequeño, --padding: 1rem. Si mi contenedor es grande, --padding: 2rem”.
Esto hace que los componentes sean verdaderamente portátiles.
Puede colocar la “Tarjeta de producto” en una barra lateral (pequeña) o en una cuadrícula principal (grande) y adapta su propia lógica interna sin anulaciones externas.
10. Modelo de objetos CSS escrito (Houdini)
¿Qué pasaría si pudieras escribir tus variables CSS?
CSS.registerProperty({ nombre: '--brand-color', sintaxis: '<color>', valor inicial: 'negro', hereda: verdadero })
Este es Houdini.
Le dice al navegador: “—brand-color ES UN COLOR”.
Si intenta configurarlo en “10px”, el navegador lo ignora.
Más importante aún, el navegador ahora puede animarlo correctamente porque sabe que es un color (interpolando valores RGB), no solo una cadena.
12. Houdini: La inmersión profunda
Houdini no se trata sólo de tipos. Se trata de Rendimiento.
Cuando animas una variable estándar, el navegador manipula cadenas en cada fotograma.
"10px" -> "11px" -> "12px".
Con CSS.registerProperty, realiza una interpolación flotante rápida.
10.0 -> 11.0 -> 12.0.
Esto mueve el trabajo del hilo principal al hilo del compositor.
La animación se mantiene fluida incluso si React está bloqueando el hilo principal con una tarea de hidratación intensa.
13. La regla @property (preparación para el futuro)
Mencionamos a Houdini. Ahora es estable en Chrome.
@propiedad --gradiente-ángulo {
sintaxis: '<ángulo>';
valor inicial: 0 grados;
hereda: falso;
}
¡Ahora puedes animar degradados!
girar fotograma clave {a { --gradient-angle: 360deg; } }
fondo: gradiente-cónico (de var (--ángulo-gradiente), rojo, azul);
Esto era imposible antes.
Tenías que usar JS/Canvas. Ahora es CSS nativo.
Esto desbloquea animaciones complejas de 60 fps en el compositor.
14. ¿Por qué Código Maison?
En Maison Code, enviamos Sistemas de diseño, no solo sitios web. Definimos los tokens de tu marca en JSON (Figma). Los exportamos a Variables CSS automáticamente. Nos aseguramos de que tu Modo Oscuro no sea una ocurrencia tardía, sino un ciudadano de primera clase. Construimos arquitecturas que le permiten cambiar el nombre de todo su sitio en 5 minutos cambiando algunos códigos hexadecimales. Valoramos la mantenibilidad tanto como la estética.
14. Lista de verificación de variables CSS
Antes de enviar su Design System:
- Espacio de nombres: ¿Tiene prefijo?
--ds-color-primaryfrente a--color-primary. - Reserva: ¿Tiene un valor de reserva?
var(--color, #000). - Imprimir: ¿Sus variables funcionan en el modo de impresión (“@media print`)?
- Contraste: comprueba la accesibilidad de tus variaciones del modo oscuro.
- Rendimiento: Evite
calc()dentro de los controladores de desplazamiento. - Herencia: ¿Utiliza
hereda: verdaderopara @property? - JS Sync: ¿Su JS está leyendo la variable correcta?
- Linting: Utilice
stylelintpara imponer el uso de variables sobre hexadecimal. - Documentación: ¿Existe un libro de cuentos que muestre todas las fichas?
- Control de versiones: ¿Cómo se manejan los cambios importantes en los tokens?
15. Conclusión
Las variables CSS son la herramienta más importante para escalar la arquitectura front-end. Cierran la brecha entre el “Diseño” (Tokens Figma) y el “Código” (CSS). Si no los está utilizando, no está creando un sistema. Sólo estás pintando páginas. Deje de codificar valores hexadecimales. Empieza a pensar en Tokens.
**[Contrate a nuestros arquitectos](/contact)**.