Haz que tu CSS sea dinámico con las propiedades personalizadas de CSS

Publicado: 2022-03-11

Si ha estado escribiendo CSS por un tiempo, en algún momento debe haber sentido la necesidad de variables. Las propiedades personalizadas de CSS son algo así como la propia implementación de variables de CSS. Sin embargo, cuando se usan correctamente, pueden ser mucho más que simples variables.

Las propiedades personalizadas de CSS le permiten:

  • Asigne valores arbitrarios a una propiedad con un nombre de su elección
  • Use la función var() para usar estos valores en otras propiedades

Aunque la compatibilidad con las propiedades personalizadas de CSS es un poco difícil en este momento, y algunos navegadores las admiten bajo indicadores que deben activarse o configurarse como verdaderos de antemano, se espera que su compatibilidad aumente drásticamente en el futuro, por lo que es importante comprender cómo usarlos y aprovecharlos. 1

Uso de propiedades personalizadas de CSS

En este artículo, aprenderá cómo puede usar las propiedades personalizadas de CSS para hacer que sus hojas de estilo sean un poco más dinámicas, tal vez haciendo obsoleto ese paso adicional de Sass/LESS en su canalización de activos.

La variable CSS original y menos potente

Antes de que comencemos a discutir las propiedades personalizadas de CSS, debe tenerse en cuenta que durante mucho tiempo, CSS ha tenido una especie de variable, y esa es la palabra clave currentColor . Esta variable rara vez utilizada pero ampliamente admitida, se refiere al valor de color actual de un elemento. Se puede usar en cualquier declaración que acepte un valor de color y se conecta perfectamente.

Echemos un vistazo a un ejemplo:

 .element { color: blue; border: 2px solid currentColor; /* Sets a solid, 2px wide, blue border to the element */ }

Además de la cascada, esto también puede producir lo siguiente:

 .element span { background: currentColor; /* Sets a blue background color for every span child of .element, unless a color property is declared in this same block */ } .element span.red { color: red; /* Sets a red background color for every span child of .element that has the class .red, since currentColor is applied to the background of every span child of .element no matter if they have the .red class or not */ }

El problema principal con currentColor , aparte del hecho de que no estaba en la especificación como una variable per se, es que solo acepta el valor de la propiedad color, lo que puede dificultar el trabajo en algunos casos.

Variables CSS completas

Una de las principales ventajas de usar pre/postprocesadores de CSS es que permiten que los valores se almacenen en una palabra clave y que se ajusten a un determinado selector si es necesario.

Después de mucho tiempo siendo solicitado por los desarrolladores, se escribió un borrador para una interpretación de variables nativas para CSS. Estos se conocen formalmente como propiedades personalizadas de CSS, pero a veces también se denominan variables de CSS.

La especificación actual para las propiedades personalizadas de CSS nativas cubre todos los mismos comportamientos que las variables de pre/postprocesador. Esto le permite almacenar códigos de color, tamaños con todas las unidades conocidas o solo números enteros si es necesario (por ejemplo, cuando necesita usar el mismo divisor o multiplicador).

La sintaxis de las propiedades personalizadas de CSS es un poco extraña en comparación con otros lenguajes, pero tiene mucho sentido si compara su sintaxis con otras características en el mismo ecosistema de CSS:

 :root { --color-black: #2e2e2e; } .element { background: var(--color-black); }

Ahora, podrías estar pensando: "¿Qué tipo de sintaxis es esa?"

Bueno, Lea Verou explica la razón de esta sintaxis de "guión-guión" con absoluta sencillez, como dice en su asombrosa charla, Variables CSS: var(–subtítulo):

Funcionan exactamente de la misma manera que cualquier otra propiedad CSS […]. Mucha gente me pregunta por qué no usamos un [signo] de dólar o algo así y la razón por la que no usamos un [signo] de dólar es que queremos que las personas puedan usar SASS, o variables de preprocesador y Variables CSS. Ambos son cosas diferentes, cumplen diferentes objetivos, hay cosas que puede hacer con variables CSS que absolutamente no puede hacer con SASS, y hay cosas que puede hacer con variables SASS que no puede hacer con variables CSS, así que queremos personas puedan usar ambos en la misma hoja de estilo, por lo que puede imaginar la sintaxis guión-guión como una propiedad de prefijo con un prefijo vacío.

Podemos recuperar el valor de la propiedad personalizada usando la función var() , que podemos usar en todas partes excepto para selectores, nombres de propiedades o declaraciones de consulta de medios.

Vale la pena señalar que, si bien las variables de pre/postprocesador solo se usan en el momento de la compilación, las variables de CSS se pueden usar y actualizar dinámicamente. ¿Qué significa esto? Significa que se conservan en la hoja de estilo CSS real. Entonces, la noción de que son variables permanecerá incluso después de compilar las hojas de estilo.

Para hacerlo más claro, permítanme ilustrar la situación con algunos ejemplos. El siguiente bloque de código es parte de una hoja de estilo SASS:

 :root { $value: 30px; } @media screen and (min-width: 768px) { $value: 60px; } .corners { border-radius: $value; }

Este fragmento de declaraciones y reglas SASS se compila en CSS de la siguiente manera:

 .corners { border-radius: 30px; }

Puede ver que tanto las propiedades dentro de :root como la consulta de media se pierden después de la compilación, porque las variables SASS no pueden existir dentro de un archivo CSS (o, para ser más precisos, se pueden forzar a existir en un archivo CSS, pero se ignoran ya que parte de su sintaxis es CSS no válida), por lo que el valor de la variable no se puede actualizar después.

Ahora, consideremos el mismo caso, pero aplicado utilizando solo variables CSS sin pre/postprocesador CSS aplicado (es decir, sin que se realice ninguna transpilación o compilación):

 :root { --value: 30px; } @media screen and (min-width: 768px) { --value: 60px; } .corners { border-radius: var(--value); }

Obviamente, nada cambia ya que no hemos compilado/transpilado nada, y el valor de la propiedad personalizada se puede actualizar dinámicamente. Entonces, por ejemplo, si cambiamos el valor de --value usando algo como JavaScript, el valor se actualizará en cada instancia en la que se llame usando la función var().

Las capacidades de las propiedades personalizadas hacen que esta característica sea tan poderosa que incluso puede hacer cosas como el prefijo automático.

Lea Verou establece un ejemplo utilizando la propiedad clip-path . Comenzamos configurando el valor de la propiedad que queremos prefijar como initial pero usamos una propiedad personalizada, y luego procedemos a establecer el valor de cada propiedad prefijada al valor de la propiedad personalizada:

 * { --clip-path: initial; -webkit-clip-path: var(--clip-path); clip-path: var(--clip-path); }

Después de esto, todo lo que queda es cambiar el valor de la propiedad personalizada dentro de un selector:

 header { --clip-path: polygon(0% 0%, 100% 0%, 100% calc(100% - 2.5em), 0% 100%); }

Si desea saber un poco más sobre esto, consulte el artículo completo de Lea sobre autoprefixing con variables CSS.

Propiedades personalizadas de CSS a prueba de viñetas

Como se mencionó, la compatibilidad del navegador con las propiedades personalizadas de CSS sigue siendo en gran medida no estándar. Entonces, ¿cómo se puede superar esto?

Aquí es donde entra en juego PostCSS y su complemento, postcss-css-variables.

En caso de que se esté preguntando qué es PostCSS, consulte mi artículo PostCSS: la nueva fecha de juego de SASS y vuelva a consultarlo cuando haya terminado. Entonces tendrá una idea básica de lo que puede hacer con esta increíble herramienta y no se sentirá desorientado al leer el resto del artículo.

Con el postcss-css-variables y su opción de preserve establecida en verdadero, podemos mantener todas las declaraciones de la función var() en la salida y tener el valor calculado como una declaración alternativa. También mantiene las declaraciones --var calculadas. Tenga en cuenta que, al usar este complemento de PostCSS, las propiedades personalizadas se pueden actualizar dinámicamente después del proceso de transpilación, pero los valores alternativos seguirán siendo los mismos, a menos que se orienten específicamente y se cambien explícitamente de forma individual.

Si está buscando una forma sin pre/postprocesador de usar variables CSS, siempre puede verificar el soporte actual manualmente con la regla @support de CSS y aplicar un respaldo adecuado cuando el soporte es irregular o inexistente. Por ejemplo:

 :root { --color-blue: #1e90ff; /* hex value for dodgerblue color */ } .element { background: var(--color-blue); } @supports (not(--value: 0)) { /* CSS variables not supported */ .element { background: dodgerblue; } }

Cambiar el valor de una propiedad personalizada usando JavaScript

He estado mencionando a lo largo de todo este artículo que las variables se pueden actualizar usando JavaScript, así que entremos en eso.

Digamos que tiene un tema claro y quiere cambiarlo a un tema oscuro, asumiendo que tiene un CSS como el siguiente:

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

Puede actualizar las propiedades personalizadas --text-color y --background-color haciendo lo siguiente:

 var bodyStyles = document.body.style; bodyStyles.setProperty('--text-color', 'white'); bodyStyles.setProperty('--background-color', 'black');

Casos de uso interesantes

A lo largo de los años de desarrollo y debate sobre las especificaciones de las propiedades personalizadas de CSS, han surgido algunos casos de uso interesantes. Aquí están algunos ejemplos:

Tematización: usar un conjunto de temas para un sitio es bastante fácil cuando se implementan variables CSS. ¿Quieres una variación clara u oscura de tu estilo actual? Simplemente cambie el valor de algunas propiedades personalizadas usando JavaScript y listo.

Ajustes de espaciado: ¿Necesita ajustar el espaciado de un sitio, por ejemplo, un canalón entre columnas? Cambie el valor de una sola variable CSS y vea este cambio reflejado en todo el sitio.

Funciones calc() completamente dinámicas: ahora puede tener funciones calc() completamente dinámicas usando propiedades personalizadas dentro de estas funciones, eliminando la necesidad de realizar cálculos complicados o efímeros dentro de JavaScript y luego actualizar estos valores manualmente en cada instancia.

Dale nueva vida a tus archivos CSS

Las propiedades personalizadas de CSS son una forma poderosa e innovadora de dar más vida a sus hojas de estilo, introduciendo valores completamente dinámicos por primera vez en CSS.

La especificación se encuentra actualmente en el estado de recomendación candidata, lo que significa que la estandarización está a la vuelta de la esquina, una buena razón para profundizar en esta función y aprovecharla al máximo.

  1. Nota: como señaló Lea Verou el 22 de abril, las propiedades personalizadas ahora son compatibles de forma predeterminada en casi todos los principales navegadores sin necesidad de cambiar una bandera. Su uso para producción es seguro a menos que se necesite compatibilidad con versiones anteriores de navegadores.