Introducción a las propiedades personalizadas o variables en CSS

Veamos qué nos ofrecen las custom properties en CSS y cómo interactúan con la cascada.

Ahora que cada vez hay más cosas de las que usamos que ya no dan soporte a IE11 como Wordpress, Angular, Bootstrap o GitHub por nombrar algunos, me parece un buen momento para echar un vistazo a lo que las CSS custom properties o propiedades personalizadas de CSS o variables en CSS nos pueden ofrecer.

Pero... ¿qué son las custom properties?

Enlace permanente a “Pero... ¿qué son las custom properties?”

Como has leído antes, tienen varios nombres. Las variables se definen abriendo un bloque e iniciando cualquier cadena con dos guiones. Al definirlas en CSS tienen esta forma:

:root {
--my-custom-property: 'Hola Mundo!';
}

Quizá te estés preguntando qué es :root. Es el componente raíz. Definir variables ahí hace que estén disponibles para toda la cascada.

Aunque hemos tenido variables de algún tipo con pre y post procesadores como Less, Sass o PostCSS, esas variables quedaban transformadas en algún punto del proceso. Entonces, ¿qué es lo que es tan genial de las custom properties? Bueno, para empezar no necesitan Webpack ni ningún pre/post procesador, siguen la cascada de CSS y además se pueden actualizar a través de JS en el navegador.

Mientras que no necesitar sistema de procesamiento es fácil de entender, el resto puede ser quizá un poco más complejo.

Veamos qué las hace tan increíbles.

Qué podemos hacer

Enlace permanente a “Qué podemos hacer”

Echando la vista atrás, la gente tiene diferentes relaciones con la cascada en CSS. Algunas personas la odian y otros la aman. Es una parte inherente de CSS. Veamos cómo nos son útiles en la cascada:

.main {
--custom-color: red;
}

.block {
background-color: var(--custom-color, rebeccapurple);
}

.sidebar {
--custom-color: blue;
}

¿De qué color será .block? Dado que la propiedad tiene cascada, si .block está dentro de .sidebar heredará el color blue que se definió en su ancestro más cercano. Si .block aparece en .main cogerá el color que se especifica ahí que es red. ¡Cambios basados en el contexto sin necesitar selectores!

Quizá te hayas dado cuenta de que en .block hay dos valores dentro de var. Este segundo valor (opcional) nos permite definir un valor por defecto en caso de que no haya ninguno definido. En este caso, si .block no está anidad en ningún otro elemento que de valor a --custom-color usará el que está definido ahí, rebeccapurple en este caso.

Todo esto está bastante guay, pero podemos añadir reglas basadas en otros cambios de contexto:

body {
background-color: var(--color-background, white);
color: var(--color-text, black);
}

@media screen and (prefers-color-scheme: dark) {
body {
--color-text: white;
--color-background: black;
}
}

Usando media queries, podemos cambiar el valor de nuestras propiedades. En este caso, para dar soporte al modo oscuro. Aquí tenemos un único selector pero imagina cambiar todos los elementos del diseño simplemente actualizando las variables que usan. Con esos conceptos podemos hacer cosas como plantillas, sistemas de diseño y componentes reusables de forma sencilla.

Subamos un último peldaño y vamos a ver cómo podemos hacer una rejilla y pongamos todo en práctica. El código tiene comentarios para ver cómo están las cosas.

// Variables globales para todos
// Aquí estarían los colores, fuentes, etc.
:root {
--color-primary-hue: 30;
}

.grid {
// Propiedades disponibles para los elementos .item
--grid-column-width: 1fr;
--grid-column-count: 4;
--grid-gap: 1.25rem;

@media (min-width: 60em) {
--grid-column-count: 8;
}

@media (min-width: 80em) {
--grid-gap: 2.5rem;
--grid-column-count: 12;
}

display: grid;
grid-gap: var(--grid-gap);
grid-template-columns: repeat(var(--grid-column-count), var(--grid-column-width));

// Podemos repetir propiedades personalizadas donde queramos
// En este caso combinando con calc podríamos hacer más cosas
padding-left: var(--grid-gap);
padding-right: var(--grid-gap);
margin-left: auto;
margin-right: auto;
max-width: 90rem;
}

.item {
// Vamos a calcular la saturación basándonos en la posición del elemento
// Dado que solo manipulamos por elemento, tiene sentido definirlo aquí
--saturation: calc(var(--index) * (100 / var(--items)) * 1%);

// Puedes usar custom properties como parte de un valor como en HSL
// Observa que estamos usando una variable global ( temas )
background: hsl(var(--color-primary-hue), var(--saturation), 40%);
border-color: hsl(var(--color-primary-hue), var(--saturation), 50%);

height: 3rem;
border-radius: 0.5rem;
border-style: solid;
border-width: 0.125rem;

// Las columnas de la grid se establecen aquí y se actualizan con clases (mira abajo)
// Estamos usando un valor por defecto en caso de que no tengan un valor
grid-column: span var(--span, var(--grid-column-count));
}

.item--half {
@media (min-width: 60em) {
--span: 4;
}

@media (min-width: 80em) {
--span: 6;
}
}

.item--third {
@media (min-width: 80em) {
--span: 4;
}
}

.item--fourth {
@media (min-width: 60em) {
--span: 2;
}

@media (min-width: 80em) {
--span: 3;
}
}

Y este sería el resultado. Si estás en un escritorio te animo a ajustar el tamaño de tu pantalla y si estás en otro entorno ¡visítala en escritorio!

En resumen

Enlace permanente a “En resumen”

Estos son algunos de los poderes que la custom properties nos ofrecen. Conforme las tecnologías avancen y los navegadores mejoren, vamos a tener muchas más opciones.

En el siguiente artículo vemos cómo podemos usar estas propiedades con JavaScript lo cual nos da aún más opciones a la hora de nuevos trucos e interacciones: El potencial de las CSS Custom Properties: son dinámicas.

Más recursos:

En las redes

¡Únete a la conversación en Twitter! O si te gustó el artículo y crees que otros deberían leerlo, ¡compártelo!

0 retweets

    0 respuestas

      Este blog usa menciones webs promovidas por la IndieWeb y usando webmention.io y Bridgy. ¿Has publicado tu propio artículo mencionando a este? ¡Hazme saber la URL!