Introducción
En los navegadores actuales, es común encontrar propiedades como esta:
elemento {
--color-fondo-principal: marrón;
}
A continuación, explicaremos detalladamente este concepto y proporcionaremos información relevante sobre su funcionamiento.
Descripción general
Las propiedades personalizadas (también conocidas como variables CSS o variables en cascada) son definidas por el autor de CSS y contain valores que pueden reutilizarse en todo el documento. Se establecen mediante la propiedad personalizada (por ejemplo: --color-primario: negro;) y se obtienen mediante la función var() (por ejemplo: color: var(--color-primario);)
Declaración
Para declarar una propiedad personalizada, el nombre debe comenzar con dos guiones (--) y el valor puede ser cualquier valor CSS válido. Como se mostró en la introducción, la propiedad --color-fondo-principal
La práctica recomendada es definirlas en el pseudoelemento :root, lo que permite acceder a ellas desde cualquier parte del documento HTML:
/*El selector :root coincide con el elemento raíz del documento.*/
/*En HTML, el elemento raíz siempre es html.*/
/*Por lo tanto: root representa el elemento raíz*/
:root {
--color-fondo-principal: marrón;
}
Nota: Los nombres de propiedades personalizadas distinguen entre mayúsculas y minúsculas, --mi-color y --Mi-color se consideran dos propiedades diferentes. Además, no pueden contener caracteres como $, [, ^, (, %, etc. Los caracteres permitidos son números [0-9], letras [a-zA-Z], guiones bajos _ y guiones -. Sin embargo, pueden usar caracteres chinos, japoneses o coreanos, por ejemplo:
body {
--azul-oscuro: #369;
background-color: var(--azul_oscuro);
}
Utilización
elemento {
background-color: var(--color-fondo-principal);
}
Estas propiedades personalizadas solo se calculan cuando son necesarias y no se almacenan según otras reglas. Por ejemplo, no se puede establecer una propiedad en un elemento para que obtenga un valor de reglas de hermanos o descendientes. Las propiedades solo coinciden con el selector actual y sus descendientes, similar al CSS tradicional.
Valores predeterminados
La función var() permite definir múltiples valores de respaldo que se utilizarán cuando el valor proporcionado no esté definido.
/*Si se proporciona el segundo parámetro, representa el valor de respaldo cuando el valor de la propiedad personalizada no sea válido. El segundo parámetro puede anidarse, pero no se puede expandir más allá:*/
.dos {
color: var(--mi-variable, rojo); /* Rojo si --mi-variable no está definida */
}
.tres {
background-color: var(--mi-variable, var(--mi-fondo, rosa)); /* Rosa si --mi-variable y --mi-fondo no están definidas */
}
.tres {
background-color: var(--mi-variable, --mi-fondo, rosa); /* Inválido: "--mi-fondo, rosa" */
}
El segundo ejemplo muestra cómo manejar más de un valor de respaldo. Esta técnica puede causar problemas de rendimiento, ya que requiere más tiempo para procesar estas variables.
Manipulación en JavaScript
En JavaScript, obtener o modificar variables CSS es similar a trabajar con propiedades CSS regulares:
// Obtener una variable CSS de un nodo DOM
elemento.style.getPropertyValue("--mi-variable");
// Obtener una variable CSS de cualquier nodo DOM
getComputedStyle(elemento).getPropertyValue("--mi-variable");
// Modificar una variable CSS de un nodo DOM
elemento.style.setProperty("--mi-variable", variableJs + 4);
Característica de espacio en blanco al final
body {
--tamaño: 20;
font-size: var(--tamaño)px;
}
Aquí font-size:var(--tamaño)px es equivalente a font-size:20 px. Hay un espacio después de 20, por lo que el font-size usa el tamaño predeterminado del elmeento <body>.
Casos de uso
Un ejemplo práctico: implementar una barra de progreso:
Hay una capa de fondo exterior, luego una barra de progreso dentro, y el valor del progreso.
Anteriormente, se usaban dos elementos div y JavaScript para cambiar el ancho de la barra de color y establecer el valor del progreso.
<label>Imagen 1:</label>
<div class="barra" style="--porcentaje: 60;"></div>
<label>Imagen 2:</label>
<div class="barra" style="--porcentaje: 40;"></div>
<label>Imagen 3:</label>
<div class="barra" style="--porcentaje: 20;"></div>
.barra {
height: 20px; width: 300px;
background-color: #f5f5f5;
}
.barra::before {
display: block;
counter-reset: progreso var(--porcentaje);
content: counter(progreso) '%\2002';
width: calc(1% * var(--porcentaje));
color: #fff;
background-color: #2486ff;
text-align: right;
white-space: nowrap;
overflow: hidden;
}
Como se puede observar, solo necesitamos una etiqueta div, lo que simplifica la estructura del DOM. Además, el único cambio requerido en el HTML es el atributo personalizado --porcentaje.
Extensión
Podemos extender las variables CSS mediante @property:
Su sintaxis:
@property --nombre-propiedad {
syntax: '<color>';
inherits: false;
initial-value: #c0ffee;
}
Los descriptores syntax y inherits en la regla @property son obligatorios; si falta cualquiera de ellos, toda la regla será inválida y se ignorará.
Eldescriptor initial-value solo es opcional cuando el descriptor syntax define una sintaxis general, de lo contrario initial-value también es obligatorio: si falta, toda la regla será inválida y se ignorará.
También podemos crear una usando JavaScript:
window.CSS.registerProperty({
name: '--mi-color',
syntax: '<color>',
inherits: false,
initialValue: '#c0ffee',
});
Su propósito, en muchos casos, es implementar efectos de animación que antes no eran posibles de manera sencilla.
Compatibilidad
Actualmente, la compatibilidad de variables CSS comienza desde Chrome 49:
En CSS podemos manejar la compatibilidad:
.selector: {}
@supports ( (--a: 0)) {
/* compatible */
.selector: {}
}
@supports ( not (--a: 0)) {
/* no compatible */
.selector: {}
}
En JavaScript también podemos realizar la verificación correspondiente:
const esCompatible =
window.CSS &&
window.CSS.supports &&
window.CSS.supports('--a', 0);
Sin embargo, @property es solo una propiedad experimentla y sus requisitos de compatibilidad son muy estrictos.
Polyfill
https://github.com/jhildenbiddle/css-vars-ponyfill
El uso de este polyfill permite alcanzar la siguiente compatibilidd:
Chrome 19+
Edge 12+
Firefox 6+
IE 9+
Safari 6+
Situación actual
less/sass
En la mayoría de los proyectos se utilizan less/sass/scss, pero estas herramientas de preprocesamiento CSS ya tienen funcionalidad de variables. Si además se usan las variables CSS nativas, puede resultar redundante.
Para estos preprocesadores, podemos reemplazar las variables originales con variables CSS nativas, manteniendo lo demás sin cambios.
CSS in JS
Una vez definidas las variables CSS base en root, se pueden utilizar en JavaScript. En este tipo de frameworks, tienen un gran potencial de aplicación.
CSS atómico
Un marco de trabajo de CSS atómico ampliamente utilizado es TailwindCSS.
Este tipo de marco utiliza ampliamente variables CSS internamente. Por lo tanto, si puedes usar Tailwind, también puedes usar variables CSS.
Conclusión
El soporte del navegador para esta funcionalidad de variables CSS ya es suficiente. Además, existe una buena adaptación para los diversos preprocesadores CSS existentes. Si está considerando usarlo, puede intentar adoptarlo.
Por supuesto, actualmente no existe una solución completamente integral, por lo que esperar un poco más no representa ningún problema.
Referencias
- https://developer.mozilla.org/zh-CN/docs/Web/CSS/Using_CSS_custom_properties
- https://www.zhangxinxu.com/wordpress/2016/11/css-css3-variables-var/
- https://juejin.cn/post/6937530846471520287
- https://www.zhangxinxu.com/wordpress/2020/07/css-var-improve-components/
- https://developer.mozilla.org/zh-CN/docs/Web/CSS/@property#browser_compatibility