Cuando chocan Sass y las nuevas funciones CSS

 

 

 


Índice
  1. Los errores
  2. La solución
  3. ¿Pero por qué?

Recientemente, CSS ha agregado muchas características nuevas e interesantes, como propiedades personalizadas y nuevas funciones. Si bien estas cosas pueden hacernos la vida mucho más fácil, también pueden terminar interactuando con preprocesadores, como Sass, de maneras divertidas.

 

Así que esta será una publicación sobre los problemas que he encontrado, cómo los soluciono y por qué todavía encuentro necesario Sass en estos días.

Los errores

Si ha jugado con las nuevas funciones min()y max(), es posible que se haya topado con un mensaje de error como este al trabajar con diferentes unidades: "Unidades incompatibles: vhy em".

Esto se debe a que Sass tiene su propia min()función e ignora la min()función CSS . Además, Sass no puede realizar ningún tipo de cálculo utilizando dos valores con unidades que no tengan una relación fija entre ellos.

Por ejemplo, cmy inlas unidades tienen una relación fija entre ellas, por lo que Sass puede descubrir cuál es el resultado min(20in, 50cm)y no arroja un error cuando intentamos usarlo en nuestro código.

Lo mismo ocurre con otras unidades. Las unidades angulares, por ejemplo, tienen todas una relación fija entre ellas: 1turn, 1rado 1gradsiempre se calculan con los mismos degvalores. Lo mismo ocurre con 1scuál es siempre 1000ms, 1kHzcuál es siempre 1000Hz, 1dppxcuál es siempre 96dpiy 1incuál es siempre 96px. Es por eso que Sass puede convertir entre ellos y mezclarlos en cálculos y funciones internas como su propia min()función.

Pero las cosas se rompen cuando estas unidades no tienen una relación fija entre ellas (como en el caso anterior con las unidades emy vh).

Y no se trata sólo de unidades diferentes. Intentar usarlo calc()en el interior min()también genera un error. Si intento algo como calc(20em + 7px), el error que aparece es " calc(20em + 7px)no es un número para min".

Otro problema surge cuando queremos usar una variable CSS o el resultado de una función matemática CSS (como calc(), min()o max()) en un filtro CSS como invert().

En este caso, nos dicen que “ $color: 'var(--p, 0.85)no es un color para invert”.

 

Lo mismo ocurre con grayscale(): “ $color: ' calc(.2 + var(--d, .3))' no es un color para grayscale.”

opacity()causa el mismo problema: " $color: ' var(--p, 0.8)' no es un color para opacity".

Sin embargo, otras filterfunciones, incluidas sepia(), blur(), drop-shadow(), brightness()y contrast(), hue-rotate()¡todas funcionan bien con variables CSS!

Resulta que lo que está sucediendo es similar al problema min()y max(). Sass no tiene funciones sepia(), blur(), drop-shadow(), brightness(), integradas contrast(), hue-rotate()pero tiene las suyas propias grayscale(), invert()y opacity()funciones, y su primer argumento es un $colorvalor. Como no encuentra ese argumento, arroja un error.

Por la misma razón, también tenemos problemas al intentar utilizar una variable CSS que enumera al menos dos valores hsl()o hsla().

Por otro lado, color: hsl(9, var(--sl, 95%, 65%))es CSS perfectamente válido y funciona bien sin Sass.

rgb()Con las funciones y ocurre exactamente lo mismo rgba().

Además, si importamos Compass e intentamos usar una variable CSS dentro de a linear-gradient()o dentro de a radial-gradient(), obtenemos otro error, aunque usar variables internas conic-gradient()funciona bien (es decir, si el navegador lo admite).

Esto se debe a que Compass viene con linear-gradient()funciones radial-gradient(), pero nunca ha agregado conic-gradient()ninguna.

Los problemas en todos estos casos surgen porque Sass o Compass tienen funciones con nombres idénticos y suponen que esas son las que pretendíamos usar en nuestro código.

¡Maldita sea!

La solución

El truco aquí es recordar que Sass distingue entre mayúsculas y minúsculas, pero CSS no.

Eso significa que podemos escribir Min(20em, 50vh)y Sass no lo reconocerá como su propia min()función. No se generarán errores y seguirá siendo CSS válido que funciona según lo previsto. De manera similar, escribir HSL()/ HSLA()/ RGB()/ RGBA()o Invert()nos permite evitar problemas que vimos anteriormente.

En cuanto a los degradados, normalmente prefiero linear-Gradient()y radial-Gradient()solo porque está más cerca de la versión SVG, pero usar al menos una letra mayúscula funciona bien.

¿Pero por qué?

Casi cada vez que twitteo algo relacionado con Sass, me sermonean sobre cómo no debería usarse ahora que tenemos variables CSS. Pensé en abordar eso y explicar por qué no estoy de acuerdo.

En primer lugar, si bien las variables CSS me parecen inmensamente útiles y las he usado para casi todo durante los últimos tres años, es bueno tener en cuenta que conllevan un costo de rendimiento y que rastrear dónde algo salió mal en un laberinto de calc()cálculos puede ser una tarea complicada. dolor con nuestras DevTools actuales. Intento no abusar de ellos para evitar entrar en un territorio donde las desventajas de usarlos superan los beneficios.

 

En general, si actúa como una constante, no cambia de elemento a elemento o de estado a estado (en cuyo caso las propiedades personalizadas son definitivamente el camino a seguir) ni reduce la cantidad de CSS compilado (resolviendo el problema de repetición). creado por prefijos), entonces usaré una variable Sass.

En segundo lugar, las variables siempre han sido una parte bastante pequeña de por qué uso Sass. Cuando comencé a usar Sass a finales de 2012, era principalmente para bucles, una característica que todavía no tenemos en CSS. Si bien moví algunos de esos bucles a un preprocesador HTML (porque reduce el código generado y evita tener que modificar tanto el HTML como el CSS más adelante), sigo usando bucles Sass en muchos casos, como generar listas de valores, listas de parada dentro de funciones de gradiente, listas de puntos dentro de una función poligonal, listas de transformaciones, etc.

He aquí un ejemplo. Solía ​​generar nelementos HTML con un preprocesador. La elección del preprocesador importa menos, pero aquí usaré Pug.

- let n = 12;while n-- .item

Luego establecería la $nvariable en Sass (y tendría que ser igual a la del HTML) y la recorrería para generar las transformaciones que posicionarían cada elemento:

$n: 12;$ba: 360deg/$n;$d: 2em;.item { position: absolute; top: 50%; left: 50%; margin: -.5*$d; width: $d; height: $d; /* prettifying styles */ @for $i from 0 to $n { :nth-child(#{$i + 1}) { transform: rotate($i*$ba) translate(2*$d) rotate(-$i*$ba); ::before { content: '#{$i}' } } }}

Sin embargo, esto significaba que tendría que cambiar tanto el Pug como el Sass al cambiar la cantidad de elementos, lo que hacía que el código generado fuera muy repetitivo. Recetas faciles y rápidas

Desde entonces, pasé a hacer que Pug genere los índices como propiedades personalizadas y luego los use en la transformdeclaración.

- let n = 12;body(style=`--n: ${n}`) - for(let i = 0; i n; i++) .item(style=`--i: ${i}`)
$d: 2em;.item { position: absolute; top: 50%; left: 50%; margin: -.5*$d; width: $d; height: $d; /* prettifying styles */ --az: calc(var(--i)*1turn/var(--n)); transform: rotate(var(--az)) translate(2*$d) rotate(calc(-1*var(--az))); counter-reset: i var(--i); ::before { content: counter(i) }}

Esto reduce significativamente el código generado.

Sin embargo, aún es necesario realizar un bucle en Sass si quiero generar algo como un arco iris.

@function get-rainbow($n: 12, $sat: 90%, $lum: 65%) { $unit: 360/$n; $s-list: (); @for $i from 0 through $n { $s-list: $s-list, hsl($i*$unit, $sat, $lum) } @return $s-list}html { background: linear-gradient(90deg, get-rainbow()) }

Claro, podría generarlo como una variable de lista desde Pug, pero hacerlo no aprovecha la naturaleza dinámica de las variables CSS y no reduce la cantidad de código que se entrega al navegador, por lo que no obtendré ningún beneficio. fuera de el.

 

Otra gran parte de mi uso de Sass (y Compass) está ligada a funciones matemáticas integradas (como funciones trigonométricas), que ahora forman parte de la especificación CSS, pero que aún no están implementadas en ningún navegador. Sass tampoco viene con estas funciones, pero Compass sí y es por eso que a menudo necesito usar Compass.

Y, claro, podría escribir mis propias funciones en Sass. Recurrí a esto al principio, antes de que Compass admitiera funciones trigonométricas inversas. Realmente los necesitaba, así que escribí el mío basado en la serie de Taylor. Pero Compass proporciona este tipo de funciones hoy en día y son mejores y más eficientes que las mías.

Las funciones matemáticas son extremadamente importantes para mí porque soy técnico, no artista. Los valores en mi CSS generalmente resultan de cálculos matemáticos. No son números mágicos ni algo usado puramente por estética. Un ejemplo es generar listas de puntos de trazados de recorte que crean polígonos regulares o cuasi regulares. Piense en el caso en el que queremos crear cosas como avatares o pegatinas no rectangulares.

Consideremos un polígono regular con vértices en un círculo con un radio 50%del elemento cuadrado del que partimos. Arrastrar el control deslizante en la siguiente demostración nos permite ver dónde se colocan los puntos para diferentes números de vértices:

Poniéndolo en código Sass, tenemos:

@mixin reg-poly($n: 3) { $ba: 360deg/$n; // base angle $p: (); // point coords list, initially empty @for $i from 0 to $n { $ca: $i*$ba; // current angle $x: 50%*(1 + cos($ca)); // x coord of current point $y: 50%*(1 + sin($ca)); // y coord of current point $p: $p, $x $y // add current point coords to point coords list } clip-path: polygon($p) // set clip-path to list of points}

Tenga en cuenta que aquí también estamos haciendo uso de bucles y cosas como condicionales y módulos que son una verdadera molestia cuando se usa CSS sin Sass.

Una versión ligeramente más evolucionada de esto podría implicar rotar el polígono agregando el mismo ángulo de desplazamiento ( $oa) al ángulo de cada vértice. Esto se puede ver en la siguiente demostración. Este ejemplo incluye un mixin de estrellas que funciona de manera similar, excepto que siempre tenemos un número par de vértices y cada vértice con índice impar está situado en un círculo de un radio más pequeño ( $f*50%, donde $fes subunitario):

También podemos tener estrellas gorditas como esta:

O pegatinas con borderpatrones interesantes. En esta demostración en particular, cada pegatina se crea con un único elemento HTML y el borderpatrón se crea con clip-pathbucles y matemáticas en Sass. De hecho, bastante.

Otro ejemplo son estos fondos de tarjetas donde el bucle, la operación de módulo y las funciones exponenciales trabajan juntas para generar las capas de fondo de píxeles difuminados:

Esta demostración también depende en gran medida de las variables CSS.

Luego está el uso de mixins para evitar escribir exactamente las mismas declaraciones una y otra vez al diseñar cosas como entradas de rango. Diferentes navegadores usan diferentes pseudoelementos para diseñar los componentes de dicho control, por lo que para cada componente, tenemos que configurar los estilos que controlan su apariencia en múltiples pseudos.

Lamentablemente, por más tentador que sea poner esto en nuestro CSS:

input::-webkit-slider-runnable-track, input::-moz-range-track, input::-ms-track { /* common styles */ }

…¡no podemos hacerlo porque no funciona! Todo el conjunto de reglas se descarta si no se reconoce siquiera uno de los selectores. Y como ningún navegador reconoce los tres anteriores, los estilos no se aplican en ningún navegador.

Necesitamos tener algo como esto si queremos que se apliquen nuestros estilos:

input::-webkit-slider-runnable-track { /* common styles */ }input::-moz-range-track { /* common styles */ }input::-ms-track { /* common styles */ }

Pero eso puede significar que muchos estilos idénticos se repitan tres veces. Y si queremos cambiar, digamos, el backgroundde la pista, necesitamos cambiarlo en los ::-webkit-slider-runnable-trackestilos, en los ::-moz-range-trackestilos y en los ::-ms-trackestilos.

La única solución sensata que tenemos es utilizar un mixin. Los estilos se repiten en el código compilado porque deben repetirse allí, pero ya no tenemos que escribir lo mismo tres veces.

@mixin track() { /* common styles */ }input { ::-webkit-slider-runnable-track { @include track } ::-moz-range-track { @include track } ::-ms-track { @include track }}

La conclusión es: sí, Sass sigue siendo muy necesario en 2020.






SUSCRÍBETE A NUESTRO BOLETÍN 

No te pierdas de nuestro contenido ni de ninguna de nuestras guías para que puedas avanzar en los juegos que más te gustan.










Al suscribirte, aceptas nuestra política de privacidad y nuestros términos de servicio.






Tal vez te puede interesar:

  1. ¿Cómo se hace el tamaño máximo de fuente en CSS?
  2. Cambiar el tamaño de los valores en pasos en CSS
  3. ¿Qué hace “revertir” en CSS?
  4. CSS4 es una mala idea

Cuando chocan Sass y las nuevas funciones CSS

Cuando chocan Sass y las nuevas funciones CSS

Los erroresLa solución¿Pero por qué?Tal vez te puede interesar:Índice Los errores

programar

es

https://aprendeprogramando.es/static/images/programar-cuando-chocan-sass-y-las-nuevas-funciones-css-1570-0.jpg

2024-06-13

 

Cuando chocan Sass y las nuevas funciones CSS
Cuando chocan Sass y las nuevas funciones CSS

Si crees que alguno de los contenidos (texto, imagenes o multimedia) en esta página infringe tus derechos relativos a propiedad intelectual, marcas registradas o cualquier otro de tus derechos, por favor ponte en contacto con nosotros en el mail [email protected] y retiraremos este contenido inmediatamente

 

 

Update cookies preferences