Las variables CSS o custom properties están definidas en la especificación de CSS desde diciembre de 2015; sin embargo, no las utilizamos mucho, como casi todo lo nuevo en CSS.

Normalmente esto nos ocurre por la falta de soporte en navegadores, pero a día de hoy el soporte ya no es una excusa:

Aunque todos estamos esperando con mucha expectación agosto de este año para que oficialmente IE11 deje de tener soporte, sabemos que tendremos que seguir incluyéndolo en los navegadores soportados de nuestros proyectos. Aun así, no es excusa para no usar custom properties ya que existen polyfills sencillos que nos permitirán usarlas y que todo funcione bien en IE11.

Probablemente, el principal motivo por el cual el uso de custom properties no está más extendido es que si ya uso un preprocesador que me da esta funcionalidad, ¿para qué voy a complicarme usándolas? Mi respuesta a esta pregunta es que confío en que CSS vaya evolucionando progresivamente hasta que dejemos de necesitar preprocesadores y podamos eliminar esa dependencia en nuestros proyectos. Además, las custom properties permiten hacer ‘cosas’ que las variables de un preprocesador no.

¿Para qué usamos las variables en CSS?

Para aquellos que estéis empezando o no tengáis muy claro para qué ibais a querer usar una variable en CSS, voy a poneros el ‘ejemplo de ejemplos’ sobre este tema: imaginad que llega un cambio de identidad corporativa (no es un mito, hace poco más de un año Paradigma lo hizo) y hay que cambiar el color primario de la marca en todas y cada una de las instancias en las que se use, y en todos y cada uno de los proyectos desarrollados bajo la marca. Antes de las variables, con suerte, un buscar y reemplazar nos salvaba del tedio, pero todos sabemos que eso no siempre funciona bien.

Si tenemos definido nuestro color primario de marca en una variable solo tendremos que ir a la definición de la misma y modificarla para que automágicamente cambie en todo el proyecto.

Usando Custom properties

Sintaxis, scope y cascada

La sintaxis de las custom properties es la siguiente:

/* Las custom properties se definen en el pseudo-elemento root */ 
:root { 

/* El nombre que le asignamos a la custom property comenzará con doble guión medio -- */ 

   --color-primary: #FF4745;
}

.my-title {
   /* Para usarlas debemos introducirlas en los paréntesis de la declaración var() */

   color: var(--color-primary);
}

Como todas las variables de cualquier lenguaje de programación, las custom properties también tienen su scope. Se definen dentro de la pseudo-clase :root que en CSS es el equivalente al selector del elemento padre más alto en el DOM, el cual normalmente suele ser la etiqueta html, pero nos ofrece una mayor especificidad. Debido a que suelen ser declaradas en la pseudo-clase :root, el scope de las variables es lo más global posible. Por supuesto, este scope puede verse reducido en caso de que así lo necesitemos, definiéndolas en algún otro selector más acotado.

También son sobreescribibles, ya que como cualquier otra propiedad CSS se ven afectadas por la cascada.


:root {
  --color-primary: #181F2C;
  --color-secondary: #03506f;
}

.primary-title {
  color: var(--color-secondary);
}

.secondary-title {
    /* volvemos a definir el valor de la variable para los elementos dentro de la clase secondary-title */

  --color-secondary: #726a95;
  color: var(--color-secondary);
}

.btn {
     /* Sobreescribimos el valor de las dos variables principales y las usamos valiéndonos de la cascada para definir el color de dos botones */
  --color-primary: #e36bae;
  --color-secondary: #822659; 
}

.btn.btn-purple {
  background-color: var(--color-secondary);
}

.btn.btn-pink {
  background-color: var(--color--primary);
}

Podéis ver el resultado en vivo a continuación:

See the Pen BaQzXxz by @NoemiMS on CodePen.

Fallbacks

La idea que tenemos de fallback es la de proveer de una alternativa a algo que pueda fallar. En el caso de las custom properties es algo parecido.

A la hora de definir un fallback de nuestra custom property, hay que tener en cuenta dos cosas:

:root {
    --primary-font: 'Roboto', sans-serif;
}

.my-paragraph {
  /* En este caso vamos a definir el valor de la propiedad font-family como haríamos de no existir la custom property para que los navegadores que no lo soporten, muestren correctamente el estilo que buscamos */
   font-family: 'Roboto', sans-serif;
   font-family: var(--primary-font);
}

Evidentemente esto no es muy práctico dado que tendríamos que repetir mucho código CSS. Por ello, lo más aconsejable es utilizar algún polyfill que nos resuelva el problema del soporte.

.my-paragraph {
  /* Indicamos un valor fijo tras el nombre de la variable para el caso en el que la variable no esté definida o pueda contener un valor erróneo */

   color: var(--primary-color, #4edbca);

  /* También se pueden usar variables como fallbacks que a su vez tengan un valor fijo seteado como fallback  */

  color: var(--primary-color, var(--blue-color, #00f)) ;

}

Cálculos

Las custom properties también pueden utilizarse junto a funciones propias de CSS como calc(). Por ejemplo:

:root{
  --std-size: 25px;

  --size-s: calc(var(--std-size) - 10px);
  --size-m: calc(var(--indent-size) + 10px);
  --size-l: calc(2*var(--indent-size));
}

/*Podemos tener diferentes valores definidos sin unidad, para poder usarlos con las custom properties debemos añadirles la unidad y la forma correcta de hacerlo es la siguiente*/
:root  {
   --unit: 5;
}

.my-element {
margin: calc(var(--unit)*1px) 0;
}

Si se hiciera algún cambio dinámico en el valor de estas variables durante la ejecución de la aplicación donde las estemos usando, el navegador recalculará automáticamente el valor del resto de variables dependientes de estas.

Podemos verlo aquí:

See the Pen eYBdYmm by @NoemiMS on CodePen.

Son “conscientes” del contenido del DOM

Las custom properties “entienden” el DOM y se aplican en base a ese consciencia del mismo. De esta manera podemos simplificar nuestro CSS:

.active {
  --color-active: PapayaWhip;
}

.btn {
  --color-default: Thistle;

  background-color: var(--color-active, var(--color-default));
}

/* Esto no es necesario gracias a esta característica de las custom properties */
.btn.active {
    background-color: var(--color-active);
}

Como vemos en este código tenemos dos utility classes definidas en las cuales se define el valor de una custom property. Al definir el background-color de la clase .btn incluímos un fallback a la custom property definida en la class .active, de manera que el navegador será capaz de interpretar esto como: si existe un elemento con la class .btn y, además, tiene la class .active le aplicará el primer valor definido en la propiedad background-color. En caso de no estar presente la class .active, le aplicará el valor fallback.

Gracias a que las custom properties son capaces de “leer” el DOM, podemos tener un botón activo sin necesidad de concatenar ambas clases.

Aquí podemos verlo para entenderlo mejor:

See the Pen gOLwZqp by @NoemiMS on CodePen.

¿Dónde no se pueden usar custom properties?

Si estamos acostumbrados al uso de preprocesadores, es posible que creamos que podemos utilizar las custom properties de la misma manera que las usamos con los preprocesadores. Lamentablemente hay algunos casos en los que el comportamiento de la custom property no será como la variable de un preprocesador:

@media (max-width: var(--mobile-breakpoint)) {
  ....
}
background-color: rgba(var(--color-primary), .25);
background-color: rgb(var(--color-primary));

Además, como otras propiedades css, las custom properties no son animables de manera que no podremos “sobrescribirlas” o “redefinirlas” dentro de una animación:

.animation {
  --my-color: #000;
  animation: myAnimation .5s loop;
}

@keyframes myAnimation {
  0% {
     --my-color: #000;
  }
  50% {
     --my-color: #f00;
  }
  100% {
     --my-color: #00f;
  }
}

Custom properties vs variables en preprocesadores

Las principales diferencias y ventajas de las custom properties frente a las variables de los preprocesadores son las siguientes:

Conclusión

La evolución de CSS es algo que no podemos seguir ignorando ya que progresivamente está convirtiéndose en un lenguaje de programación más potente que nos ofrece la posibilidad de ir eliminando dependencias de herramientas que suplieron sus carencias como son los preprocesadores.

Esta ha sido una breve introducción a las custom properties o variables CSS para animaros a comenzar a usarlas y sacarles todo el potencial que tienen.

Cuéntanos qué te parece.

Los comentarios serán moderados. Serán visibles si aportan un argumento constructivo. Si no estás de acuerdo con algún punto, por favor, muestra tus opiniones de manera educada.

Suscríbete

Estamos comprometidos.

Tecnología, personas e impacto positivo.