Less.js: Propiedades personalizadas dentro de funciones integradas como `rgba ()` throw error

Creado en 13 nov. 2016  ·  14Comentarios  ·  Fuente: less/less.js

La sintaxis del contenido de las propiedades personalizadas de CSS es muy permisiva, pero eso causa problemas al usar dichas propiedades dentro de funciones integradas como rgba()

Ejemplo:
Mi proyecto permite al usuario definir el color de acento en el que se basa toda la interfaz de usuario de la aplicación y varios componentes personalizados. Y estoy usando el formato rgb debido a la necesidad de desvanecerse en ciertos lugares y CSS no proporciona nada como fade(<strong i="8">@color</strong>, 50%) en menos. De esa manera puedo hacer rgba( var(--color), 0.5 ) . Esto funciona en Chrome y es compatible con el estándar. Sin embargo, less arroja el siguiente error error evaluation function 'rgba': color functions take numbers as parameters .

Código de ejemplo:

:root {
    --color-accent: 169,57,255;
}
button:hover {
    background-color: rgba(var(--color-accent), 0.2);
    color: rgb(var(--color-accent));
}

Nota: Esta es una biblioteca desplegable y no quiero obligar a los usuarios a agregar otro paso de compilación en su flujo de trabajo solo para construir mi biblioteca menos con sus colores. Es por eso que estoy usando las nuevas y brillantes propiedades personalizadas (y también debido a su capacidad de alcance).

Por cierto: ¿Existe alguna solución temporal que evite un manejo tan estricto y lo construya de todos modos? No es que me falte un corchete en las reglas anidadas.

feature request high priority

Comentario más útil

La sintaxis del contenido de las propiedades personalizadas de CSS es muy permisiva, pero eso causa problemas al usar dichas propiedades dentro de funciones integradas como rgba()

Ejemplo:
Mi proyecto permite al usuario definir el color de acento en el que se basa toda la interfaz de usuario de la aplicación y varios componentes personalizados. Y estoy usando el formato rgb debido a la necesidad de desvanecerse en ciertos lugares y CSS no proporciona nada como fade(<strong i="9">@color</strong>, 50%) en menos. De esa manera puedo hacer rgba( var(--color), 0.5 ) . Esto funciona en Chrome y es compatible con el estándar. Sin embargo, less arroja el siguiente error error evaluation function 'rgba': color functions take numbers as parameters .

Código de ejemplo:

:root {
  --color-accent: 169,57,255;
}
button:hover {
  background-color: rgba(var(--color-accent), 0.2);
  color: rgb(var(--color-accent));
}

Nota: Esta es una biblioteca desplegable y no quiero obligar a los usuarios a agregar otro paso de compilación en su flujo de trabajo solo para construir mi biblioteca menos con sus colores. Es por eso que estoy usando las nuevas y brillantes propiedades personalizadas (y también debido a su capacidad de alcance).

Por cierto: ¿Existe alguna solución temporal que evite un manejo tan estricto y lo construya de todos modos? No es que me falte un corchete en las reglas anidadas.

escribe así ~

:root {
    --color-accent: 169,57,255;
}
button:hover {
    background-color: ~"rgba(var(--color-accent), 0.2)";
    color: ~"rgb(var(--color-accent))";
}

Todos 14 comentarios

Solo escapa .


Puse la etiqueta "Solicitud de función" ya que definitivamente se convierte en un problema cuando las propiedades personalizadas están en TR. Es fácil de solucionar desactivando cualquier detección de errores para los argumentos de las funciones CSS (aunque es bastante triste ya que mata una parte importante del lenguaje, es decir, nunca más encontraremos un error hasta que se depure en un navegador).

Las propiedades personalizadas son compatibles con todos los navegadores excepto IE11. Probablemente llegarán a la corriente principal el próximo año, por lo que creo que el soporte debería implementarse pronto.

Less, AFAIK, tampoco tiene pruebas para la naturaleza extremadamente permisiva de los valores de propiedad personalizados. Pueden contener prácticamente cualquier cosa, incluso punto y coma, siempre y cuando no sean fichas de nivel superior (no contenidas en pares de corchetes o llaves). Ver: https://www.w3.org/TR/css-variables/#syntax

Dado que este cambio requiere una verificación de n-de-argumentos de todos modos (para mantener al menos alguna validación de error dentro de las funciones), también se supone que la implementación rgba más reciente también admite la forma de dos argumentos para valores de color ordinales, p. :

rgba(var(--some), .42); // -> rgba(var(--some), .42)
rgba(#010101, .42); // -> rgba(1, 1, 1, .42)

¿Cómo debemos manejar las propiedades personalizadas en argumentos en general? Técnicamente, puede usar var(--some-property) casi en cualquier lugar, y si Less está tratando de interpretar argumentos para funciones CSS integradas como rgba() , eso es un problema. Aunque no estoy seguro de por qué Less arroja errores de valor estricto para una función CSS incorporada. ¿Solo para apoyar expresiones?

Veo un montón de funciones CSS integradas en https://github.com/less/less.js/blob/master/lib/less/functions/color.js#L34 , y en mi opinión, la mayoría de ellas no deberían estar ahí. Less no es un linter, y esas no son funciones Less. Si el analizador intenta ser muy inteligente en las funciones CSS, fallará. Así que creo que esa es la fuente del problema, que Less actualmente está parcheando funciones de color CSS regulares en lugar de dejarlas pasar.

No estoy seguro de si eso se agregó para navegadores que aún no son compatibles con rgb() rgba() ? Parece que se agregó hace 4 años. ¿Quizás el motivo fue agregar equilibrio a las funciones de color más nuevas que aún no son compatibles con los navegadores? 🤔 @lukeapage , ¿todavía estás por aquí para responder?

Teniendo en cuenta mi comentario en # 3214, para este problema, la solución rápida sería simplemente: "si (nargs <3/4) retrocede a la cadena css (no devolviendo nada)" en las implementaciones de funciones correspondientes.

(Y una solución más estricta es poner cheques para cada argumento en cada función para decidir si es evaluable y devolver un objeto de color o un respaldo de cadena CSS).

Teniendo en cuenta mi comentario en # 3214, para este problema, la solución rápida sería simplemente: "si (nargs <3/4) retrocede a la cadena css (no devolviendo nada)" en las implementaciones de funciones correspondientes.

¿Y un cheque similar por var() ?

darken(rgba(var(--red-value), 2, 3, .4), 5%)

Es decir: deberíamos hacer lo siguiente:

  1. ¿Permitir el paso de funciones si no coinciden con n-args? Supongo que necesitaríamos marcar funciones especialmente ya que no hay nada especial en el registro de funciones (a menos que hagamos algo loco como toString() la función y literalmente contamos argumentos con expresiones regulares; AFAIK, ese es el único tipo de reflexión en JS; tú puede que pueda hacerlo con TypeScript pero eso no nos ayuda)
  2. Lanza un error si se usa una función que no coincide en otra evaluación de la función Less.

Este es un problema interesante porque la introducción de propiedades personalizadas ha hecho que las funciones CSS no se puedan resolver en tiempo de compilación. Hasta cierto punto, podemos estar al final de una era de preprocesamiento estático. Pero esa es una discusión completamente diferente.

Este es un problema interesante porque la introducción de propiedades personalizadas ha hecho que las funciones CSS no se puedan resolver en tiempo de compilación.

Realmente nada nuevo. Toda la facilidad necesaria para manejar esto con Less está ahí desde su v1.x - ver más abajo. El único desafío es codificarlo de una manera que no se hinche.

Supongo que necesitaríamos marcar funciones especialmente, ya que no hay nada especial en el registro de funciones.

No, las funciones deberían devolver undefined (o null ) si descubren que no pueden evaluar sus argumentos: así (a menos que también detecten que los argumentos son 100% erráticos y es mejor desencadenar un error). .
Y el valor de retorno indefinido hace que el evaluador de funciones recurra a la representación de cadena inicial: Demo .

Y un cheque similar por var()

Además, no, no es necesario verificar var ni nada específico (básicamente cosas desconocidas de un futuro CSS). Ese es el punto. El código debe verificar lo que es posible evaluar (cosas conocidas) en lugar de lo que no es posible evaluar (incógnitas).
(aunque los detalles pueden variar dependiendo de la función específica, eso no es tan importante).


Por cierto, observe que --var también es una función Less incorporada (así como cualquier cosa ident(...) ) que simplemente no se implementa explícitamente (por lo tanto, simplemente recurre a la representación de cadena propia ) porque no es necesario. Pero un complemento (por ejemplo) puede anularlo con su propia implementación que puede devolver un valor potencialmente evaluable.

@ seven-phase-max Oh, de acuerdo, ¿entonces crees que la solución simple es que estas funciones CSS / Less devuelvan undefined en lugar de arrojar un error (para renderizar como están)? Eso parece razonable, entonces si la función no. 2 (como darken() ) no puede interpretar un argumento (¿que en este punto sería evaluado a un valor anónimo rgba() ?), Todavía debería lanzar?

Discutiendo conmigo mismo:

Además, no, no hay necesidad de verificar var() ni nada específico (básicamente cosas desconocidas de un futuro CSS).

Por otro lado, no sería un problema (e incluso tentador) detectar var específicamente para que la función pueda distinguir entre rgba(var(...), ...) y rgba(foo, ...) y aún así desencadenar un error para los últimos, pero eso significaría que surgiría un problema similar cada vez que agreguen algo nuevo a CSS.
(Ambas variantes están bien, supongo, y se trata más de encontrar el equilibrio y / o predecir la menor carga para los mantenedores ...).

@ matthew-dean

Eso parece razonable, entonces si la función no. 2 (como darken ()) no puede interpretar un argumento (¿que en este punto sería evaluado a un valor anónimo rgba ()?), ¿Todavía debería lanzar?

Sí, exactamente, ni siquiera necesitamos ningún código nuevo para esto (aunque idealmente ellos (funciones como darken ) deberían tener mensajes de error más amigables en este caso porque los mensajes actuales de "a.toHSL is not a function" son bastante confuso).

Bueno, la otra cosa que no se menciona es que los navegadores tratan algo como rgba(calc(1),1,1) como válido (tenga en cuenta tanto el cálculo como los argumentos 3 frente a 4), por lo que probablemente no deberíamos ser demasiado inteligentes al respecto. Me gusta la idea de simplemente generar como es como regla general, si es posible.

Sí, esto es lo que quiero decir con

El código debe verificar lo que es posible evaluar (cosas conocidas) en lugar de lo que no es posible evaluar (incógnitas).

Los únicos argumentos válidos para Less rgba son un número o un objeto de color (si también consideramos las formas "neo" - "CSS4" como rgba(#123, .42) ).
Cualquier otra cosa es un error o un valor CSS (desconocido pero potencialmente válido).

La sintaxis del contenido de las propiedades personalizadas de CSS es muy permisiva, pero eso causa problemas al usar dichas propiedades dentro de funciones integradas como rgba()

Ejemplo:
Mi proyecto permite al usuario definir el color de acento en el que se basa toda la interfaz de usuario de la aplicación y varios componentes personalizados. Y estoy usando el formato rgb debido a la necesidad de desvanecerse en ciertos lugares y CSS no proporciona nada como fade(<strong i="9">@color</strong>, 50%) en menos. De esa manera puedo hacer rgba( var(--color), 0.5 ) . Esto funciona en Chrome y es compatible con el estándar. Sin embargo, less arroja el siguiente error error evaluation function 'rgba': color functions take numbers as parameters .

Código de ejemplo:

:root {
  --color-accent: 169,57,255;
}
button:hover {
  background-color: rgba(var(--color-accent), 0.2);
  color: rgb(var(--color-accent));
}

Nota: Esta es una biblioteca desplegable y no quiero obligar a los usuarios a agregar otro paso de compilación en su flujo de trabajo solo para construir mi biblioteca menos con sus colores. Es por eso que estoy usando las nuevas y brillantes propiedades personalizadas (y también debido a su capacidad de alcance).

Por cierto: ¿Existe alguna solución temporal que evite un manejo tan estricto y lo construya de todos modos? No es que me falte un corchete en las reglas anidadas.

escribe así ~

:root {
    --color-accent: 169,57,255;
}
button:hover {
    background-color: ~"rgba(var(--color-accent), 0.2)";
    color: ~"rgb(var(--color-accent))";
}

@weivea En la última versión de Less 3.x, esto no es necesario, simplemente escriba rgba(var(--color-accent))

¿Fue útil esta página
0 / 5 - 0 calificaciones