Propiedades personalizadas y CSS moderno

Escoges un azul de marca, lo escribes en cuarenta reglas diferentes y publicas el sitio. Un mes después marketing quiere un azul ligeramente diferente. Ahora estás buscando en cada hoja de estilos, esperando atrapar los cuarenta y no perder los dos que fueron escritos con mayúscula. Las propiedades personalizadas arreglan esto: nombras el color una sola vez, usas el nombre en todas partes, y lo cambias en un lugar. Ese único hábito es el comienzo de los temas, tokens de diseño, y hojas de estilos que sobreviven a un rediseño.
Declarar y usar una variable
Una propiedad personalizada es un valor al que le das un nombre para poder reutilizarlo. Escribes el nombre con dos guiones al frente, lo estableces a un valor, y luego lo lees de vuelta con var():
:root {
--color-brand: #2563eb; /* declara el valor una sola vez, bajo un nombre */
}
.button {
background: var(--color-brand); /* léelo de vuelta aquí */
}
.link {
color: var(--color-brand); /* y aquí, el mismo valor */
}--color-brand es el nombre (los dos guiones son obligatorios), y var(--color-brand) es cómo lo usas. Declararlo en :root (que es el elemento <html>, la parte superior de la página) hace que el nombre esté disponible en todas partes. Cambia la línea única en :root y cada regla que la lee se actualiza.
--color-brand, luego léelo con var(--color-brand). Ponlo en :root para que toda la página pueda usarlo. Cambia la línea única y cada regla que lee el nombre se actualiza con ella. En cascada y herencia
Si has usado variables en otro lenguaje, esta siguiente parte es la sorpresa: una propiedad personalizada no es fija. Sigue las mismas reglas que cualquier otra propiedad de CSS, lo que significa que hereda hacia elementos hijos, y puedes darle un valor diferente en un lugar sin tocar el resto.
:root {
--color-text: #1f2937; /* el predeterminado para toda la página */
}
.callout {
--color-text: #92400e; /* un valor diferente, solo dentro de .callout */
color: var(--color-text);
}
p {
color: var(--color-text); /* gris oscuro normalmente, ámbar dentro de un callout */
}El mismo var(--color-text) te da gris oscuro en la mayoría de párrafos pero ámbar dentro de un callout, porque el callout estableció su propio valor. Esto es lo que hace posible la temática, y has visto la cascada detrás de ello en cómo funciona CSS.
var(--color-text) puede ser gris en la mayoría de párrafos y ámbar dentro de un callout. Redefine el nombre en un contenedor y todo dentro de él recoge el nuevo valor. Fallbacks y calc()
var() puede tomar un segundo valor, usado solo si la propiedad personalizada nunca fue establecida. Este es el fallback, y mantiene una regla funcionando incluso cuando un token falta:
.card {
gap: var(--gap, 1rem); /* usa --gap si existe, de lo contrario 1rem */
}También puedes hacer matemáticas con una propiedad personalizada usando calc(). Si tienes un valor de espaciado base, puedes construir uno más grande a partir de él en lugar de codificar un segundo número:
:root {
--space-md: 16px;
}
.section {
padding: calc(var(--space-md) * 2); /* 32px, derivado del base */
}Derivar valores así significa que un cambio a --space-md se propaga a través de todo lo construido encima de él.
var(--gap, 1rem) usa el token si existe y cae a 1rem si no, así una regla sigue funcionando cuando un valor falta. Y calc() te permite construir valores desde un token, como calc(var(--space-md) * 2) para el doble del espaciado base. Cambia el base y todo construido en él sigue. Temática
Porque una propiedad personalizada puede ser redefinida más abajo del árbol, puedes construir un tema oscuro cambiando los tokens bajo una clase, y dejar cada regla de componente sola:
:root {
--color-bg: #ffffff;
--color-text: #1f2937;
}
.theme-dark {
--color-bg: #0f172a; /* los mismos nombres, nuevos valores */
--color-text: #e2e8f0;
}
body {
background: var(--color-bg);
color: var(--color-text);
}Añade class="theme-dark" a la página y cada regla que lee --color-bg o --color-text cambia a los valores oscuros. Nunca tocaste la regla body, o cualquier componente, para hacer el cambio de tema. Ese es el beneficio de nombrar tus colores como tokens en lugar de escribir los códigos hex directamente.
.theme-dark. Establece class="theme-dark" y cada regla leyendo esos tokens cambia, sin editar un sólo componente. Por eso nombras tus colores como tokens en lugar de escribir el código hex directamente en cada regla. 
