Less.js: Пользовательские свойства внутри встроенных функций, таких как `rgba ()` throw error

Созданный на 13 нояб. 2016  ·  14Комментарии  ·  Источник: less/less.js

Синтаксис содержимого настраиваемых свойств CSS очень разрешающий, но это вызывает проблемы при использовании таких свойств внутри встроенных функций, таких как rgba()

Пример:
Мой проект позволяет пользователю определять цвет акцента, на котором основан весь пользовательский интерфейс приложения и различные пользовательские компоненты. И я использую формат rgb из-за необходимости исчезать в определенных местах, а CSS не предоставляет ничего вроде fade(<strong i="8">@color</strong>, 50%) меньше. Таким образом я смогу сделать rgba( var(--color), 0.5 ) . Это работает в Chrome и поддерживается стандартом. Однако less вызывает следующую ошибку: error evaluation function 'rgba': color functions take numbers as parameters .

Пример кода:

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

Примечание. Это добавляемая библиотека, и я не хочу заставлять пользователей добавлять еще один этап сборки в свой рабочий процесс только для создания моей библиотеки less с их цветами. Вот почему я использую новые блестящие настраиваемые свойства (а также из-за возможности определения области видимости).

BTW: Есть ли какое-то временное обходное решение, которое пропустило бы такую ​​строгую обработку и все равно построило бы его? Это не похоже на то, что мне не хватает скобки во вложенных правилах.

feature request high priority

Самый полезный комментарий

Синтаксис содержимого настраиваемых свойств CSS очень разрешающий, но это вызывает проблемы при использовании таких свойств внутри встроенных функций, таких как rgba()

Пример:
Мой проект позволяет пользователю определять цвет акцента, на котором основан весь пользовательский интерфейс приложения и различные пользовательские компоненты. И я использую формат rgb из-за необходимости исчезать в определенных местах, а CSS не предоставляет ничего вроде fade(<strong i="9">@color</strong>, 50%) меньше. Таким образом я смогу сделать rgba( var(--color), 0.5 ) . Это работает в Chrome и поддерживается стандартом. Однако less вызывает следующую ошибку: error evaluation function 'rgba': color functions take numbers as parameters .

Пример кода:

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

Примечание. Это добавляемая библиотека, и я не хочу заставлять пользователей добавлять еще один этап сборки в свой рабочий процесс только для создания моей библиотеки less с их цветами. Вот почему я использую новые блестящие настраиваемые свойства (а также из-за возможности определения области видимости).

BTW: Есть ли какое-то временное обходное решение, которое пропустило бы такую ​​строгую обработку и все равно построило бы его? Это не похоже на то, что мне не хватает скобки во вложенных правилах.

напиши вот так ~

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

Все 14 Комментарий

Просто убегай .


Я поставил метку «Запрос функции», поскольку это определенно становится проблемой, когда настраиваемые свойства находятся в TR. Это легко исправить, отключив обнаружение ошибок для аргументов функций CSS (хотя это довольно печально, так как убивает важную часть языка - т.е. мы никогда больше не найдем ошибку, пока не отладим ее в браузере).

Настраиваемые свойства поддерживаются во всех браузерах, кроме IE11. Вероятно, они станут массовыми в течение следующего года, поэтому я думаю, что скоро должна появиться поддержка.

Меньше, AFAIK, также нет тестов на чрезвычайно разрешительный характер значений пользовательских свойств. Они могут содержать что угодно, даже точки с запятой, если они не являются токенами верхнего уровня (не содержатся в парах скобок или фигурных скобок). См .: https://www.w3.org/TR/css-variables/#syntax

Поскольку это изменение в любом случае требует проверки n-of-args (чтобы сохранить хотя бы некоторую проверку ошибок в функциях), также предполагается, что более новая реализация rgba также поддерживает форму с двумя аргументами для порядковых значений цвета, например :

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

Как нам вообще обрабатывать настраиваемые свойства в аргументах? Технически вы можете использовать var(--some-property) где угодно, и если Less пытается интерпретировать аргументы для встроенных функций CSS, таких как rgba() , это проблема. Хотя я не уверен, почему Less выдает строгие ошибки значений для встроенной функции CSS? Просто чтобы поддержать выражения?

Я вижу целую кучу встроенных функций CSS на https://github.com/less/less.js/blob/master/lib/less/functions/color.js#L34 , и большинство из них IMO не должно будь там. Less - это не линтер, и это не функции Less. Если синтаксический анализатор пытается стать супер-умным в функциях CSS, он потерпит неудачу. Итак, я думаю, что источник проблемы заключается в том, что Less в настоящее время исправляет обычные цветовые функции CSS, а не пропускает их.

Я не уверен, что это было добавлено для браузеров, которые еще не поддерживали rgb() rgba() ? Похоже, он был добавлен 4 года назад. Может быть, причина заключалась в том, чтобы добавить баланс к новым функциям цвета, которые еще не поддерживаются в браузерах? 🤔 @lukeapage ты еще не

Принимая во внимание мой комментарий в № 3214, для этой проблемы быстрое исправление было бы просто: «if (nargs <3/4) откат к строке css (ничего не возвращая)» в соответствующих реализациях функций.

(И более строгое исправление заключается в проверке каждого аргумента в каждой такой функции, чтобы решить, подлежит ли он оценке, и вернуть либо объект цвета, либо резервную копию строки CSS).

Учитывая мой комментарий в № 3214, быстрое исправление этой проблемы было бы просто: «if (nargs <3/4) откат к строке css (ничего не возвращая)» в соответствующих реализациях функций.

А аналогичная проверка на var() ?

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

То есть: должны ли мы сделать следующее:

  1. Разрешить передачу функций, если они не соответствуют n-args? Я предполагаю, что нам нужно будет специально помечать функции, поскольку в реестре функций нет ничего особенного (если мы не делаем что-то сумасшедшее, например toString() функцию и буквально подсчитываем аргументы с регулярным выражением - AFAIK, это единственный тип отражения в JS; вы может сделать это с помощью TypeScript, но это нам не помогает)
  2. Выдает ошибку, если несовпадающая функция используется в оценке другой функции Less.

Это интересная проблема, потому что введение настраиваемых свойств сделало функции CSS неразрешимыми во время компиляции. В какой-то степени мы, возможно, подошли к концу эры статической предварительной обработки. Но это совсем другое обсуждение.

Это интересная проблема, потому что введение настраиваемых свойств сделало функции CSS неразрешимыми во время компиляции.

На самом деле ничего нового. Все необходимые средства, чтобы справиться с этим с помощью Less, есть с версии v1.x - см. Ниже. Единственная проблема - написать код без вздутия живота.

Я предполагаю, что нам нужно будет специально помечать функции, поскольку в реестре функций нет ничего особенного.

Нет, функции должны просто возвращать undefined (или null ), если они обнаруживают, что не могут оценить свои аргументы: вот так (если они также не обнаруживают, что аргументы являются ошибочными на 100%, и лучше вызвать ошибку). .
А возвращаемое значение undefined заставляет оценщик функции вернуться к исходному строковому представлению: Demo .

И аналогичный чек на var()

Также нет, нет необходимости проверять var или что-то конкретное (в основном неизвестные вещи из будущего CSS). В этом-то и дело. Код должен проверять, что можно оценить (известные вещи), а не то, что невозможно оценить (неизвестные).
(хотя детали могут сильно зависеть от конкретной функции - это не так важно).


Кстати, обратите внимание, что --var также является встроенной функцией Less (как и любая ident(...) вещь), которая просто не реализована явно (следовательно, она просто возвращается к самостроковому представлению ), потому что в этом нет необходимости. Но плагин (например) может переопределить его собственной реализацией, которая может возвращать потенциально оцениваемое значение.

@ seven-phase-max Ну ладно, значит, вы думаете, что простое исправление состоит в том, чтобы эти функции CSS / Less возвращали undefined, а не выдавали ошибку (чтобы отображать как есть)? Это кажется разумным, тогда если функции нет. 2 (например, darken() ) не может интерпретировать аргумент (который на этом этапе будет оцениваться как анонимное значение rgba() ?), Он все равно должен выдавать?

Спорим с собой:

Также нет, нет необходимости проверять var() или что-то конкретное (в основном неизвестные вещи из будущего CSS).

С другой стороны, не было бы проблемой (и даже соблазнительно) обнаружить var специально, чтобы функция могла различать rgba(var(...), ...) и rgba(foo, ...) и при этом вызывать ошибку. для последнего, но это будет означать, что подобная проблема будет возникать каждый раз, когда они добавляют что-то новое в CSS.
(Думаю, оба варианта хороши, и это больше о поиске баланса и / или прогнозировании меньшей нагрузки для сопровождающих ...).

@ Мэтью-Дин

Это кажется разумным, тогда если функции нет. 2 (например, darken ()) не может интерпретировать аргумент (который на этом этапе будет оцениваться как анонимное значение rgba ()?), Он все равно должен выдавать?

Да, именно так - нам даже не нужен новый код для этого (хотя в идеале они (функции типа darken ) должны иметь более понятные сообщения об ошибках в этом случае, потому что текущие "a.toHSL is not a function" -подобные сообщения являются довольно запутанно).

Ну, еще не упомянуто, что что-то вроде rgba(calc(1),1,1) рассматривается браузерами как действительное (обратите внимание на аргументы calc и 3 против 4), поэтому нам, вероятно, не следует слишком умничать. Мне нравится идея просто выводить как есть, как общее правило, если это возможно.

Да, это то, что я имею в виду

Код должен проверять, что можно оценить (известные вещи), а не то, что невозможно оценить (неизвестные).

Единственные допустимые аргументы для Less rgba - это либо число, либо объект цвета (если мы также рассмотрим "neo" - "CSS4" -подобные формы, такие как rgba(#123, .42) ).
Все остальное является либо ошибкой, либо (неизвестным, но потенциально допустимым) значением CSS.

Синтаксис содержимого настраиваемых свойств CSS очень разрешающий, но это вызывает проблемы при использовании таких свойств внутри встроенных функций, таких как rgba()

Пример:
Мой проект позволяет пользователю определять цвет акцента, на котором основан весь пользовательский интерфейс приложения и различные пользовательские компоненты. И я использую формат rgb из-за необходимости исчезать в определенных местах, а CSS не предоставляет ничего вроде fade(<strong i="9">@color</strong>, 50%) меньше. Таким образом я смогу сделать rgba( var(--color), 0.5 ) . Это работает в Chrome и поддерживается стандартом. Однако less вызывает следующую ошибку: error evaluation function 'rgba': color functions take numbers as parameters .

Пример кода:

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

Примечание. Это добавляемая библиотека, и я не хочу заставлять пользователей добавлять еще один этап сборки в свой рабочий процесс только для создания моей библиотеки less с их цветами. Вот почему я использую новые блестящие настраиваемые свойства (а также из-за возможности определения области видимости).

BTW: Есть ли какое-то временное обходное решение, которое пропустило бы такую ​​строгую обработку и все равно построило бы его? Это не похоже на то, что мне не хватает скобки во вложенных правилах.

напиши вот так ~

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

@weivea В последней версии Less 3.x в этом нет необходимости, просто напишите rgba(var(--color-accent))

Была ли эта страница полезной?
0 / 5 - 0 рейтинги