Propiedades personalizadas de CSS en la cascada

Publicado: 2022-03-10
Resumen rápido ↬ En este artículo, Miriam profundiza en la especificación 'Propiedades personalizadas CSS para variables en cascada' para preguntar: "¿Por qué se llaman propiedades personalizadas, cómo funcionan en la cascada y qué más podemos hacer con ellas? ?” Más allá de la metáfora de la "variable", las propiedades personalizadas pueden proporcionar nuevas formas de equilibrar el contexto y el aislamiento en los patrones y componentes de CSS.

El mes pasado, tuve una conversación en Twitter sobre la diferencia entre los estilos de "alcance" (generados en un proceso de compilación) y los estilos "anidados" nativos de CSS. Pregunté por qué, anecdóticamente, los desarrolladores evitan la especificidad de los selectores de ID, mientras adoptan los "estilos de alcance" generados por JavaScript. Keith Grant sugirió que la diferencia radica en equilibrar la cascada* y la herencia, es decir, dar preferencia a la proximidad sobre la especificidad. Vamos a ver.

la cascada

La cascada de CSS se basa en tres factores:

  1. Importancia definida por el indicador !important y el origen del estilo (usuario > autor > navegador)
  2. Especificidad de los selectores utilizados (en línea > ID > clase > elemento)
  3. Orden de origen del propio código (el último tiene prioridad)

La proximidad no se menciona en ninguna parte: la relación del árbol DOM entre las partes de un selector. Los párrafos a continuación estarán ambos en rojo, aunque #inner p describe una relación más estrecha que #outer p para el segundo párrafo:

Vea el Pen [Cascade: Specificity vs Proximity](https://codepen.io/smashingmag/pen/OexweJ/) de Miriam Suzanne.

Ver Pen Cascade: Especificidad vs Proximidad por Miriam Suzanne.
 <section> <p>This text is red</p> <div> <p>This text is also red!</p> </div> </section>
 #inner p { color: green; } #outer p { color: red; }

Ambos selectores tienen la misma especificidad, ambos describen el mismo elemento p y ninguno está marcado como !important , por lo que el resultado se basa solo en el orden de origen.

¡Más después del salto! Continúe leyendo a continuación ↓

BEM y estilos de alcance

Las convenciones de nomenclatura como BEM ("Block__Element—Modifier") se utilizan para garantizar que cada párrafo tenga "alcance" a un solo padre, evitando la cascada por completo. Los "elementos" de párrafo reciben clases únicas específicas para su contexto de "bloque":

Consulte el Pen [BEM Selectors & Proximity](https://codepen.io/smashingmag/pen/qzPyeM/) de Miriam Suzanne.

Vea los Selectores Pen BEM y Proximity de Miriam Suzanne.
 <section class="outer"> <p class="outer__p">This text is red</p> <div class="inner"> <p class="inner__p">This text is green!</p> </div> </section>
 .inner__p { color: green; } .outer__p { color: red; }

Estos selectores aún tienen la misma importancia relativa, especificidad y orden de origen, pero los resultados son diferentes. Las herramientas CSS de "alcance" o "modulares" automatizan ese proceso, reescribiendo nuestro CSS para nosotros, basado en HTML. En el siguiente código, cada párrafo tiene como alcance a su padre directo:

Consulte el Pen [Proximidad de estilo con alcance] (https://codepen.io/smashingmag/pen/NZaLWN/) de Miriam Suzanne.

Vea Proximidad al estilo Pen Scoped de Miriam Suzanne.
 <section outer-scope> <p outer-scope>This text is red</p> <div outer-scope inner-scope> <p inner-scope>This text is green!</p> </div> </section>
 p[inner-scope] { color: green } p[outer-scope] { color: red; }

Herencia

La proximidad no es parte de la cascada, pero es parte de CSS. Ahí es donde la herencia se vuelve importante. Si quitamos la p de nuestros selectores, cada párrafo heredará un color de su ancestro más cercano:

Consulte el Pen [Herencia: especificidad frente a proximidad] (https://codepen.io/smashingmag/pen/mZBGyN/) de Miriam Suzanne.

Ver Herencia de pluma: Especificidad vs Proximidad por Miriam Suzanne.
 #inner { color: green; } #outer { color: red; }

Dado que #inner y #outer describen diferentes elementos, nuestro div y section respectivamente, ambas propiedades de color se aplican sin conflicto. El elemento p anidado no tiene un color especificado, por lo que los resultados se determinan por herencia (el color del padre directo) en lugar de cascada . La proximidad tiene prioridad y el valor #inner anula el #outer .

Pero hay un problema: para usar la herencia, estamos diseñando todo dentro de nuestra section y div . Queremos apuntar específicamente al color del párrafo.

(Re)Introducción de propiedades personalizadas

Las propiedades personalizadas proporcionan una nueva solución nativa del navegador; heredan como cualquier otra propiedad, pero no tienen que usarse donde están definidas . Usando CSS simple, sin convenciones de nomenclatura ni herramientas de compilación, podemos crear un estilo que sea a la vez específico y contextual, en el que la proximidad tenga prioridad sobre la cascada:

Vea el Pen [Accesorios personalizados: Especificidad vs Proximidad](https://codepen.io/smashingmag/pen/gNGdaO/) por Miriam Suzanne.

Vea los accesorios personalizados de la pluma: especificidad frente a proximidad de Miriam Suzanne.
 p { color: var(--paragraph); } #inner { --paragraph: green; } #outer { --paragraph: red; }

La propiedad custom --paragraph se hereda igual que la propiedad color , pero ahora tenemos control sobre cómo y dónde se aplica exactamente ese valor. La propiedad --paragraph actúa de manera similar a un parámetro que se puede pasar al componente p , ya sea mediante selección directa (reglas de especificidad) o contexto (reglas de proximidad).

Creo que esto revela un potencial para las propiedades personalizadas que a menudo asociamos con funciones, mixins o componentes.

"Funciones" y parámetros personalizados

Las funciones, los mixins y los componentes se basan en la misma idea: código reutilizable, que se puede ejecutar con varios parámetros de entrada para obtener resultados consistentes pero configurables. La distinción está en lo que hacen con los resultados. Comenzaremos con una variable de degradado rayado y luego podemos extenderla a otras formas:

 html { --stripes: linear-gradient( to right, powderblue 20%, pink 20% 40%, white 40% 60%, pink 60% 80%, powderblue 80% ); }

Esa variable se define en el elemento html raíz (también podría usar :root , pero eso agrega una especificidad innecesaria), por lo que nuestra variable rayada estará disponible en todas partes del documento. Podemos aplicarlo en cualquier lugar donde se admitan gradientes:

Vea el Pen [Accesorios personalizados: Variable](https://codepen.io/smashingmag/pen/NZwrrm/) de Miriam Suzanne.

Vea los Accesorios personalizados para bolígrafos: Variable de Miriam Suzanne.
 body { background-image: var(--stripes); }

Adición de parámetros

Las funciones se usan como variables, pero definen parámetros para cambiar la salida. Podemos actualizar nuestra variable --stripes para que sea más similar a una función definiendo algunas variables similares a parámetros dentro de ella. Comenzaré reemplazando to right con var(--stripes-angle) , para crear un parámetro de cambio de ángulo:

 html { --stripes: linear-gradient( var(--stripes-angle), powderblue 20%, pink 20% 40%, white 40% 60%, pink 60% 80%, powderblue 80% ); }

Hay otros parámetros que podríamos crear, dependiendo del propósito al que se destine la función. ¿Deberíamos permitir que los usuarios elijan sus propios colores de franjas? Si es así, ¿nuestra función acepta 5 parámetros de color diferentes o solo 3 que irán de afuera hacia adentro como tenemos ahora? ¿Queremos crear parámetros para las paradas de color también? Cada parámetro que agregamos proporciona más personalización a costa de la simplicidad y la consistencia.

No existe una respuesta correcta universal para ese equilibrio: algunas funciones deben ser más flexibles y otras deben ser más obstinadas. Las abstracciones existen para proporcionar consistencia y legibilidad en su código, así que dé un paso atrás y pregúntese cuáles son sus objetivos. ¿Qué necesita realmente ser personalizable y dónde se debe aplicar la consistencia? En algunos casos, podría ser más útil tener dos funciones de opinión, en lugar de una función totalmente personalizable.

Para usar la función anterior, necesitamos pasar un valor para el parámetro --stripes-angle y aplicar la salida a una propiedad de salida CSS, como background-image :

 /* in addition to the code above… */ html { --stripes-angle: 75deg; background-image: var(--stripes); } 

Vea el Pen [Accesorios personalizados: Función](https://codepen.io/smashingmag/pen/BgwOjj/) de Miriam Suzanne.

Vea los accesorios personalizados de la pluma: función de Miriam Suzanne.

Heredado Versus Universal

--stripes la función --stripes en el elemento html por costumbre. Las propiedades personalizadas heredan, y quiero que mi función esté disponible en todas partes, por lo que tiene sentido colocarla en el elemento raíz. Eso funciona bien para heredar variables como --brand-color: blue , por lo que también podemos esperar que funcione para nuestra "función". Pero si intentamos usar esta función nuevamente en un selector anidado, no funcionará:

Consulte el Pen [Accesorios personalizados: error de herencia de funciones] (https://codepen.io/smashingmag/pen/RzjRrM/) de Miriam Suzanne.

Consulte Accesorios personalizados del bolígrafo: error de herencia de función de Miriam Suzanne.
 div { --stripes-angle: 90deg; background-image: var(--stripes); }

El nuevo --stripes-angle se ignora por completo. Resulta que no podemos confiar en la herencia para las funciones que deben volver a calcularse. Esto se debe a que cada valor de propiedad se calcula una vez por elemento (en nuestro caso, el elemento raíz html ) y luego se hereda el valor calculado . Al definir nuestra función en la raíz del documento, no hacemos que la función completa esté disponible para los descendientes, solo el resultado calculado de nuestra función.

Eso tiene sentido si lo enmarcas en términos del parámetro cascading --stripes-angle . Como cualquier propiedad CSS heredada, está disponible para los descendientes pero no para los ancestros. El valor que establecemos en un div anidado no está disponible para una función que definimos en el ancestro raíz html . Para crear una función universalmente disponible que vuelva a calcular en cualquier elemento, debemos definirla en cada elemento:

Vea el Pen [Accesorios personalizados: Función universal](https://codepen.io/smashingmag/pen/agLaNj/) de Miriam Suzanne.

Vea los accesorios personalizados para bolígrafos: función universal de Miriam Suzanne.
 * { --stripes: linear-gradient( var(--stripes-angle), powderblue 20%, pink 20% 40%, white 40% 60%, pink 60% 80%, powderblue 80% ); }

El selector universal hace que nuestra función esté disponible en todas partes, pero podemos definirla de forma más específica si queremos. Lo importante es que solo puede volver a calcular donde está explícitamente definido. Aquí hay algunas alternativas:

 /* make the function available to elements with a given selector */ .stripes { --stripes: /* etc… */; } /* make the function available to elements nested inside a given selector */ .stripes * { --stripes: /* etc… */; } /* make the function available to siblings following a given selector */ .stripes ~ * { --stripes: /* etc… */; } 

Vea el Pen [Accesorios personalizados: función de ámbito](https://codepen.io/smashingmag/pen/JQMvGM/) de Miriam Suzanne.

Vea los accesorios personalizados de la pluma: función de ámbito de Miriam Suzanne.

Esto se puede ampliar con cualquier lógica de selector que no dependa de la herencia.

Parámetros gratuitos y valores alternativos

En nuestro ejemplo anterior, var(--stripes-angle) no tiene valor ni respaldo. A diferencia de las variables Sass o JS que deben definirse o instanciarse antes de llamarlas, las propiedades personalizadas de CSS se pueden llamar sin definirlas nunca. Esto crea una variable "libre", similar a un parámetro de función que se puede heredar del contexto.

Eventualmente podemos definir la variable en html o :root (o cualquier otro ancestro) para establecer un valor heredado, pero primero debemos considerar la alternativa si no se define ningún valor. Hay varias opciones, dependiendo exactamente de qué comportamiento queremos

  1. Para los parámetros "requeridos", no queremos una alternativa. Tal como está, la función no hará nada hasta que se --stripes-angle .
  2. Para los parámetros "opcionales", podemos proporcionar un valor alternativo en la función var() . Después del nombre de la variable, agregamos una coma, seguida del valor predeterminado:
 var(--stripes-angle, 90deg)

Cada función var() solo puede tener un respaldo, por lo que cualquier coma adicional será parte de ese valor. Eso hace posible proporcionar valores predeterminados complejos con comas internas:

 html { /* Computed: Hevetica, Ariel, sans-serif */ font-family: var(--sans-family, Hevetica, Ariel, sans-serif); /* Computed: 0 -1px 0 white, 0 1px 0 black */ test-shadow: var(--shadow, 0 -1px 0 white, 0 1px 0 black); }

También podemos usar variables anidadas para crear nuestras propias reglas en cascada, dando diferentes prioridades a los diferentes valores:

 var(--stripes-angle, var(--global-default-angle, 90deg))
  1. Primero, pruebe nuestro parámetro explícito ( --stripes-angle );
  2. Retroceda a un "valor predeterminado de usuario" global ( --user-default-angle ) si está disponible;
  3. Finalmente, recurra a nuestro "valor predeterminado de fábrica" (90deg ).

Consulte el Pen [Accesorios personalizados: valores alternativos](https://codepen.io/smashingmag/pen/jjGvVm/) de Miriam Suzanne.

Vea los accesorios personalizados de la pluma: valores alternativos de Miriam Suzanne.

Al establecer valores alternativos en var() en lugar de definir la propiedad personalizada explícitamente, nos aseguramos de que no haya restricciones de especificidad o cascada en el parámetro. Todos los parámetros de *-angle son "libres" para ser heredados de cualquier contexto.

Fallbacks del navegador frente a fallbacks variables

Cuando usamos variables, hay dos rutas alternativas que debemos tener en cuenta:

  1. ¿Qué valor deben usar los navegadores sin soporte de variables?
  2. ¿Qué valor deben usar los navegadores que admiten variables, cuando falta una variable en particular o no es válida?
 p { color: blue; color: var(--paragraph); }

Mientras que los navegadores antiguos ignorarán la propiedad de declaración de variable y volverán al blue , los navegadores modernos leerán ambos y usarán el último. Es posible que nuestra var(--paragraph) no esté definida, pero es válida y anulará la propiedad anterior, por lo que los navegadores con soporte variable recurrirán al valor heredado o inicial, como si usaran la palabra clave unset .

Eso puede parecer confuso al principio, pero hay buenas razones para ello. El primero es técnico: los motores de navegación manejan la sintaxis no válida o desconocida en el "tiempo de análisis" (lo que sucede primero), pero las variables no se resuelven hasta el "tiempo del valor calculado" (lo que sucede más tarde).

  1. En el momento del análisis, las declaraciones con sintaxis no válida se ignoran por completo, recurriendo a declaraciones anteriores. Este es el camino que seguirán los navegadores antiguos. Los navegadores modernos admiten la sintaxis variable, por lo que se descarta la declaración anterior.
  2. En el momento del valor calculado, la variable se compila como no válida, pero es demasiado tarde: la declaración anterior ya se descartó. De acuerdo con la especificación, los valores de variables inválidas se tratan de la misma manera que no unset :

Consulte el Pen [Accesorios personalizados: no válido/no admitido frente a no definido](https://codepen.io/smashingmag/pen/VJMGbJ/) de Miriam Suzanne.

Consulte los accesorios personalizados del lápiz: no válidos/no admitidos frente a no definidos de Miriam Suzanne.
 html { color: red; /* ignored as *invalid syntax* by all browsers */ /* - old browsers: red */ /* - new browsers: red */ color: not a valid color; color: var(not a valid variable name); /* ignored as *invalid syntax* by browsers without var support */ /* valid syntax, but invalid *values* in modern browsers */ /* - old browsers: red */ /* - new browsers: unset (black) */ --invalid-value: not a valid color value; color: var(--undefined-variable); color: var(--invalid-value); }

Esto también es bueno para nosotros como autores, porque nos permite jugar con respaldos más complejos para los navegadores que admiten variables y proporciona respaldos simples para navegadores más antiguos. Aún mejor, eso nos permite usar el estado null / undefined para establecer los parámetros requeridos. Esto se vuelve especialmente importante si queremos convertir una función en un mixin o componente.

"Combinaciones" de propiedades personalizadas

En Sass, las funciones devuelven valores sin procesar, mientras que los mixins generalmente devuelven una salida CSS real con pares de propiedades y valores. Cuando definimos una propiedad --stripes universal, sin aplicarla a ninguna salida visual, el resultado es similar a una función. Podemos hacer que se comporte más como un mixin, definiendo la salida universalmente también:

 * { --stripes: linear-gradient( var(--stripes-angle), powderblue 20%, pink 20% 40%, white 40% 60%, pink 60% 80%, powderblue 80% ); background-image: var(--stripes); }

Mientras --stripes-angle siga siendo inválido o indefinido, el mixin no se compilará y no se aplicará ninguna background-image . Si establecemos un ángulo válido en cualquier elemento, la función calculará y nos dará un fondo:

 div { --stripes-angle: 30deg; /* generates the background */ }

Desafortunadamente, ese valor de parámetro heredará , por lo que la definición actual crea un fondo en el div y todos los descendientes . Para arreglar eso, tenemos que asegurarnos de que el valor --stripes-angle no se herede, dejándolo en la initial (o cualquier valor no válido) en cada elemento. Podemos hacer eso en el mismo selector universal:

Vea el Pen [Accesorios personalizados: Mixin](https://codepen.io/smashingmag/pen/ZdXMJx/) de Miriam Suzanne.

Vea los accesorios personalizados para bolígrafos: Mixin de Miriam Suzanne.
 * { --stripes-angle: initial; --stripes: /* etc… */; background-image: var(--stripes); }

Estilos en línea seguros

En algunos casos, necesitamos que el parámetro se establezca dinámicamente desde fuera de CSS, en función de los datos de un servidor back-end o un marco front-end. Con propiedades personalizadas, podemos definir variables de forma segura en nuestro HTML sin preocuparnos por los problemas habituales de especificidad:

Vea el Pen [Accesorios personalizados: Mixin + Inline Style](https://codepen.io/smashingmag/pen/qzPMPv/) de Miriam Suzanne.

Vea los accesorios personalizados para bolígrafos: Mixin + Inline Style de Miriam Suzanne.
 <div>...</div>

Los estilos en línea tienen una alta especificidad y son muy difíciles de anular, pero con las propiedades personalizadas, tenemos otra opción: ignorarlo. Si establecemos div en background-image: none (por ejemplo), esa variable en línea no tendrá impacto. Para llevarlo aún más lejos, podemos crear una variable intermedia:

 * { --stripes-angle: var(--stripes-angle-dynamic, initial); }

Ahora tenemos la opción de definir --stripes-angle-dynamic en el HTML, o ignorarlo, y configurar --stripes-angle directamente en nuestra hoja de estilo.

Vea el Pen [Accesorios personalizados: Mixin + Inline / Override](https://codepen.io/smashingmag/pen/ZdXMao/) de Miriam Suzanne.

Vea los accesorios personalizados de Pen: Mixin + Inline / Override de Miriam Suzanne.

Valores preestablecidos

Para valores más complejos o patrones comunes que queremos reutilizar, también podemos proporcionar algunas variables preestablecidas para elegir:

 * { --tilt-down: 6deg; --tilt-up: -6deg; }

Y use esos ajustes preestablecidos, en lugar de establecer el valor directamente:

 <div>...</div> 

Vea el Pen [Accesorios personalizados: Mixin + Presets](https://codepen.io/smashingmag/pen/LKemZm/) de Miriam Suzanne.

Vea los Accesorios personalizados para bolígrafos: Mixin + Presets de Miriam Suzanne.

Esto es excelente para crear cuadros y gráficos basados ​​en datos dinámicos, o incluso diseñar un planificador diario.

Consulte el Pen [Gráfico de barras en cuadrícula CSS + variables](https://codepen.io/smashingmag/pen/wLrEyg/) de Miriam Suzanne.

Vea el gráfico Pen Bar en CSS grid + variables por Miriam Suzanne.

Componentes contextuales

También podemos reformular nuestro "mixin" como un "componente" aplicándolo a un selector explícito y haciendo que los parámetros sean opcionales. En lugar de depender de la presencia o ausencia de --stripes-angle para alternar nuestra salida, podemos confiar en la presencia o ausencia de un selector de componentes. Eso nos permite establecer valores alternativos de forma segura:

Vea el Pen [Accesorios personalizados: Componente](https://codepen.io/smashingmag/pen/QXqVmM/) de Miriam Suzanne.

Vea los Accesorios personalizados para bolígrafos: Componente de Miriam Suzanne.
 [data-stripes] { --stripes: linear-gradient( var(--stripes-angle, to right), powderblue 20%, pink 20% 40%, white 40% 60%, pink 60% 80%, powderblue 80% ); background-image: var(--stripes); }

Al colocar el respaldo dentro de la función var() , podemos dejar --stripes-angle sin definir y "libre" para heredar un valor desde fuera del componente. Esta es una excelente manera de exponer ciertos aspectos del estilo de un componente a la entrada contextual. Incluso los estilos de "ámbito" generados por un marco JS (o dentro del ámbito del shadow-DOM, como los iconos SVG) pueden usar este enfoque para exponer parámetros específicos para la influencia externa.

Componentes aislados

Si no queremos exponer el parámetro para la herencia, podemos definir la variable con un valor predeterminado:

 [data-stripes] { --stripes-angle: to right; --stripes: linear-gradient( var(--stripes-angle, to right), powderblue 20%, pink 20% 40%, white 40% 60%, pink 60% 80%, powderblue 80% ); background-image: var(--stripes); }

Estos componentes también funcionarían con una clase o cualquier otro selector válido, pero elegí el atributo de data- para crear un espacio de nombres para cualquier modificador que queramos:

 [data-stripes='vertical'] { --stripes-angle: to bottom; } [data-stripes='horizontal'] { --stripes-angle: to right; } [data-stripes='corners'] { --stripes-angle: to bottom right; } 

Vea el Pen [Accesorios personalizados: componentes aislados](https://codepen.io/smashingmag/pen/agLaGX/) de Miriam Suzanne.

Vea los accesorios personalizados de la pluma: componentes aislados de Miriam Suzanne.

Selectores y Parámetros

A menudo desearía poder usar atributos de datos para establecer una variable, una función compatible con la especificación attr() de CSS3, pero que aún no está implementada en ningún navegador (consulte la pestaña de recursos para ver los problemas vinculados en cada navegador). Eso nos permitiría asociar más estrechamente un selector con un parámetro en particular:

 <div data-stripes="30deg">...</div> /* Part of the CSS3 spec, but not yet supported */ /* attr( , ) */ [data-stripes] { --stripes-angle: attr(data-stripes angle, to right); } <div data-stripes="30deg">...</div> /* Part of the CSS3 spec, but not yet supported */ /* attr( , ) */ [data-stripes] { --stripes-angle: attr(data-stripes angle, to right); } <div data-stripes="30deg">...</div> /* Part of the CSS3 spec, but not yet supported */ /* attr( , ) */ [data-stripes] { --stripes-angle: attr(data-stripes angle, to right); }

Mientras tanto, podemos lograr algo similar usando el atributo de style :

Vea el Pen [Accesorios personalizados: Selectores de estilo](https://codepen.io/smashingmag/pen/PrJdBG/) de Miriam Suzanne.

Vea los accesorios personalizados para bolígrafos: selectores de estilo de Miriam Suzanne.
 <div>...</div> /* The `*=` atttribute selector will match a string anywhere in the attribute */ [style*='--stripes-angle'] { /* Only define the function where we want to call it */ --stripes: linear-gradient(…); }

Este enfoque es más útil cuando queremos incluir otras propiedades además del parámetro que se está configurando. Por ejemplo, establecer un área de cuadrícula también podría agregar relleno y fondo:

 [style*='--grid-area'] { background-color: white; grid-area: var(--grid-area, auto / 1 / auto / -1); padding: 1em; }

Conclusión

Cuando comenzamos a juntar todas estas piezas, queda claro que las propiedades personalizadas van mucho más allá de los casos de uso de variables comunes con los que estamos familiarizados. No solo podemos almacenar valores y aplicarlos a la cascada, sino que podemos usarlos para manipular la cascada de nuevas formas y crear componentes más inteligentes directamente en CSS.

Esto nos exige repensar muchas de las herramientas en las que confiamos en el pasado, desde convenciones de nomenclatura como SMACSS y BEM, hasta estilos de "alcance" y CSS-in-JS. Muchas de esas herramientas ayudan a evitar la especificidad o a administrar estilos dinámicos en otro idioma, casos de uso que ahora podemos abordar directamente con propiedades personalizadas. Los estilos dinámicos que a menudo hemos calculado en JS ahora se pueden manejar al pasar datos sin procesar al CSS.

Al principio, estos cambios pueden verse como "complejidad adicional", ya que no estamos acostumbrados a ver la lógica dentro de CSS. Y, como ocurre con todo el código, el exceso de ingeniería puede ser un peligro real. Pero yo diría que en muchos casos, podemos usar este poder no para agregar complejidad, sino para mover la complejidad fuera de las herramientas y convenciones de terceros, volver al lenguaje central del diseño web y (lo que es más importante) volver al navegador. Si nuestros estilos requieren cálculo, ese cálculo debe vivir dentro de nuestro CSS.

Todas estas ideas se pueden llevar mucho más lejos. Las propiedades personalizadas apenas comienzan a ver una adopción más amplia y solo hemos comenzado a arañar la superficie de lo que es posible. Estoy emocionado de ver a dónde va esto, y qué más se le ocurre a la gente. ¡Divertirse!

Otras lecturas

  • "Es hora de comenzar a usar las propiedades personalizadas de CSS", Serg Hospodarets
  • "Una guía de estrategia para las propiedades personalizadas de CSS", Michael Riethmuller