Less.js: Cómo manejar las matemáticas

Creado en 17 feb. 2014  ·  102Comentarios  ·  Fuente: less/less.js

  1. Nos decidimos por las matemáticas estrictas en el futuro, pero existe una inquietud generalizada por forzar () en cada cálculo
  2. No creo que queramos cambiar las cosas de forma masiva o volver a la mesa de dibujo

Ver # 1872

¿Posibilidad de agregar otro caso para calc que, al igual que la fuente, con el modo estricto desactivado, esencialmente activa el modo estricto para una regla? ¿Demasiadas excepciones en el futuro?

@ siete-fases-max:
Bueno, hay muchas otras posibilidades, por ejemplo, ./ o requerir parens para la división (por ejemplo, 1/2 -> 1/2 pero (1/2) -> 0.5 ) etc ...
Además, los "casos especiales" (por ejemplo, propiedades en las que x/y pueden aparecer como abreviatura) no son tan raros (comienzan en padding / margin y terminan en background / border-radius y eventualmente puede haber más ) por lo que simplemente no podemos codificarlos todos como se hizo por font (y por eso creo que la fuente actual es simplemente un kludge temporal y bastante sucio que idealmente debería eliminarse también).

feature request high priority

Comentario más útil

Para simplificar / reformular la propuesta , los cambios matemáticos serían los siguientes

  1. La suma y la resta solo se calcularían en unidades similares. por ejemplo, 1px + 2px = 3px , 1px + 1vh = 1px + 1vh
  2. La división y la multiplicación solo se calcularían con divisores / multiplicadores sin unidades. por ejemplo, 10px/2 = 5px , 10px/5px = 10px/5px
  3. Las relaciones de valor sin unidades se tratarían de manera similar a # 2. por ejemplo, 1/3 = 1/3
  4. Para simplificar, las expresiones con subexpresiones parcialmente inválidas pueden tratarse como una expresión matemática inválida y producirse tal cual. por ejemplo, 1px + 2vh / 2 = 1px + 2vh / 2

Esta propuesta resuelve lo siguiente (de este hilo):

  • font: 10px/5px y sintaxis similar (proporción) (sin cálculo)
  • calc(100vh - 30px) (sin cálculo)
  • lost-column: 1/3 y una sintaxis de proporción personalizada similar (sin cálculo)

Al mismo tiempo, estos cambios preservarían el 99% del uso típico de Menos matemáticas. Además, las funciones existentes unit() y convert() permiten a los usuarios convertir valores en unidades compatibles para matemáticas.

Todos 102 comentarios

No creo que queramos cambiar las cosas de forma masiva o volver a la mesa de dibujo

Sí, sugerí comenzar esto solo porque _si_ queremos algunas matemáticas estrictas "predeterminadas" en 3.0 tendremos que inventar algo menos pesado que el actual (y la posibilidad de solucionar todos los problemas sin introducir ningún --alt-strict-math opción font ...).

No me había dado cuenta de que está creciendo

https://developer.mozilla.org/en-US/docs/Web/CSS/border-radius

:(

Creo que en este momento estoy a favor de expandir inicialmente las matemáticas estrictas para ser

  • Apagado
  • División
  • Sobre

y luego para 2.0.0 configurando el valor predeterminado para ser División

Entonces..

Consultas de medios: si está desactivado, cambie a la división para los subnodos
Fuente: si está desactivado, cambie a división para subnodo
calc (- si está desactivado o dividido, cambie a activado para subnodos

https://developer.mozilla.org/en-US/docs/Web/CSS/border-radius

Sí, creo que están a favor de permitir "valores abreviados" (es decir, x/y ) en _cualquier_ "propiedad abreviada" ...

Otra opción ... procesar llamadas a calc pero solo donde las unidades lo permitan, por ejemplo
calc (1% + 2%) => 3%
calc (100% - 10 px) => sin cambios

Esto arreglará calc pero no arreglará # 1627 y cosas relacionadas.
Quiero decir que sí, calc(100% - 10 px) => unchanged podría ser una solución para calc pero esto no cancela la necesidad de una solución less-heavy-than-parens-everywhere .

Si se están revisando las matemáticas estrictas, me gustaría sugerir que las funciones Less como percentage() no requieran paréntesis adicionales dentro de ellas. Con las matemáticas estrictas activadas, debes envolver dos veces el argumento. Esto reduciría en gran medida la posibilidad de confusión y errores difíciles de encontrar, ya que tanto percentage(16 / 17) como percentage((16 / 17)) serían válidos.

@calvinjuarez V2 proporciona un subsistema de complementos donde un complemento puede agregar una cantidad arbitraria de funciones al entorno y, en este sentido, el núcleo no podrá decidir si dicha función incorporada espera un valor único o una expresión, es decir, es permitido aceptar 16/17 , y luego evaluar 16/17 _antes_ de que se pase a una función sería incorrecto (bueno, hablando en términos generales, es un poco más complicado que eso internamente).

En ese contexto, ./ change parece ser mi favorito, aunque entiendo que sería un cambio muy dramático (si se compara con (/) , sin contar también requiere un espacio en blanco antes de . , por ejemplo, 16 ./17 y no 16./17 , hmm).

Otra cosa en la que menos actualmente rompe el CSS válido es la abreviatura de fondo:

background: url(image.png) 50%/300px no-repeat;

Creo que en este momento estoy a favor de expandir inicialmente las matemáticas estrictas para ser

Apagado
División
Sobre
y luego para 2.0.0 configurando el valor predeterminado para ser División

Lo siento, no respondí a esto antes de que se lanzara 2.0. Creo que es un buen instinto. Los operadores de división desnudos simplemente entran en conflicto con demasiado CSS, y entrarán en conflicto cada vez más a medida que la gente utilice más funciones de CSS3. Y entiendo el rechazo de la gente para no requerir paréntesis para todas las matemáticas, ya que no es necesario en muchos casos.

@ siete-fases-max

está permitido aceptar 16/17, y luego evaluar 16/17 antes de pasarlo a una función sería incorrecto

Estrictamente hablando, sí, eso es absolutamente correcto. Esto no debe evaluarse ANTES de que llegue a la función, especialmente para una personalizada. Sin embargo, creo que sería inteligente permitir que las funciones opten por procesar argumentos como este, si tiene sentido. Entonces, el porcentaje recibiría 16/17 como un argumento de texto, y luego la función de porcentaje podría realizar una llamada a alguna función auxiliar para ver si el texto es matemático. En el caso del porcentaje, el argumento no es ambiguo. Una declaración CSS3 no es válida aquí. Entonces, otras funciones definidas por el usuario podrían operar de la misma manera: opte por evaluar argumentos para ecuaciones matemáticas válidas. Por lo tanto, no es necesariamente cierto que las matemáticas estrictas "fuercen" un paréntesis doble en este caso. Creo que sugerir que provoca cierto rechazo a la idea de la matemática estricta, debe, como necesidad, ser detallada en todos los casos.

Nuestras opciones de --math podrían ser más como:

  • Siempre
  • División (predeterminado)
  • Estricto

Entonces, podríamos desaprobar --strict-math = true y convertirlo en un alias para --math = strict

Sin embargo, creo que sería inteligente permitir que las funciones opten por procesar argumentos como este, si tiene sentido.

Ya están permitidos (solo pruebe cómo funcionan percentage(16 / 17) y percentage((16 / 17)) con --strict-math=on ).
Aunque ninguna de las funciones usa:

y luego la función de porcentaje podría hacer una llamada a alguna función auxiliar para ver si el texto es matemático.

simplemente porque de esta manera cada función tendría que tener esas ~ 20 líneas adicionales de ese extra-helpers-conversion-arg-check-smart-arg-handling-stuff mientras que el código de la propia función es solo una (!) línea en la mayoría de los casos.

¿Cada función tiene que tener 20 líneas extra? ¿Cómo te imaginas?

Si el porcentaje ya funciona con un solo paréntesis en matemáticas estrictas, entonces no entiendo el problema de @calvinjuarez . Parecía insinuar en su respuesta que no se podía conseguir un solo paréntesis.

¿Cada función debe tener 20 líneas adicionales? ¿Cómo te imaginas?

Eso es solo una exageración típica de: tal vez 5, tal vez 10, tal vez 20 ... ¿A quién le importarían los números exactos si la proporción de código real / código auxiliar -> 0 ? (Tomando un enfoque pragmático, me detendría en percentage(16 / 17) simplemente arrojando un error en lugar de producir NaN% (como ahora), y no intentar realizar ninguna conversión ... Aunque incluso de esta manera sigue siendo 4 líneas adicionales de código, bueno, menos o más aceptable, supongo :)

Mi respuesta inicial implicaba que él asume que esta conversión 16/17 -> (16/17) será realizada implícitamente por el propio compilador (y no por la función).


Hablando de opciones. En un mundo perfecto, soñaría que no hay opciones para esto (es decir, debería ser el único y el resto para ser marcado como obsoleto y eventualmente eliminado) ... Todas estas opciones adicionales hacen que la base de código no -mantenible ... incluso para una pequeña corrección / cambio de una sola línea, el número de casos extremos que tiene que predecir y las pruebas que necesita realizar crece exponencialmente ... (casi sin motivo).

Estaba pensando que sería algo como:

percentage: function(...) {
  Helper.convertMath(arguments);  // a function that doesn't need it doesn't call it
  // ... the rest
} 

Hablando de opciones. En un mundo perfecto, soñaría que no hay opciones para esto.

Estoy de acuerdo. Pero necesitaremos las opciones a corto plazo. Especialmente si nos estamos desviando de las matemáticas estrictas y el comportamiento heredado. Ambos pueden marcarse como obsoletos si perfeccionamos una opción de "matemáticas más inteligentes".

Helper.convertMath(arguments);

arguments es demasiado optimista.
En el mejor de los casos (contando no solo percentage , que de todos modos es algo inútil , sino cualquier otra función que espere un argumento numérico), un requisito mínimo sería:

some: function(a, b, c) { 
    a = convert2number(a, "Error message when fails"); 
    // b is not a number for example
    c = convert2number(c, "Error message when fails"); 
} 

Pero ese no era mi punto realmente, lo que quise decir es probablemente algo como: si bien esto siempre es / fue posible, nadie se molesta en escribir ese código ... (con algunas excepciones limitadas como ) ...

Sí, te entiendo.

percentage(16 / 17) solo arroja un error

sería una mejora, sin duda. (No puedo pensar en ningún momento en el que NaN% sea ​​un resultado útil).

En cuanto a qué funciones intentarían ser inteligentes con sus argumentos, no hay razón para intentar anticipar todo. Una función auxiliar como sugiere @ matthew-dean podría implementarse de manera bastante simple a medida que se realizan y se discuten las solicitudes de funciones para que funciones específicas sean más inteligentes.

De hecho, desde el principio, diría que solo las funciones matemáticas deberían ser inteligentes sobre sus argumentos.

Editar: en realidad, cada vez que se pasa una función matemática solo un argumento.

¿Cuál es el estado de esto? Recibimos quejas de que LESS intenta analizar propiedades CSS inválidas como matemáticas. por ejemplo, lost-column: 1/3; descansos.

También parece que http://www.w3.org/TR/css-grid-1/#grid -template-rowcol no funcionará con MENOS.

¿Alguien puede parchear esto para que, si alguien quiere explícitamente usar MENOS para hacer la división en una propiedad, necesita envolverlo en parens o algo así?

@corysimmons ¿No preguntaste esto en el número 2769 y obtuviste una respuesta? o_O

Una cosa que no discutimos cuando esto sucedió por primera vez. Parece que el único conflicto matemático real es la división. Y la división es esencialmente un problema porque esencialmente estamos "reutilizando" un carácter de "separación" de CSS.

En lugar de tratar de "envolver" la división de varias formas, o envolver todas las matemáticas (como nuestra primera solución a este problema), me pregunto por qué nunca hablamos de lo obvio: _no reutilizar un operador existente en primer lugar_, especialmente cuando tan claramente a) hace que el código Less sea ambiguo, b) causa conflicto.

Después de haber tenido tiempo de digerir esto, poniendo las matemáticas entre paréntesis, incluso si es solo una división, _todavía_ causa ambigüedad para los casos en los que las matemáticas ya están entre paréntesis. (Lo que también podría haber significado que el paréntesis fue una elección incorrecta de "envoltorio matemático").

Entonces, ¿por qué no desaprobar / como operador de división? Sé que es un símbolo de división común, pero hay otras compensaciones de sintaxis que Less ha hecho para extender CSS. Y ahora tengo claro que básicamente estamos tratando de solucionar un problema creado por Less en primer lugar mediante el uso de una barra oblicua. Estamos creando ambigüedad y luego intentamos revertir la ambigüedad.

Para ser justos, los otros símbolos matemáticos están todos reutilizados en otras partes de CSS, es solo que su uso en matemáticas no causa ninguna ambigüedad.

Iba a proponer algunas ideas, pero, he aquí, ya existen caracteres alternativos estándar a la división. Aparte de ÷ , que no está en el teclado, encontré esto:

El signo de división también es matemáticamente equivalente al símbolo de razón, habitualmente denotado por dos puntos (:) y se lee "es a". Por lo tanto, para cualquier número real x y cualquier número real distinto de cero y, esta ecuación se cumple:

x ÷ y = x: y

En otras palabras:

lost-column: 1/3;   //  value
lost-column: 1:3;   // division 

Sé que se necesitarían algunos ajustes del analizador sintáctico para usar dos puntos en matemáticas, pero aparentemente es matemáticamente correcto. No puedo pensar en otros símbolos que podrían ser mejores sustitutos. ¿Quizás | como segunda opción? Sin embargo, sería más arbitrario.

¿Pensamientos?

_Alternativamente_, aún podríamos admitir el símbolo de división entre paréntesis y / o corchetes, como en:

lost-column: 1/3;   //  value
lost-column: 1:3;   // division 
lost-column: (1/3);
lost-column: [1/3];

Sí, es por eso que inicialmente comencé con ./ (inspirado en el operador vector-div de Matlab, son dos símbolos, pero visualmente es probablemente el menos pesado debido al punto liviano, aunque en el contexto de Menos estropear el punto no es una idea brillante).
: - Esto volverá a empujar margaritas, este símbolo se usa en demasiados contextos CSS. De hecho, ya existe una sintaxis conflictiva:

.foo(<strong i="9">@a</strong>: 1, <strong i="10">@b</strong>: 2) {
  result: <strong i="11">@a</strong> @b;  
}

bar {
    <strong i="12">@b</strong>: 4;
    .foo(<strong i="13">@b</strong>:3); // would mean both @second-parameter:3 and 4/3
}

@ seven-phase-max Ah, sí, maldita sea. SI SOLO LOS TECLADOS FUE MAS GRANDE. Sí, parece inevitable una secuencia de dos caracteres para la división. Había pasado mucho tiempo desde que leí todo el hilo, así que me olvidé de eso. ./ Realmente no está mal. Si tanto tú como @lukeapage están a bordo, eso no sería un mal compromiso. Tal vez lo pasemos a la etapa de propuesta y veamos si hay alguna objeción.

Volviendo a leer, hasta este punto:

sin contar, también requiere un espacio en blanco antes de . , por ejemplo, 16 ./17 y no 16./17

No estoy seguro de estar de acuerdo. Sí, 16. es un número válido, técnicamente, pero sería extraño que alguien lo escribiera de esa manera. Creo que no importa cómo lo escribas, con espacios en blanco o no, debería dividir 16 entre 17.

No habrá una opción perfecta, pero creo que es mejor que a) Usar / para la división de forma predeterminada, b) siempre requiriendo paréntesis. (A pesar de mis posiciones en el pasado, también he llegado a un sí, eso es un poco molesto, especialmente entre otros paréntesis. Y especialmente porque solo es necesario debido a la división, que yo sepa. ¿Sí?)

Creo que no importa cómo lo escribas, con espacios en blanco o no, debería dividir 16 entre 17.

Sí, claro.
Aunque lo pienso más, espero que ./ ponga algunos trucos adicionales al analizador (el análisis de números necesitará una mirada adicional hacia adelante para detenerse antes de ./ mientras que actualmente siempre come terminando . ).

Y especialmente porque solo se requiere debido a la división, que yo sepa. ¿Sí?)

Sí exactamente. Sin contar el código dentro de calc , pero para este supongo que la solución sugerida por @lukepage debería funcionar.

(Técnicamente, en el futuro podría haber alguna ambigüedad adicional para +, -, * si se mantienen en la sintaxis de sus funciones de manipulación de color CSS, pero esto no debería ser demasiado dramático ya que los valores allí tienen la forma * 20% (por lo tanto claramente se pueden detectar como algunos expr no evaluados menos). Después de todas esas diversiones, de todos modos necesitará algunos cambios de análisis, ya que los valores actuales como (* 20%) causan un error de análisis).

Quizás ... hemos estado haciendo todo mal sobre esto. (Definitivamente incluyéndome en eso, ya que fui un ávido partidario inicial de la función de "matemáticas estrictas").

Estamos tratando de hacer que las matemáticas funcionen universalmente, pero ... realmente no es necesario. Es decir, estamos tratando de hacer matemáticas en los casos en que debería ser obvio que no se deberían realizar matemáticas.

El ejemplo calc(100% - 10px) es el más obvio. No hay ningún cálculo de Less que pueda / deba realizarse a menos que lancemos unidades, lo cual estoy de acuerdo en que Less debería dejar de hacer, de forma predeterminada. 1

Veamos la propiedad abreviada de fuente utilizada como ejemplo.

font: italic small-caps normal 13px/150% Arial, Helvetica, sans-serif;
font: italic bold 12px/30px Georgia, serif;

La solución actual para esto es convertir strict-math: on para la propiedad de fuente. Pero ... ¿por qué Less debería hacer cálculos en primer lugar? Claro, 13px/150% es una declaración válida en matemáticas, pero ¿es razonable tratarla como válida en Less? 12px/30px usted _podría_ tratar como una declaración matemática válida, pero ¿debería hacerlo? 2

Es decir: en Less, las operaciones matemáticas en unidades deben realizarse mediante _ enteros_ y _floats_, no unidades. Los estamos tratando como declaraciones matemáticas válidas, como si las personas realmente estuvieran escribiendo sus matemáticas de esta manera. Pero no veo cómo es posible que eso sea cierto.

Es decir, es razonable pedirle a alguien que escriba 13px/150% como 13px/1.5 . E incluso ignorando el hecho de que 12px/30px no tendría sentido como operación matemática, no necesitamos saber que no lo es, y no necesitamos hacer una lista blanca de font . Si un autor Less estuviera haciendo una operación matemática, razonablemente lo estaría escribiendo 12px/30 . Eso no solo sería razonable, es una probabilidad extremadamente alta que esa sea la forma en que lo están escribiendo en primer lugar.

Es un lugar común para mí escribir un mixin o incluso usar algo como esto dentro de un solo bloque:

width: <strong i="5">@size</strong> / 2;
height: <strong i="6">@size</strong> / 2;

¿Por qué lo escribiría de esta manera? ¿Alguien lo está escribiendo de esta manera?

width: <strong i="10">@size</strong> / 2px;
height: <strong i="11">@size</strong> / 2px;

La operación _sort of_ tiene sentido si @size es una unidad px , pero, independientemente, tiene menos sentido en el ámbito de LESS / CSS tratar de hacer matemáticas en el último caso cuando el divisor es un valor con una unidad. El segundo no parece matemático. Parece un valor CSS.

Si dejamos de hacer operaciones matemáticas para la multiplicación o división (solo la división necesaria para la ambigüedad, pero la multiplicación también para la coherencia lógica) cuando el multiplicador o divisor es un valor con una unidad, creo que este problema desaparecería en gran medida. Por el contrario, las unidades _son_ lógicas para la suma y la resta, pero probablemente no sea necesario que sea necesario (que es lo que es ahora).

<strong i="18">@pad</strong>: 2px;
width: 10px + @pad; 

Pero al sumar / restar un valor con unidad a otro con una unidad diferente, Less debería dejarlo solo.

<strong i="22">@val1</strong>: 100%;
<strong i="23">@val2</strong>: 10px;
width: calc(<strong i="24">@val1</strong> - @val2);

// output
width: calc(100% - 10px);

Requerir unidades coincidentes para sumar / restar (o entero / flotante) y requerir números enteros / flotantes en operaciones matemáticas contra unidades (sin unidades multiplicadas / divididas por unidades) resolvería el 99% de las ambigüedades y aún permitiría operaciones matemáticas válidas sin ningún símbolo nuevo .

Por ejemplo, según esas reglas, la taquigrafía de fondo estaría bien:

background: no-repeat 10px 10px/80% url("../img/image.png");

% es una unidad CSS. px es una unidad CSS diferente. Por lo tanto, nada de matemáticas. La excepción especial sería un cero.

background: no-repeat 0 0/80% url("../img/image.png");

Si alguien parece estar dividiendo cero por otro número, o dividiendo un número por cero, creo que podemos generar con seguridad tal como está.

Radio de borde, lo mismo:

border-radius: 30% / 20%;

Menos lo daría un pase. Si alguien tuviera la intención de hacer matemáticas, la forma adecuada de escribirlo sería:

border-radius: 30% / 0.2;

Lo bueno es que, al hacer estas distinciones, debería ser obvio que una operación matemática _no_ puede ser un valor CSS, ya que, como en el ejemplo border-radius , un valor CSS válido requeriría unidades en ambos lados. No habría superposición / ambigüedad.

Exceeeept un caso en el que puedo pensar, y puede haber otros:

font: 10px/1.5;

Puede (y normalmente debería) representar la altura de la línea como solo un número. (Pero probablemente tampoco deberíamos usar abreviaturas de fuentes). Pero si lo hemos reducido a un caso, eso es bastante bueno. Activar matemáticas estrictas para font (excepto para las funciones internas dentro del valor de la fuente) es una buena solución. (No estoy seguro de que no haya uno mejor, pero funciona). Y aún así, es la solución con el menor daño, ya que esos valores abreviados de fuentes generalmente aparecen en bibliotecas de estilo de interfaz de usuario importadas, restablecimientos de CSS u hojas de estilo de fuente personalizadas.

Entonces, todavía hay un uso para las matemáticas estrictas, pero creo que con estos cambios, menos, y tal vez no sean necesarios como una opción en el futuro.

Doy la bienvenida a las respuestas / comentarios de la galería.

1 _Me di cuenta de que debería dejar en claro que los comentarios de @lukeapage y el enlace de @ seven-phase-max son lo que me hizo pensar en esta dirección, para dar un paso más.
2 _Como descubrí mientras miraba ejemplos, activar las matemáticas estrictas para la fuente puede ser una solución inevitable, pero creo que se aplica el resto de la lógica.

Solo para un contexto histórico, es importante tener en cuenta que las unidades de lanzamiento cuando Less.js se lanzó por primera vez no fue un gran problema. calc() no se implementó y background y border-radius no tenían barras como valores válidos. Creo que font fue el único lugar que hizo tropezar las cosas (que, irónicamente, aún puede ser el caso).

Mi única preocupación es el lado de la implementación, por ejemplo: para calc(4px + 2rem + 20%) (las unidades reales no importan), la primera adición da como resultado un resultado que ya no es numérico, por lo que el controlador de la segunda adición no puede distinguir su entrada de cualquier instrucción not-a-number + 20% donde debería arrojar un error. Probablemente no sea un gran problema (se puede resolver colocando indicadores de tipo / tipo adicionales), pero aún necesita algo de investigación.

Y la otra preocupación es ehm, ¿no estás seguro, "redabilidad"? Es decir, mientras que para los números explícitos el resultado se ve muy claro, para las variables comienza a verse bastante ambiguo, por ejemplo: border-radius: 10px <strong i="8">@a</strong> / <strong i="9">@b</strong> 30px; : nunca se sabe lo que se supone que significa esto hasta que ve @a y @b definiciones.

Y sí, font sigue siendo un problema (es probable que otras propiedades abreviadas parezcan usar unidades en ambos lados, pero nuevamente nunca sabemos qué se les ocurre a continuación (también contando cosas como # 2769) ... A algunas cosas más como font y comenzará a verse roto nuevamente).

PD: Un problema más (quizás una pequeña regresión). Hay valores como:

border-radius: 10px / auto;
border-radius: 1px inherit / 2px;
background: ... center / 80% ...;
// etc.

Es decir, para que todo funcione, tendremos que deshabilitar cualquier error de operando div incompatible actual para que cualquier foo/bar , 1x/bar y foo/1x puedan pasar sin error.

Mi única preocupación es el lado de la implementación, por ejemplo: para calc (4px + 2rem + 20%) (las unidades reales no importan)

Esto es lo que estoy diciendo. Las unidades reales deberían importar. Menos debería dejar eso en paz, independientemente. 4px + 2rem tiene significado en el navegador, pero no tiene sentido en Less. No hay razón para intentar agregarlo cuando no tiene sentido y causa estos problemas adicionales.

por ejemplo: border-radius: 10px <strong i="10">@a</strong> / <strong i="11">@b</strong> 30px ; - nunca se sabe lo que se supone que significa esto hasta que ve las definiciones @a y @b .

Este es un caso en el que no podemos guardar el autor del estilo de sí mismo (lo mismo con el primer ejemplo, si alguien realmente intentaba agregar rems a los píxeles por alguna razón). Estoy seguro de que hay todo tipo de ejemplos existentes en los que alguien podría escribir su código LESS para ser confuso de seguir. Eso existe en cualquier parte.

Con estas reglas matemáticas que propongo, considere:
calc(4px + 2rem - 2px)

Menos podría / calcularía eso como calc(2px + 2rem) , que en realidad está perfectamente bien, y en realidad es un valor de salida correcto. En este momento, Less lo calcula como calc(4px) , que no es una respuesta correcta ni útil. (Sí, actualmente es correcto si descartamos unidades, pero las unidades no son insignificantes y, excepto en algunos casos, no son interoperables). Less calcula 2px + 100% como 102px , como si hubiera algún valor en ese resultado, cuando nadie posiblemente querría eso como resultado.

Para que todo funcione, tendremos que deshabilitar cualquier error de operando div incompatible actual para que cualquier foo / bar, 1x / bar y foo / 1x puedan pasar sin un error.

Creo que en realidad es la forma más sana de tratarlo. Funciones similares, si no hay un resultado Menos, entonces debería pasar. Dado que / es un separador válido para más de un valor de propiedad, Less no puede saber que _no_ es válido, a menos que agreguemos valores en la lista blanca para propiedades particulares. (No.) En ese momento, el resultado no es trágico. Si un valor de transferencia no es válido en el navegador, es visualmente evidente. Parece mejor intentar pasar el valor al navegador en caso de que sea válido, que lanzar un error porque Less no está seguro.

Menos podría / calcularía eso como calc (2px + 2rem)

Me temo que nunca lo hará, ya que esto requerirá un nuevo controlador de expresión de optimización que sería excesivo (básicamente 4px + 2rem - 2px se almacena en el árbol como (4px + 2rem) - 2px para obtener 2px + 2rem tiene que ser un motor de reordenamiento para probar todos los barajados válidos (trivial en este caso particular, pero se vuelve bastante complejo para más operandos / operadores). Pero no importa, dejar 4px + 2rem - 2px tal cual está bien (después todo si lo hace 4px - 2px + 2rem está optimizado).

Pero lo que realmente quise decir con ese comentario es algo similar a:

para que cualquier foo / bar, 1x / bar y foo / 1x puedan pasar sin un error.

Es decir, (4px + 2rem) - 2px para el expr.evaluator sería similar a foo + 2px , por lo que, para que funcione, tampoco debería generar errores para ese tipo de cosas.
En realidad, probé foo/bar, 1x/bar, foo/1x y ya pasaron sin errores (extraño, pensé que arrojaban), pero otros operadores dan como resultado todo tipo de cosas extrañas (aunque nada realmente crítico, solo es cuestión de arreglar cada caso uno a uno).

Me temo que nunca lo hará, ya que esto requerirá un nuevo controlador de expresión de optimización que sería excesivo (básicamente 4px + 2rem - 2px se almacena en el árbol como (4px + 2rem) - 2px, por lo que para obtener 2px + 2rem tiene para ser un motor de reordenamiento para probar todos los barajados válidos (trivial en este caso particular pero que se vuelve bastante complejo para más operandos / operadores).

¿Por qué barajar? Aplana los operadores en el mismo nivel de precedencia (por lo que el árbol es Sum(4px, 2rem, -2px) ), recopila términos con unidades compatibles (tal vez normalizando las unidades de antemano) y simplifica cada parte. Es álgebra simbólica, donde las unidades se tratan como variables independientes.

Me gustaría escribirlo yo mismo, pero hay muchas bibliotecas que probablemente estén mejor probadas y tengan más probabilidades de estar completas. Apostaría a que algunos compiladores de optimización de código abierto escritos en Javascript tienen tales subsistemas de simplificación.

El punto es que, si bien este no es un problema fácil de resolver, el problema más general ya está bastante bien resuelto, y dicho subsistema podría ser útil para Less.js de otras formas.

Aplanas los operadores en el mismo nivel de precedencia (por lo que el árbol es Sum (4px, 2rem, -2px)),

¿Y qué es exactamente lo que hace que el código piense que algún árbol de expresión es realmente aplanable? (Así que mi "sufrimiento" no se trata de un algoritmo de deducción específico, sino de un atajo para "probar todos", incluido el "aplanar").

pero hay muchas bibliotecas que probablemente estén mejor probadas y tengan más probabilidades de estar completas.

No estoy seguro si hablas en serio. Entonces, ¿cree que todo ese código para convertir Less tree en un árbol de bibliotecas externo y viceversa (sin contar que ninguna de esas bibliotecas JS puede manejar unidades CSS) realmente vale la pena ese caso específico 4px + 2rem - 2p para ser optimizado? Mmm...

Entonces, no hay problema en absoluto (no dije que sea imposible, solo que nunca valdrá la pena): inténtelo y las relaciones públicas son bienvenidas.
(También, por si acaso, probablemente sea importante tener en cuenta que la optimización de subexpresiones ni siquiera es el objetivo de este ticket, ni siquiera entre sus tres primeros).

¿Y qué es exactamente lo que hace que el código piense que algún árbol de expresión es realmente aplanable? (Así que mi "sufrimiento" no se trata de un algoritmo de deducción específico, sino de un atajo para "probar todos", incluido el "aplanar").

El analizador determina si el contexto es, por ejemplo, "longitud", y si el subárbol se puede interpretar como "longitud".

No estoy seguro si hablas en serio. Entonces crees que todo ese código para convertir Less tree en un árbol de bibliotecas externo y viceversa

Debe analizarse en un árbol de sintaxis. A partir de ahí, sería relativamente sencillo generar una cadena que represente una expresión algebraica. Retroceder puede ser más difícil: es posible que deba analizarse nuevamente a partir de una cadena, o sí, es posible que deba tomar el árbol de bibliotecas externas. La dificultad depende de la biblioteca elegida.

(sin contar ninguna de esas bibliotecas JS puede manejar unidades CSS)

Simplemente convertiría unidades en variables algebraicas. Incluso se pueden realizar sustituciones (por ejemplo, mm -> px ) mientras la expresión está en forma simbólica.

¿Realmente vale la pena optimizar ese caso específico de 4px + 2rem - 2p?

Estoy haciendo una sugerencia alternativa para la optimización de expresiones que es menos difícil (como un problema de algoritmo que el propio código de Less debe resolver) y más útil en general de lo que dijo que era necesario.

La simplificación algebraica puede resolver cosas con subexpresiones entre paréntesis y permitir que Less agregue más características matemáticas.

intente y las relaciones públicas son bienvenidas.

Intentaré. Solo comencé a buscar en Less hoy, y tengo problemas para terminar proyectos, así que admito que probablemente no consiga un PR.

Además, por si acaso, probablemente sea importante tener en cuenta que la optimización de subexpresiones ni siquiera es el objetivo de este ticket, ni siquiera en sus tres primeros

Sé. Estuve aquí por una de las razones. ¿Por qué tal mordisco?

¿Por qué tal mordisco?

Bueno, tal vez ... Si es así, mis disculpas (parece que estoy demasiado sorprendido por los esfuerzos y el tiempo que alguien está listo para dedicar a resolver el problema calc(4px + 2rem - 2px) no existe. Probablemente solo tengamos una noción muy diferente de ligereza).

y permitir que Less agregue más funciones matemáticas.

¿Podrías nombrar algunos?

para resolver prácticamente el problema calc(4px + 2rem - 2px) no existe

¿Eh? Less no puede manejar eso en absoluto. [resto eliminado porque no entendí bien lo que se estaba tratando]

Para simplificar / reformular la propuesta , los cambios matemáticos serían los siguientes

  1. La suma y la resta solo se calcularían en unidades similares. por ejemplo, 1px + 2px = 3px , 1px + 1vh = 1px + 1vh
  2. La división y la multiplicación solo se calcularían con divisores / multiplicadores sin unidades. por ejemplo, 10px/2 = 5px , 10px/5px = 10px/5px
  3. Las relaciones de valor sin unidades se tratarían de manera similar a # 2. por ejemplo, 1/3 = 1/3
  4. Para simplificar, las expresiones con subexpresiones parcialmente inválidas pueden tratarse como una expresión matemática inválida y producirse tal cual. por ejemplo, 1px + 2vh / 2 = 1px + 2vh / 2

Esta propuesta resuelve lo siguiente (de este hilo):

  • font: 10px/5px y sintaxis similar (proporción) (sin cálculo)
  • calc(100vh - 30px) (sin cálculo)
  • lost-column: 1/3 y una sintaxis de proporción personalizada similar (sin cálculo)

Al mismo tiempo, estos cambios preservarían el 99% del uso típico de Menos matemáticas. Además, las funciones existentes unit() y convert() permiten a los usuarios convertir valores en unidades compatibles para matemáticas.

Less no puede manejar eso en absoluto.

Simplemente no leíste lo que yo y @leewz estábamos hablando arriba. No tuvo nada que ver con calc(100vh - 30px) . Y mi "resolver prácticamente un problema que no existe" se destina únicamente a "optimizar expresiones aritméticas en calc ".

@ seven-phase-max Ohhh, eso es cierto. Lo siento. No, no necesitamos optimizar. Solo averigua cuándo hacer matemáticas.

Este problema se ha marcado automáticamente como obsoleto porque no ha tenido actividad reciente. Se cerrará si no se produce más actividad. Gracias por sus aportaciones.

Eliminar la etiqueta de la pizarra, ya que el problema sigue siendo importante y empeora a medida que evoluciona CSS.

@ matthew-dean
Voy a jugar al abogado del diablo por un momento aquí ...

12px/30px usted _podría_ tratar como una declaración matemática válida, pero ¿debería hacerlo?

Sí; debería. Calcula un valor escalar que representa una relación entre ambos tamaños y que puede ser bastante útil cuando se convierte a la unidad em.

Digamos que tengo un tamaño de fuente base conocido de 16px y un tamaño de encabezado conocido de 24px, ambos escondidos en variables, y luego quiero asignar un tipo particular de encabezado con el tamaño de fuente correcto, pero en una unidad em.

@fontsize-body    : 16px;
@fontsize-heading : 24px;

// ( ... and then somewhere else ... )

.heading {
  font-size : unit(@fontsize-body/@fontsize-heading, em);

  // Or if dividing compatible unit values is produces a unit-less scalar
  // value ( as it really _should_ -- mind you... ),  you could prefer:
  font-size : @fontsize-body/@fontsize-heading * 1em;
}

Y si necesita admitir la división de unidades compatibles como una expresión matemática, entonces seguirá necesitando admitir una forma de eliminar la ambigüedad de CSS literal de las expresiones matemáticas Less para cubrir cada mitad de los casos.

Ahora bien, eso podría implicar el uso de parens para forzar una expresión matemática y tomar un literal CSS de forma predeterminada. Pero eso parece incorrecto y propenso a errores. Requiere muchos casos especiales precocinados, como en las abreviaturas border-radius y font , y requiere que Less se mantenga continuamente actualizado sobre estos. (Como ha sido ilustrado por algunas de las nuevas propiedades de la cuadrícula que desarrollan el mismo problema con el signo de división).

Entonces...

¿Por qué no darle la vuelta a su razonamiento? Si algo se parece a una expresión matemática y tiene unidades compatibles , se tratará como una expresión matemática de forma predeterminada. Y si no quieres que eso suceda ... bueno; luego use la trampilla de escape ~"..." . Es exactamente para lo que está ahí, después de todo ...

Mi visión actual de la propuesta:

  • Deje de tratar / como división en cualquier lugar, independientemente de cualquier untis e independientemente de las opciones (a menos que, opcionalmente, esté encerrado por parens redundantes como con -sm = on)
    Por lo tanto, Less solo evalúa 1anything./3whatever y (opcionalmente) (1anything/3whatever) .
  • + , - y * permanecen sin cambios
  • calc subissue se resuelve sin evaluar ningún aritmo. expresiones dentro de calc(...) (aunque, una vez más, los parientes reductores también pueden tener su efecto).

@ siete-fases-max

El problema con eso es que / está increíblemente arraigado como operador de división. Usar cualquier otro símbolo sería difícil de vender para los usuarios. Está tomando el caso de uso general y descartándolo por el caso de uso excepcional ( / en abreviaturas CSS) que casi nadie usa.

@rjgotten

El problema con eso está increíblemente arraigado como operador de división.

No en CSS.

para el caso de uso excepcional (/ en abreviaturas CSS) que casi nadie usa.

Por ahora, / ya se usa mucho , y en comparación, la opción Less div es mucho más excepcional que CSS / estos días (a diferencia de lo que era hace unos años donde CSS / se puede encontrar principalmente dentro de font solamente).

@ seven-phase-max Gracias por estar al tanto. Agregué el bot Stale para ayudarnos a manejar los problemas y le di una cantidad bastante generosa de tiempo para marcarlo. También eximí dos etiquetas, "error" y "en juego". Cualquier sugerencia al respecto es bienvenida, como otras etiquetas para incluir en la lista blanca. El archivo está aquí: https://github.com/less/less.js/blob/3.x/.github/stale.yml

Volviendo al hilo del problema ...

@rjgotten
Su caso de uso crea un problema arbitrario. El argumento es que es útil. Pero estructurar sus vars de esa manera crea un problema que se puede evitar con una sintaxis que es, como señaló @ seven-phase-max, ambiguo.

Incluso tomado al pie de la letra, con CSS como guía para los principios de Less, no puede, en cálculo, dividir 12px por 30px. Hacerlo en Less no solo crea un problema de ambigüedad, sino que rompe con el modelo sin una buena razón (aparte de la histórica). Probablemente una de las cosas que le faltan a Less es solo una forma de extraer el valor numérico de un valor unitario para que Less no tenga que hacer esta magia matemática para la división.

Entonces, la respuesta simple es que su ejemplo se vería así:

font-size : @fontsize-body/number(@fontsize-heading) * 1em

Pero también estoy de acuerdo con la propuesta de @ seven-phase-max. Todavía podríamos evaluar _vars_ en calc() , pero no en matemáticas. Y no evaluar la división fuera de los parens. Creo que es un buen compromiso. Y, posiblemente, si quisiera preservar la matemática de división mágica de dividir una unidad por una unidad pero manteniendo la unidad (lo cual aún es extraño, pero está bien), podría suceder dentro de los parens.

Sé que hay algunas preferencias diferentes sobre el tema de las matemáticas en Less, pero creo que sería realmente genial si pudiéramos llegar a un consenso sobre algo que causó los menores efectos secundarios y fue el más fácil de razonar sin causar un gran mantenimiento. o carga de desarrollo.

Creo que todos estamos en la misma página de que el enfoque actual (predeterminado) de las matemáticas en Less está roto. Y habíamos recibido la retroalimentación de que parens-todo por defecto era más fácil de razonar, pero engorroso. Así que espero un buen término medio que podamos poner como predeterminado pronto (¿probablemente en 4.0?)

Probablemente una de las cosas que le faltan a Less es solo una forma de extraer el valor numérico de un valor unitario

La función unit realmente hace eso si no especifica un segundo parámetro. Pero eso es más un efecto secundario del hecho de que los escalares se implementan actualmente con un tipo de nodo Dimension que no tiene una unidad definida.

Otorgado; da la vuelta, pero si _realmente_ quiere evitar dividir dimensiones que tienen unidades compatibles, entonces arrancar la unidad funcionaría.

También agregaría que estoy fuertemente en contra de cualquier conjetura de "unidades compatibles" (como dejar que a/b siga siendo una división y b/c no lo sea) en este contexto particular.
Simplemente porque:

  • el manejo excepcional es la raíz de todos los males (por ejemplo, # 3047 - ver más abajo, http://stackoverflow.com/questions/19705791- Recuerdo que no pude encontrar la razón del problema SO hasta que realmente pasé por cada una de las trillones de líneas del código Less involucrado en un depurador).
  • y lo más importante, simplemente no está preparado para el futuro, es decir, si un cambio radical importante es inevitable, será mejor que nos aseguremos de hacerlo una vez (e idealmente para siempre) ... y no como si agreguen alguna nueva característica de CSS que involucre a/b y está roto de nuevo.

Entonces, para mí, el tema de las "Unidades compatibles" es más como algo totalmente no relacionado y ortogonal (podría haber algunas discusiones sobre las unidades resultantes con o sin -su , pero esa es otra historia).


(sin relación:)
Y por cierto, hablando de los ejemplos anteriores:
@rjgotten si tiene:

@fontsize-body/@fontsize-heading * 1em; 

en algún lugar de su código y cualquiera de las dos variables es px , en realidad está usando un error :)
El código correcto es:

1em * @fontsize-body/@fontsize-heading;

Esto siempre da como resultado una unidad bien definida por http://lesscss.org/features/#features -overview-feature-operations (contando # 3047 para ser corregido, el error es una vez más un ejemplo de un error producido exactamente por demasiados código de conjeturas sobre "unidades compatibles" en la base del código). No hay necesidad real de --su , number , unit bla-bla ... Comportamiento actual de -su como "arrojar un error si ve unidades incompatibles" , es decir, una simple validación, está más que bien (para mí). No veo ninguna necesidad de sobreingeniería 1px/2px->.5 y 1px*2px->2px^2 mambo-jambo. Pero una vez más, esta es otra historia no relacionada).

@ siete-fases-max

realmente usando un error

Uhm ... sí; tienes razón, por supuesto. Afortunadamente, no tengo ese código en producción en ninguna parte. Fue solo un ejemplo rápido mezclado para ilustrar el punto.

También agregaría que estoy fuertemente en contra de cualquier conjetura de "unidades compatibles" (como dejar que a / b siga siendo una división y b / c no lo sea) en este contexto particular.

Creo que estaba de acuerdo con eso más como una rama de olivo para aquellos que quieren divisores desnudos. Pero creo que su comentario [ aquí ] es la propuesta más viable. La intención original de las "matemáticas estrictas" era eliminar la ambigüedad. Creo que la preocupación se convirtió en operaciones dentro de mixin y llamadas de función que conducen a todo tipo de parens dentro de parens. Pero, en general, estoy de acuerdo con ustedes en que los esfuerzos para facilitar las matemáticas en Less también, irónicamente, lo han hecho muy difícil, debido a la mayor ambigüedad.

Además, más tarde me di cuenta de que font: 10px/3 es una abreviatura válida. Entonces, realmente no existe una solución algorítmica que pueda ayudar allí.

Para volver a tu pregunta, @rjgotten ...

¿Por qué no darle la vuelta a su razonamiento? Si algo se parece a una expresión matemática y tiene unidades compatibles, se tratará como una expresión matemática de forma predeterminada. Y si no quieres que eso suceda ... bueno; luego use la trampilla de escape ~ "...". Es exactamente para lo que está ahí, después de todo ...

La idea / relación de Less con CSS es similar a TypeScript con JavaScript. Es decir, cambie el nombre de su .css válido a .less y puede comenzar a agregar funciones Menos. Similar a cómo puede cambiar el nombre de .js a .ts y comenzar a agregar funciones de TypeScript. Si no agrega nada, debería obtener el mismo resultado válido Less / JavaScript, porque los idiomas son superconjuntos del idioma base.

Sin embargo, en el caso de estas proporciones u otros divisores de / en CSS, Less ya falla desde el principio, de forma predeterminada. Su CSS regular se convierte arbitrariamente en una expresión menos matemática con un resultado diferente, aunque no haya cambiado nada. Eso viola el contrato del idioma. Ser capaz de cambiar su .less en una expresión Less completamente diferente para recuperar el CSS original con el que comenzó no tiene sentido. Ese trabajo nunca debería ser requerido. Less no debería requerir que cambie su CSS válido en expresiones Less compatibles para recuperar el CSS válido que tenía en primer lugar. Eso es solo un modelo roto.

El mismo razonamiento se aplica a calc() . Sí, puede escapar de cadenas de sus expresiones, pero no debería tener que hacerlo. .css renombrado a .less debería producir el mismo CSS efectivo. Este debería ser el objetivo básico del proyecto, no interferir / sobrescribir / sobreinterpretar la hoja de estilo original. Cualquier otra cosa es intentar llevar el problema al desarrollador sin otro pecado que usar el analizador / lenguaje en primer lugar.

Sí, puede escapar de cadenas de sus expresiones, pero no debería tener que hacerlo. .css renombrado a .less debería producir el mismo CSS efectivo. Este debería ser el objetivo básico del proyecto, no interferir / sobrescribir / sobreinterpretar la hoja de estilo original. Cualquier otra cosa es intentar llevar el problema al desarrollador sin otro pecado que usar el analizador / lenguaje en primer lugar.

Ese.

MENOS sabe dónde está permitido / y dónde no está en css. Donde no lo está, pero aparece de todos modos, debe asumir que se deben hacer las matemáticas. Además, cuando las matemáticas están rodeadas por corchetes redondos donde los corchetes redondos no están permitidos en css, deben interpretarse con LESS.

En otras palabras, LESS debería intentar interpretar la menor cantidad posible de matemáticas para llegar a un CSS válido. Tan pronto como la salida sea válida, deje de ejecutar más operaciones matemáticas.

@gracias

Demasiadas suposiciones de lo que sabe el compilador (y algunas de ellas son simplemente incorrectas).
De cualquier manera, el modo "los corchetes" es casi lo que hace --sm=on , así que úsalo y olvídate de este hilo (lo más probable es que no uses ninguna matemática en tus proyectos además de calc (introdujimos algunos años después de que se diseñó Less), por lo que no puede ver cómo los padres adicionales son molestos. Pero otros sí.)


Para el resto, consulte https://github.com/less/less.js/issues/1880#issuecomment -345194431.

@ seven-phase-max No olvides que / también tiene significado en las abreviaturas background y border-radius , y posiblemente otras en las que no estoy pensando en este momento. LESS felizmente los tratará como una división. Con o sin el modo matemático estricto, MENOS debería "saber cuándo dejar" de hacer sus propias pequeñas operaciones matemáticas.

@gracias
MENOS debería "saber cuándo dejar" de hacer sus propias pequeñas operaciones matemáticas.

No, no debería. No hay forma de saber dónde van a aparecer las futuras abreviaturas de CSS con la barra de división. Hacer que el compilador Less "sepa" sobre eso es un enfoque fundamentalmente defectuoso y precisamente lo que esta discusión está tratando de encontrar una solución.

Hasta ahora, hay dos opciones sensatas y predecibles para / como operador de división:

  • Trátelo siempre como tal y requiera un escape explícito para otros usos.
    Esto romperá el comportamiento donde la sintaxis Less es un superconjunto estricto de sintaxis CSS.
  • Nunca lo trate como un operador de división, __ a menos que__ esté dentro de un contexto matemático conocido.
    Donde el contexto matemático conocido podría / podría decidirse como en el comportamiento actual --strict-math=on .

(Además, tenga en cuenta que el nombre Less ya no se escribe en mayúsculas).

No olvide que / también tiene significado en las abreviaturas de fondo y radio de borde,

Esto es básicamente con lo que comienza este hilo.
Y vea el resumen de los cambios propuestos en https://github.com/less/less.js/issues/1880#issuecomment -345194431 (sin ninguna suposición de lo que el compilador debería o no saber).

No, no debería. No hay forma de saber dónde van a aparecer las futuras abreviaturas de CSS con la barra de división. Hacer que el compilador Less "sepa" sobre eso es un enfoque fundamentalmente defectuoso y precisamente lo que esta discusión está tratando de encontrar una solución.

Estoy de acuerdo con esto completamente. @thany Si bien estuvo de acuerdo conmigo en lo que citó de lo que escribí, está llegando a una conclusión diferente a la que yo haría. Menos no debería ni puede saber cuándo "dejar de hacer matemáticas". Lo que yo diría es que el cambio decisivo debería ser que Less es más conservador acerca de comenzar con las matemáticas (para usar el estadounidense / canadiense) en primer lugar.

@rjgotten

Nunca lo trate como un operador de división, a menos que esté dentro de un contexto matemático conocido.
Donde el contexto matemático conocido podría / se decidiría como en el actual --strict-math = sobre comportamiento.

Solo para aclarar, esta parte (con la que estoy de acuerdo):

Nunca lo trate como un operador de división, a menos que esté dentro de un contexto matemático conocido.

En realidad, tiene 4 posibles soluciones, que sé que usted conoce, pero solo resumiendo para el hilo:

  1. Haz todas las matemáticas solo entre paréntesis . Aparentemente, esto ha sido rechazado por los comunes, lo cual está bien, aunque todavía está disponible como un interruptor opcional ( strictMath ).
  2. Haga todas las matemáticas en todas partes, pero divida solo entre paréntesis.
  3. Haga todas las matemáticas en todas partes, pero divida solo entre paréntesis. A menos que el operador de división esté impreso como ./
  4. Haga todas las matemáticas en todas partes, pero corrija las matemáticas para que 12px/4px no resulte en una división. (Multiplicación y división solo con valores sin unidades). En otras palabras, división en todas partes, pero con reglas mucho más conservadoras. En los casos en que no resuelva las cosas, recurra nuevamente a escapar. Por lo tanto, no es una solución completa, pero sigue siendo una mejora (discutible) sobre la situación actual.

Desde una perspectiva de usabilidad, me gusta hacer las matemáticas "más inteligentes" como en #4 . Desde el punto de vista de la ingeniería y el mantenimiento, y para protegerme de futuros cambios de CSS, me gusta #3 como la solución más sólida.

Sin embargo, creo que en realidad, tendríamos que hacer tanto #3 Y #4 para arreglar calc() . En este momento, menos ignorar todas las unidades al hacer matemáticas es un verdadero desastre. 100vh - 12px nunca debe ser tocado por Menos (paréntesis o no). Pero en mi opinión, tampoco debería 12px/4px (paréntesis o no), pero podría ser una minoría en eso.

Por lo tanto, no veo esto tanto como un problema de "matemáticas en conflicto con la sintaxis CSS", sino que, para empezar, Less es demasiado agresivo con la resolución prematura de ecuaciones matemáticas.

Multiplicación y división solo con valores sin unidades.

no va a funcionar ya que hay cosas como:

font: small-caps bold 24px/3 ...;
lost-column: 1/3;
// etc.

y no son divs.

Sin embargo, creo que, en realidad, tendríamos que hacer tanto #3 Y #4 para arreglar calc()

calc() es un fastidio. Irónicamente, _probablemente_ se resuelve mejor implementándola como una función Less real, que idealmente tomaría su árbol de expresión analizado e intentaría simplificar la expresión. Es decir: debe precalcular y combinar componentes compatibles como 4px + 12px (o 4px + @a cuando se sabe que @a tiene un valor de píxel) pero dejar componentes incompatibles, p. Ej. con unidades incompatibles, solo.

P.ej

<strong i="17">@a</strong> : 4px;
<strong i="18">@b</strong> : 2;
width : calc(100%/<strong i="19">@b</strong> - 10px + @a);

eventualmente debería rendir

width : calc(50% - 6px);

(repitiéndome de https://github.com/less/less.js/issues/1880#issuecomment-345345735)
Y no veo ningún beneficio de sobreenergizar mucho al compilador para optimizar las expresiones dentro de calc . Si está escribiendo calc entonces está bien con el navegador para hacer el trabajo independientemente de la expresión larga que tenga allí. Entonces, como ya se mencionó anteriormente, estoy a favor de "no toque nada dentro de calc " (= no intente ser más inteligente de lo que realmente es necesario) y déjelo para el navegador ( o para un minificador de CSS, ya que , si mal no recuerdo, algunos de ellos ya hacen un trabajo bastante bueno en la optimización de subexpresiones de cálculo).


El "comportamiento inteligente de la unidad mamabo-jambo" me recuerda a los min/max monstruos (pila abultada de código no mantenible y nunca usado ) - cuánto me arrepiento de no haber gritado contra las "unidades mambo" en ese entonces , oh (Así que seguiré lloriqueando aquí hasta que la idea misma de "diferentes semánticas de operador dependiendo de las unidades de operando" sea totalmente aniquilada: P).


PD Tan pronto como calc convierta en una función que reciba una expresión no evaluada por aritmo (tendrá que hacerlo de todos modos), uno podrá escribir un complemento y anularlo con cualquier optimización deseada.

@rjgotten
Hacer que el compilador Less 'sepa' eso es un enfoque fundamentalmente defectuoso

Creo que es un enfoque fundamentalmente correcto . LESS es un compilador de CSS, por lo que tiene todo el sentido del mundo que LESS sepa sobre lo que está compilando.

@ matthew-dean
Menos no debería ni puede saber cuándo "dejar de hacer matemáticas". Lo que yo diría es que el cambio decisivo debería ser que Less es más conservador acerca de comenzar con las matemáticas (para usar el estadounidense / canadiense) en primer lugar.

Es interesante que lo piense desde el otro lado, por así decirlo. Esto es lo que propongo:

background: url(...) no-repeat 50% 50% / 40px + 10px 40px;

Lo que LESS debería hacer aquí, es obvio para mí:

background: url(...) no-repeat 50% 50% / (40px + 10px) 40px;

Resultando en:

background: url(...) no-repeat 50% 50% / 50px 40px;

No debería calcular la parte 50% / 50px en esto, porque (1) no debería poder hacerlo debido a unidades incompatibles y (2) porque esto ya es lo suficientemente lejos para un background . Así que aquí es donde "dejará de hacer matemáticas".

Eso es lo que quise decir con MENOS "saber cuándo parar".

Si fuera una propiedad diferente como esta:

padding-left: 50% / 10px + 5px;

Debería romperse con un error (unidades incompatibles). Una salida posible sería 50% / 15px que no es válida para esta propiedad. Otro resultado podría ser 5% lo que hará actualmente, lo cual está mal en todas las direcciones.
Y:

padding-left: 50px / 10px + 5px;

Debería resultar en:

padding-left: 10px;

Como se esperaba. Entonces, en este caso, / no es válido para padding-left y se toma en LESS y hace sus cálculos matemáticos.

@ matthew-dean
En realidad, tiene 4 posibles soluciones, que sé que usted conoce, pero solo resumiendo para el hilo:

Uno mas:
5) Utilice el operador \ para las divisiones en LESS y desapruebe el uso de / . MATLAB tiene algo como esto, y ciertos sabores de BASIC lo usaron para forzar la división de enteros. Entonces, usar la barra invertida no es completamente inaudito.

/editar
También podemos presionar para incluir una tecla ÷ en los teclados y usarla como operador de división. Ese es el que aprendí en la escuela primaria :)

Lo que sugieres ya se discutió muchas veces antes (no dudes en mirar los hilos a los que se hace referencia aquí). Así que aquí hay comentarios pequeños y perezosos:

Utilice el operador \ para las divisiones en MENOS y desapruebe el uso de / .

https://github.com/less/less.js/issues/1872#issuecomment -35245890

suficiente para background ... no es válido para padding-left

Conozca a los "chicos, mi navegador / polyfill / lo que sea que haya agregado / actualizado / expandido soporte para una propiedad fnord , ¿podrían lanzar una nueva versión Less para mí?" asunto.
Conoce el problema de font .
etcétera etcétera.
Bueno, @rjgotten ya comentó anteriormente por qué ese tipo de "conocimiento" es el camino a ninguna parte.

@ siete-fases-max
La barra invertida fue solo una sugerencia. También puede usar ? para la división. Realmente no importa. Lo que estoy sugiriendo, supongo, es no usar un carácter ( / ) que tenga significados muy diferentes y ambiguos.

Conozca a los "chicos, mi navegador / polyfill / lo que sea que haya agregado / actualizado / expandido soporte para una propiedad fnord , ¿podrían lanzar una nueva versión Less para mí?" asunto.

CSS es un estándar bien definido. No debe admitir nada fuera del estándar. Ese es tu problema, creo. No debe admitir la propiedad fnord , porque no forma parte de ningún estándar. Cuando ocurre esta nueva propiedad no especificada, LESS puede volver a su comportamiento predeterminado, que podría ser el actual, o requerir paréntesis, o cualquier otra cosa siempre que no sea ambiguo.

Resuelva el problema de la fuente.

El problema de la fuente prueba que el problema / ha existido desde los inicios absolutos de LESS. No solo cuando background obtuvo la capacidad de incluir un valor para el tamaño de fondo o cuando surgió border-radius . Tbh, al indicar el problema de la fuente, acaba de presentar el mejor argumento en su contra :)

Tbh, al indicar el problema de la fuente, acaba de presentar el mejor argumento en su contra :)

Creo que malinterpretas algo. Fui yo quien inicialmente propuso eliminar totalmente el / como operador div. Entonces, para el resto de cosas, supongo que es el mismo problema de que no prestas atención a lo que te responden.

CSS es un estándar bien definido.

Si va a ceñirse a las partes de especificación que han alcanzado la madurez completa en el nivel de TR, tal vez.
¿De lo contrario? No, no es. Hay especificaciones satélite de nuevos 'módulos' de CSS y revisiones de módulos existentes con nuevas adiciones que aparecen mensualmente, si no semanalmente.

@ siete-fases-max

no va a hacer el truco ya que hay cosas como: fuente: minúsculas negrita 24px / 3 ...

No, lo entiendo. Mi punto fue exactamente eso: div / multiplicación sin unidades solo reduce el problema pero no resuelve el problema.

Y creo que, en general, su sugerencia de ./ para todas las divisiones todavía parece bastante lógica.

@thany En lugar de responder a todos los ejemplos específicos, diré que, en general, los esfuerzos para hacer que Menos matemáticas sean más inteligentes simplemente patearán la pelota hacia una línea de yarda diferente. Siguen siendo los mismos problemas, solo que en un lugar diferente. Como ha dicho @ seven-phase-max, nada de lo que sugirió no se ha discutido.

Y no veo ningún beneficio de sobreenergizar mucho el compilador para optimizar las expresiones dentro de calc. Si está escribiendo calc, entonces está bien con el navegador para hacer el trabajo independientemente de la expresión larga que tenga allí. Entonces, como ya se mencionó anteriormente, estoy a favor de "no tocar nada dentro de calc" (= no intente ser más inteligente de lo que realmente es necesario) y déjelo para el navegador (o para un minificador de css, ya que, si recuerdo correctamente , algunos de ellos ya hacen un buen trabajo en la optimización de subexpresiones de cálculo).

Estoy completamente de acuerdo con esto. Eliminaríamos el 99% de los nuevos problemas relacionados con las matemáticas si incluyéramos calc() lista blanca. Si bien he sugerido algunas formas en que Less podría hacer matemáticas de manera más inteligente para TAMBIÉN evitar problemas de calc() (que tal vez debería), me disculpo si eso se interpretó como un argumento en contra de esta idea. Yo también apoyo esto.

La única advertencia (como se discutió aquí / en otro lugar) es que un desarrollador inevitablemente querrá usar variables en calc() , por lo que debemos tener cuidado de asegurarnos de continuar intercambiando vars, pero simplemente no lo hagamos Matemáticas. No estoy seguro de cuán desafiante es eso. Si logramos hacer eso, apoyaría un cambio en el manejo de calc() hoy.

@gracias

El problema de la fuente prueba que el problema / ha existido desde los inicios absolutos de LESS.

Esto puede ser cierto y es un punto justo, pero había muchas soluciones alternativas adecuadas y no era necesariamente una práctica estándar en ese momento usar la abreviatura de propiedad font . En realidad, debido a que llegaron múltiples fondos y calc() después de que Less comenzara, esto hizo que esto fuera más un problema, y ​​ahora la sintaxis de CSS Grid significa que ahora hay un montón de conflictos donde inicialmente no existía ninguno en términos prácticos cotidianos.

Por cierto, así es como Sass resuelve el problema, ilustrado con este ejemplo:

p {
  font: 10px/8px;             // Plain CSS, no division
  $width: 1000px;
  width: $width/2;            // Uses a variable, does division
  width: round(1.5)/2;        // Uses a function, does division
  height: (500px/2);          // Uses parentheses, does division
  margin-left: 5px + 8px/2px; // Uses +, does division
  font: (italic bold 10px/8px); // In a list, parentheses don't count
}

No es uno a uno, ya que puede hacer cálculos matemáticos (actualmente) dentro de los argumentos de las funciones Less, Y las funciones Less pueden devolver valores de píxeles (por lo que Less podría hacer font: print10px()/8px , ¿teóricamente? ¿No?), Así que yo Lo estoy pegando de forma ilustrativa, no como una sugerencia. Es interesante cómo abordaron el problema.

Personalmente, creo que hacer que los desarrolladores intenten recordar en qué casos se producirán las matemáticas en función de la existencia de expresiones mágicas es una especie de locura (como estar precedido por un + ?), Pero para cada uno lo suyo. .

Personalmente, creo que hacer que los desarrolladores intenten recordar en qué casos se producirán las matemáticas en función de la existencia de expresiones mágicas es una locura.

+1


Sin contar que la "solución" no resuelve lessc --sm . Y resultados diferentes para 1/2 y $var/2 es simplemente un fenomenal brillante ... ~ estupidez ~ "¡Feliz depuración, perdedores!"

@ matthew-dean
Por cierto, así es como Sass resuelve el problema, ilustrado con este ejemplo:

Es una solución brillante sin tener que recurrir a un operador diferente.
Si la expresión es posiblemente CSS válida, déjela.

Personalmente, creo que hacer que los desarrolladores intenten recordar en qué casos se producirán las matemáticas en función de la existencia de expresiones mágicas es una locura.

Discrepar. Es un conjunto simple de reglas, no es diferente de cualquier otro conjunto de reglas (locas o no) que necesita recordar.

Hay algunos casos extremos en los que las matemáticas ocurren sin querer, pero luego solo aplicará paréntesis y listo.

Sin contar que la "solución" no resuelve ninguno de los problemas aquí discutidos más allá de lo que ya hace lessc --sm. ¿Por qué escribiría 0 + 1/2 en lugar de (1/2) cuando lo que quiero es solo una división? Y diferentes resultados para 1/2 y $ var / 2 es simplemente una estupidez fenomenalmente brillante "¡Feliz depuración, perdedores!" mensaje.

Ja, sí, esto.

@gracias

Es una solución brillante sin tener que recurrir a un operador diferente.
Si la expresión es posiblemente CSS válida, déjela.

No para meterse en la maleza, pero no va a funcionar para Less, por razones sintácticas y también por la coherencia del lenguaje. Puede ser brillante para Sass, lo que yo diría que es discutible, pero no estoy involucrado personalmente con ese proyecto desde una perspectiva de diseño, así que quién puede decirlo. Todo lo que sé es que las opciones sobre la mesa son el mejor lugar para comenzar, y estoy seguro de que si dedicara tanto tiempo a revisar algunos de los hilos de mensajes relacionados con este problema y dedicara tiempo al idioma, vendría a la misma conclusión.

Una observación de la que no podemos escapar: si importa CSS vainilla válido, su salida debe ser funcionalmente idéntica. Entonces, la única conclusión que puedo sacar es que LESS no debería tocar expresiones que ya sean CSS posiblemente válidas. Cómo se hace esto, no depende de mí. Pero el hecho es que la importación de CSS vanilla no es confiable, principalmente como resultado de que MENOS ejecuta divisiones con demasiada avidez.

Importar CSS vainilla en Sass funciona virtualmente sin problemas, porque como se dijo, Sass deja solo al operador / si no le indica al compilador que vaya y haga cosas, de acuerdo con algunas reglas de sintaxis simples. Estas reglas de sintaxis describen formas de forzar una división que no puede ocurrir en CSS vainilla válido, y por eso es brillante.

Sigues discutiendo con tu propia imaginación y no con lo que te dicen. Responda la pregunta simple: "¿Cómo 0 + 1/2 puede ser posiblemente mejor que (1/2) ?". Si la compatibilidad 100% -CSS es lo único que le importa, configure el encantador -sm y olvídese de este hilo.

Una observación de la que no podemos escapar: si importa CSS vainilla válido, su salida debe ser funcionalmente idéntica. Entonces, la única conclusión que puedo sacar es que LESS no debería tocar expresiones que ya sean CSS posiblemente válidas. Cómo se hace esto, no depende de mí. Pero el hecho es que la importación de CSS vanilla no es confiable, principalmente como resultado de que MENOS ejecuta divisiones con demasiada avidez.

Básicamente estoy de acuerdo con esta parte, y creo que encontrarías mucho acuerdo en este hilo sobre ese punto. La mayoría de los desacuerdos se han relacionado con soluciones, y cada solución tiene varios efectos secundarios.

Estaría de acuerdo con hacer estos cambios importantes como una prioridad:

  1. matemáticas fuera de paréntesis que requieren ./ lugar de un / desnudo. 12px./10px todavía se ve un poco extraño.

@ seven-phase-max: quiero volver a visitar la barra invertida. En relación con esto, sé que mencionó https://github.com/less/less.js/issues/1872#issuecomment -35245890, pero no veo ningún conflicto absoluto, ya que esos identificadores no lo son y creo que no pueden ser parte de las expresiones matemáticas. ¿O me equivoco? Supongo que es posible proponer un caso teórico como el nombre de una función con un carácter de escape como parte del nombre, pero eso parece más un ejercicio intelectual que un caso del mundo real. Los selectores de escape, sí, se usan comúnmente por varias razones, pero en los valores de propiedad, parece poco probable o, en un caso límite, está bien romper / solucionar con la solución histórica (simplemente escapar de este texto).

¿Podemos explorar un poco más que el uso de una sola barra invertida para la división causaría conflictos en el mundo real? Mi instinto es que \ es menos problemático que la situación actual en torno a / , y es más amigable para los desarrolladores que ./ . Si hicimos la investigación y descubrimos que es factible, entonces podríamos hacer el cambio radical para usarlo en todas partes, en lugar de cambiar de contexto, lo que permite / entre paréntesis. Y luego podríamos admitir / con un conmutador heredado.

  1. (segunda prioridad) calc() está en mayúsculas especiales para que pueda hacer un reemplazo de variable pero no evaluará ninguna expresión matemática

¿Podemos explorar un poco más que el uso de una sola barra invertida para la división causaría conflictos en el mundo real?

Bueno, el problema de que \anycharacter es CSS válido y tiene su propio significado. Claro, apenas encuentras ese código en proyectos reales (excepto tal vez en los trucos similares a \9 ), pero ... ¿queremos alimentar a ese león? Arreglar un "uh-oh, mi CSS 100% válido no se compila" al introducir otro "uh-oh" del mismo suena un poco extraño :)

En cuanto a calc , supongo que tuvimos un consenso desde el principio, por lo que básicamente solo espera a que un voluntario lo implemente (estimo que la solución rápida se realizará en solo 5-6 líneas de código nuevo, por lo que En realidad, solo se trata de un hombre valiente para hacer esto; los detalles menores de implementación pueden variar, pero creo que está bien que se decidan en el proceso).

Bueno, el problema de que \ anycharacter es CSS válido y tiene su propio significado. Claro, apenas encuentras ese código en proyectos reales (excepto quizás en los hacks tipo ie \ 9), pero ... ¿queremos alimentar a ese león? Arreglar un "uh-oh, mi CSS 100% válido no se compila" al introducir otro "uh-oh" del mismo suena un poco extraño :)

Te escucho, es una posible compensación. Y sí, sé que \anycharacter es CSS válido. Supongo que me pregunto si es un mejor conjunto de compensaciones. Es solo que cuando escribí 12px./10px me pareció extraño, sintácticamente. Siento que Less sintácticamente ha intentado reutilizar CSS tanto como sea posible sin crear conflictos.

Por ejemplo, ./ proporciona claridad de sintaxis y evita completamente los conflictos, pero también lo hizo aplicar paréntesis en todas partes para las matemáticas, razón por la cual lo apoyé, pero hubo una reacción violenta, y eso me preocupa aquí. Entonces, ¿hay algún caso legítimo en el que confundiríamos 10px\10 con la intención del desarrollador de escapar de \10 ? Sé que es una teoría difícil, y probablemente tu punto sea que no sabemos realmente ... Es una pregunta complicada, y agregar una nueva sintaxis siempre es complicado, especialmente con Less, ya que no conocemos todo el CSS en el CSS salvaje ni futuro.

En cuanto a calc, supongo que tuvimos un consenso desde el principio, por lo que básicamente solo se espera a que un voluntario lo implemente (estimo que la solución rápida se realizará en solo 5-6 líneas de código nuevo, por lo que en realidad solo se trata de un valiente para hacer esto: los detalles menores de implementación pueden variar, pero creo que están bien para decidirse en el proceso).

¡Bien! ¿Deberíamos rastrearlo por separado para aumentar la visibilidad?

@ siete-fases-max:

Claro, apenas encuentras ese código en proyectos reales (excepto tal vez en los trucos como, por ejemplo, \9 )

Correcto . Oh, esos revoltosos "occidentales" ... :)

@ siete-fases-max
Responda la pregunta simple: "¿Cómo 0 + 1/2 puede ser posiblemente mejor que (1/2)?"

No veo a dónde vas con eso. (1/2) debe ser ejecutado por MENOS porque no es posible que sea CSS válido, por lo que debe significar MENOS. 0 + 1/2 debería convertirse en 1/2 donde LESS ejecuta la parte 0 + 1 porque esa es la parte que no puede ser CSS válida. La parte 1/2 podría ser válida, así que es mejor no tocarla.

@gracias
Bien, ahora date cuenta de que (1/2) funciona como esperas tanto en Less como en Sass ..
Y 0 + 1/2 (así como 1 * 1/2 etc.) es la parte de la solución que llamas brillante arriba y el resultado de "la solución brillante" es 0.5 .
¿Aún no tienes idea de lo que está pasando aquí?
Vuelve a leer todo (empezando por tu primera publicación) de arriba una vez más y trata de responderte a ti mismo "¿De qué me estoy quejando

@ siete-fases-max
Y 0 + 1/2 (así como 1 * 1/2, etc.) es la parte de la solución que llamas brillante arriba y "la solución brillante" resut es 0.5.

No, la solución sería 1/2 no 0.5 , ya que 1/2 podría ser CSS válido. No parece que desee que LESS sepa cuándo una barra es válida, así que asuma que siempre podría serlo. Por lo tanto, 1/2 es el único resultado lógico. De la misma manera, 2 * 1/2 daría como resultado 2/2 , porque * lo contrario lo convertiría en CSS inválido.

¿Aún no tienes idea de lo que está pasando aquí?

Tengo perfectamente claro lo que está pasando aquí. LESS está ejecutando divisiones matemáticas con entusiasmo y ciegamente ignora las unidades.

Vuelve a leer todo (empezando por tu primera publicación) de arriba una vez más y trata de responderte a ti mismo "¿De qué me estoy quejando exactamente?".

No hay necesidad de ataques personales.

LESS está ejecutando divisiones matemáticas con entusiasmo y ciegamente ignora las unidades.

Así que esto es de lo que te quejas, ¿verdad?

No hay necesidad de ataques personales.

Entonces, ¿qué debo hacer en su lugar? ¿Repetir las dos publicaciones originales una y otra vez (y otra vez)? Hasta que te quede claro:
@comunidad :

usar la opción -sm

@gracias :

entonces debería estar activado de forma predeterminada.

@ siete-fases-max:

No puede ser porque esto rompería inmediatamente un trillón de proyectos. Entonces, si trata el comportamiento predeterminado como un problema, simplemente configure la opción documentada y listo.


Entonces estás repitiendo "debería", "debería", "debería" ¿esperando qué? Supongo que para nosotros es más fácil responder simplemente "No, no debería" en lugar de perder el tiempo tratando de explicar en detalle por qué lo que sugieres no va a funcionar o no tiene sentido en general (las explicaciones que no quieres entender o simplemente no puedo).


Entonces, ¿de qué se trata este hilo? Se trata de "darse cuenta de que, si bien es inevitable un eventual cambio radical de hacer un comportamiento predeterminado" -sm similar a margin: (1/2) (3/4) (5/6) (7/8); para aquellos que usa mucho el aritmo ".
Sus publicaciones aquí sugieren algo que no es mejor que (o hace exactamente lo mismo) el comportamiento de -sm ya existente o discute algo que está fuera de discusión desde el principio (como allí ). En otras palabras, solo un ruido aleatorio .

@ seven- phase -max

Creo que la mayoría de la gente está en la misma página acerca de estos dos, idealmente, no siendo interpretados por Less como una expresión matemática:

font: 12px/10px;
width: calc(100% - 20px);

Por lo tanto, hay mayor acuerdo sobre esos puntos, y la mayoría de los argumentos giran en torno a posibles soluciones. El problema calc() parece que tiene suficiente consenso para seguir adelante. Básicamente: no toque calc y trate las vars en calc() como una interpolación de cadenas. Así es como lo hace Sass, aunque requiere la sintaxis de interpolación en calc() , que no creo que necesitemos.

Las soluciones a la parte font se vuelven mucho más complicadas y las soluciones líderes han sido:

  1. Requerir parens para todo de forma predeterminada (primer intento, casi implementado, pero la comunidad rechazado)
  2. Gire el interruptor strictMath (que se agregó en lugar de convertirlo en el predeterminado, y la sugerencia de @ seven-phase-max) y luego explícitamente haga todos sus cálculos. Es, técnicamente, una posible solución para la mayoría de las personas en la actualidad, pero ... la pregunta surge con tanta frecuencia y sabemos, psicológicamente, que alguien nuevo en cualquier sistema probablemente mantenga los valores predeterminados, por lo que es problemático. Y no todos los desarrolladores pueden cambiar su configuración de compilación, especialmente en equipos.
  3. Esencialmente, cambie el operador de división en Less. El contendiente líder en el hilo ha sido ./ , que funciona pero es un poco extraño de ver. \ es un desconocido en este momento sin investigación. Podría funcionar, podría causar conflictos desconocidos al escapar. Es una sintaxis más limpia, con un riesgo (potencialmente, pero desconocido) mayor. Si alguien se toma el tiempo para demostrar que esto NO causará conflicto, es decir, proporcionar ejemplos de escape y matemáticas entremezclados de manera que el analizador pueda distinguir claramente los dos, entonces todavía es una posibilidad. Así que solo se necesita trabajo. @gracias , si tú o alguien más es fanático de esto, entonces este es el trabajo requerido. Lo último que queremos es mover las pausas a otro lugar.

Creo que, para simplificar este hilo, deberíamos, desde aquí, centrarnos SÓLO en #3 . Publiqué el ejemplo de Sass principalmente como una curiosidad, pero no creo que esas soluciones sean buenas o resuelvan completamente el problema, y ​​son conceptualmente incompatibles con Less. Discutir sobre la validez de exigir 0 + 1/2 no nos va a llevar a ninguna parte.

Entonces, con una buena solución sobre la mesa por calc() , que nos lleva al 50% del camino allí para la mayoría de los problemas publicados, recomendaría centrarse solo en esta pregunta a corto plazo:

Si se debe cambiar el operador de división Menos, ¿a qué se debe cambiar?

  • ./ - ¿Es esto tan incómodo como siento, o la gente piensa que está bien?
  • \ - sin investigación y pruebas, y pseudocódigo para que lo siga un analizador, esto no avanzará. Personalmente lo preferiría, si se puede demostrar que es seguro.
  • ¿Otros reemplazos?

Honestamente, si cambiamos calc() y cambiamos / , creo que silenciaríamos el 99% del ruido relacionado con las matemáticas en Less.

Hola a todos, arreglé calc() - https://github.com/less/less.js/pull/3162

Me sorprendió un poco cuando se me ocurrió una solución que funcionó sin mucho código adicional. Básicamente, ya teníamos código para el interruptor strictMath , y verificamos las expresiones para no evaluar las matemáticas si estaban fuera de los parens, así que simplemente agregué un interruptor adicional en la llamada para desactivar las matemáticas mientras evaluaba el calc() args, y luego de nuevo. Ya teníamos todas las piezas para dejar las matemáticas en paz, pero aún así sustituimos vars. Eh.

Consulte https://github.com/less/less.js/pull/3162/files#diff -a94aaffd78b1d3c5eda7a42d5be1ca0d y https://github.com/less/less.js/pull/3162/files#diff -4e696271823c96903abab6fff84983

¿Son suficientes las pruebas?

@ matthew-dean: café:

¿Son suficientes las pruebas?

según los comentarios en el PR, agregue una prueba como:

foo: 1 + 2 calc(3 + 4) 5 + 6; // expected result: 3 calc(3 + 4) 11;

Y un comentario menor: esta solución, obviamente, introduce el mismo problema que en # 1627, es decir

<strong i="13">@a</strong>: floor(1.1);
<strong i="14">@b</strong>: floor(1 + .1);

div {
    foo: calc(<strong i="15">@a</strong> + 20%); // ok
    bar: calc(<strong i="16">@b</strong> + 20%); // error: invalid floor arguments
    baz: @b;             // ok
}

Pero por calc está bien, supongo (después de todo, simplemente no hay otras formas simples de solucionarlo sin una rehacer importante del concepto de evaluación perezosa). Entonces creo que es solo una cuestión de poner un aviso en los documentos para tener en cuenta lazy-eval al usar vars dentro de calc .

Y un comentario menor: esta solución obviamente presenta el mismo problema que en el n. ° 1627

¡Buena atrapada!

Cambiar la propiedad de contexto mathOn por llamada resuelve esto, similar a su comentario en el PR. ¡Agregué una prueba por float(1 + .1) que pasa!

Cambiar la propiedad de contexto mathOn por llamada resuelve esto, similar a su comentario en el PR. ¡He agregado una prueba para float (1 + .1) que pasa!

:) No, el error "piso" debe estar ahí cuando -sm: off . Vea mi comentario más reciente en el PR.
La restauración solo se ocupa de cosas similares a 1 + 2 calc(3 + 4) 5 + 6 .

:) No, el error "piso" debe estar ahí cuando -sm: off.

¿Por qué? Cualquier función dentro de calc() debería ser funciones Less. Incluso si no lo son, no hay funciones nativas de CSS dentro de calc () que yo sepa que puedan tomar expresiones matemáticas sin procesar. El resultado esperado sería evaluar vars y funciones Less, pero dejar las funciones sin procesar dentro de calc() solas.

Nota al margen: hice un experimento de rama de cambiar / a \ como operador de división en Less. Ya hay muchas pruebas para escapar (y agregué más, para abordar: # 3160), y todas todavía funcionan bien, y las matemáticas funcionan bien con los operadores cambiados. No vi ningún conflicto inherente. La rama está aquí en mi bifurcación: https://github.com/matthew-dean/less.js/commit/509d34fff7e234846afa150b099cd259755a39d0

Re: funciones anidadas

Para esto:

div {
    bar: calc(floor(1 + .1) + 20%);
}

Como desarrollador, el resultado esperado debería ser:

div {
    bar: calc(1 + 20%);
}

Eso es exactamente lo que sucede ahora (con estos cambios). No debería arrojar un error.

@ matthew-dean
No, de la forma en que lo escribiste, esto:

foo: unit(1/2, px);

con -sm:on se compilará en:

foo: .5px;

^ - mal.
Lo mismo para las funciones anidadas. Además, el hecho de que la mayoría de las funciones no puedan tomar expresiones aritméticas como argumento no es una razón para violar -sm: on ;
Por lo tanto, debajo de -sm: on ambas líneas:

foo: floor(1 + .1);
bar: calc(floor(1 + .1) + 20%);`

debe arrojar un error (y esto es lo que se rompe en la confirmación).

¿De qué estás hablando?

unit(1/2, px) con -sm:on :

ERROR: error evaluating function `unit`: the first argument to unit must be a number. Have you forgotten parenthesis?

calc(floor(1 + .1) + 20%) con -sm:on

ERROR: error evaluating function `floor`: argument must be a number

Mira la sucursal. Pruébalo.

Una cosa que podría ser más útil al revisar el código es que si no está seguro de si algo producirá un resultado incorrecto, verifíquelo. O pídeme que pruebe una entrada específica para verificar que funciona como se esperaba. O haga preguntas si no está seguro de cómo o por qué funciona. Llamarlo incorrectamente sin saber si lo es no es útil.

Mis disculpas. Supongo que me perdí el control indirecto de esta parte .

Mira la sucursal. Pruébalo

No puedo, lo siento.

Mis disculpas. Supongo que me perdí el control indirecto de esta parte.

No hay problema. Con eso abordado, ¿parece que está funcionando como cabría esperar?

Con eso abordado, ¿parece que está funcionando como cabría esperar?

Sí, hasta ahora no puedo imaginar otras cosas sospechosas allí.

@ matthew-dean
Esencialmente, cambie el operador de división en Less. El principal contendiente en el hilo ha sido ./, que funciona pero es un poco extraño a la vista. \ es un desconocido en este punto sin investigación [...] @thany , si tú o alguien más es fanático de esto, entonces este es el trabajo requerido. Lo último que queremos es mover las pausas a otro lugar.

En realidad, no. Sugerí el operador \ como último recurso después de no pasar, tratando de que LESS solo hiciera sus propias matemáticas. Si lo que se necesita es un nuevo operador de división ... Bueno, calc() también puede hacer sumas, restas y multiplicaciones. ¿Nuevos operadores para esos? Creo que no es práctico. Un nuevo operador de división podría ser una solución para cosas como la fuente, el fondo y el radio del borde, pero no es una solución para las matemáticas de CSS.

Sigo pensando que la solución real es que MENOS sepa sobre el contexto. Debería (sí, aquí voy de nuevo con mi "debería", ¿qué otra palabra debo usar? ...) saber que calc() es una función CSS y solo debería evaluar matemáticas que CSS no puede hacer . Pero floor() no existe en CSS, por lo que tendría que evaluar uno (por completo) para no arrojar CSS no válido. Sin embargo, creo que esto se mencionó antes, con una redacción diferente.

Sigo pensando que la solución real es que MENOS sepa sobre el contexto. Debería (sí, aquí voy de nuevo con mi "debería", ¿qué otra palabra debo usar? ...) saber que calc () es una función CSS y solo debería evaluar matemáticas que CSS no puede hacer. Pero floor () no existe en CSS, por lo que tendría que evaluar (por completo) para no arrojar CSS no válido. Sin embargo, creo que esto se mencionó antes, con una redacción diferente.

Bastante justo re: \ , pero en lo que respecta al contexto, según sus otras publicaciones, puedo garantizar que es un problema mucho más complejo de lo que cree. Realmente tienes que reducirlo a:

12px/10px  // Is this division, or not?
10px/1.5 // is this division, or not? 

Si desea dejar definitivamente / como operador de división, para imitar calc() , y no ser ambiguo, entonces es absolutamente necesario asegurarse de que / esté en paréntesis (excepto la excepción calc() ). Eso proporcionaría un contexto predecible.

Esa sugerencia al comienzo de este hilo también es todavía una posibilidad, y tuvo un fuerte apoyo. Esencialmente, que la configuración predeterminada sea que todas las matemáticas sean compatibles fuera de los paréntesis EXCEPTO la división (y nuevamente, excepto calc() , ahora es el caso de 3.0+). Quizás ese sea el camino a seguir. Eso permitiría:

font: 10px/1.5;   // not division
font: (10px/10);  // division, result is 1px
font: 10px+15px/1.5;   // addition but not division, result is 25px/1.5
font: (10px+15px/1.5);  // result is 20px

La cuestión es que el resultado de 10px+15px/1.5 aún podría ser difícil de asimilar para los desarrolladores, con una expresión que parece ser "medio evaluada" a menos que esté entre paréntesis. Si hubiéramos seguido adelante y activado las matemáticas estrictas de forma predeterminada, probablemente habría estado bien. Es incluso menos ambiguo. [encogiéndose de hombros] De cualquier manera, envolver las matemáticas en algún tipo de contexto ES la forma de eliminar la ambigüedad, y la única forma de división que no sea cambiar el operador de división.

La comunidad tiene que decidir esencialmente la dirección. Hay opciones viables en este hilo. Cada uno tiene sus desventajas. Cada uno tiene puntos débiles. Ninguno tendrá pleno consenso. Pero en mi opinión, cualquiera de ellos es mejor que el escenario actual. Solo tengo que tragar esa pastilla.

Última llamada para tomar una decisión

Entonces, en un esfuerzo por trabajar lo imposible, me gustaría proponer que hagamos esto (refiriéndome a los comentarios de hace 3 años).

Dar configuración de --strict-math 3

  1. apagado
  2. división
  3. estricto (alias on para compatibilidad con versiones anteriores)

Para resolver el debate, permita que el interruptor --strict-math=division haga lo siguiente:

  1. No realice la división con solo el carácter / fuera del paréntesis. Por ejemplo, border-radius: 55px / 25px; -> no-math (sí, eso es CSS válido)
  2. Permita la división con dos métodos diferentes:
    una. . prefijo - border-radius: 55px ./ 25px;
    B. paréntesis - border-radius: (55px / 25px);
  3. Ambas formas son válidas entre paréntesis, por ejemplo, border-radius: (55px ./ 25px); sería válido

Entonces, como desarrollador, si cree que una versión no es su preferencia, puede usar la otra. Algunos pueden preferir no usar paréntesis; algunos pueden preferir no utilizar un operador de división modificado. Algo para todos. Y no más sorpresas desagradables para los nuevos en Less que usan lo que ahora es una sintaxis generalizada en CSS, con / se usa en font , background , border-radius , @media consultas, propiedades de CSS Grid y probablemente más en el futuro.

Próximos pasos

Recomiendo que esto entre en un PR como una opción, y luego, como se discutió, se cambia como predeterminado para una futura versión principal.

@ matthew-dean

Es decir, ¿el período actúa como el inverso de una secuencia de escape?
No es mala idea, de verdad...

Y considerando todas las cosas, _probablemente_ una de las soluciones más limpias posibles.

@rjgotten Empecé aquí: https://github.com/matthew-dean/less.js/tree/strict-math-division

Sigo recibiendo un error extraño en una de las pruebas, donde parece convertir uno de los nodos de dimensión en un nodo de operación (y luego arroja un error porque no puede realizar una operación en un nodo de operación. No lo hace ' Parece ser un problema de análisis porque otra prueba que no se ejecuta por debajo de strictMath: division funciona bien. ¿Quieres comprobarlo y ver si puedes ayudar?

Lo que me gustaría hacer es cerrar este problema y crear nuevos problemas que manejen las preguntas de matemáticas restantes. Específicamente:

  1. División de manejo y la función strictMath: 'division' .
  2. Manejo de matemáticas de unidades mixtas. Ver: https://github.com/less/less.js/issues/3047
¿Fue útil esta página
0 / 5 - 0 calificaciones