Меньше CSS: миксины с переменным числом аргументов
LESS позволяет параметрические микшины, такие как:
.transition(@property, @duration){
transition: @property @duration;
-moz-transition: @property @duration; /* Firefox 4 */
-webkit-transition: @property @duration; /* Safari and Chrome */
-o-transition: @property @duration; /* Opera */
}
Однако это не всегда работает со свойствами, такими как переходы. Если вы пытаетесь иметь несколько переходов и пытаетесь вызвать mixin несколько раз, последний mixin переопределяет все ранее определенные переходы. Это потому, что правильный синтаксис CSS3 для определения нескольких переходов:
... {
transition: @property1 @duration1, @property2 @duration2, ...;
}
Единственный способ, с помощью которого я могу определить несколько переходов в качестве миксинов, - это перегрузить mixin:
.transition(@property, @duration){...}
.transition(@property, @duration, @prop2, @dur2){...}
.transition(@property, @duration, @prop2, @dur2, @prop3, @dur3){...}
Существует ли более надежный и лаконичный способ определения переходного mixin для принятия переменного количества аргументов и построения соответствующего перехода CSS?
Контекст: Иногда мне хотелось бы перейти на несколько свойств; например, :hover
может вызывать переходы по цвету фона, коробке-тени, текстовому цвету и т.д.
Ответы
Ответ 1
См. мой ответ здесь: Несколько свойств обрабатываются как отдельные аргументы в mixins
Сводка: используйте этот mixin для переменного количества аргументов:
.transition (@value1,@value2:X,...)
{
@value: ~`"@{arguments}".replace(/[\[\]]|\,\sX/g, '')`;
-webkit-transition: @value;
-moz-transition: @value;
-ms-transition: @value;
-o-transition: @value;
transition: @value;
}
Ответ 2
UPDATE для LESS 1.3.3 +
Вывод одинаков, но обратите внимание на разницу в том, как свойства могут передаваться в более поздних версиях LESS, используя точку с запятой вместо выполнения строки с экранированием:
@prop1: color;
@prop2: opacity;
@dur1: 3s;
@dur2: 4s;
.transition(@transString: 0) when not (@transString = 0) {
transition: @transString;
-moz-transition: @transString; /* Firefox 4 */
-webkit-transition: @transString; /* Safari and Chrome */
-o-transition: @transString; /* Opera */
}
.class1 {.transition();}
.class2 {.transition(width 2s, height 2s;);}
^
semicolon here
.class3 {.transition(@prop1 @dur1, @prop2 @dur2;);}
^
semicolon here
Точка с запятой заставляет запятые оцениваться как разделители списков, а не разделители параметров.
Одно решение для LESS до 1.3.3
Мы строим правильные аргументы свойств как строку для transition
, а затем используем оператор escaped value (~
), чтобы перевести его в требуемый синтаксис. С помощью строковой интерполяции (@{variableName}
) мы можем даже вставлять переменные в этот процесс, но фактический вход должен быть в виде экранированной строки.
МЕНЬШИЙ код
@prop1: color;
@prop2: opacity;
@dur1: 3s;
@dur2: 4s;
.transition(@transString: 0) when not (@transString = 0) {
transition: @transString;
-moz-transition: @transString; /* Firefox 4 */
-webkit-transition: @transString; /* Safari and Chrome */
-o-transition: @transString; /* Opera */
}
.class1 {.transition();}
.class2 {.transition(~" width 2s, height 2s");}
.class3 {.transition(~" @{prop1} @{dur1}, @{prop2} @{dur2}");}
Выход CSS
Примечание: no .class1
выводится, потому что выражение guard гарантирует, что что-то введено (хотя оно не защищает от неправильного ввода).
.class2 {
transition: width 2s, height 2s;
-moz-transition: width 2s, height 2s;
-webkit-transition: width 2s, height 2s;
-o-transition: width 2s, height 2s;
}
.class3 {
transition: color 3s, opacity 4s;
-moz-transition: color 3s, opacity 4s;
-webkit-transition: color 3s, opacity 4s;
-o-transition: color 3s, opacity 4s;
}
Ответ 3
В LESS вы можете разделить аргументы с помощью запятых или полуколоней. Для одиночных значений, содержащих запятые, вы можете завершить одно значение с помощью двоеточия, чтобы отправить список как одно значение, например:
.class {
.background-size(100%, auto;);
}
Для нескольких значений просто используйте этот синтаксис:
/* Example mixin */
.set-font-properties(@font-family, @size) {
font-family: @font-family;
font-size: @size;
}
/* Usage with comma-separated values */
.class {
.set-font-properties(Arial, sans-serif; 16px);
}
/* Output */
.class {
font-family: Arial, sans-serif;
font-size: 16px;
}
Легкий peasy!
Ответ 4
Это должно работать, я думаю:
.transition(...) {
transition: @arguments;
-moz-transition: @arguments; /* Firefox 4 */
-webkit-transition: @arguments; /* Safari and Chrome */
-o-transition: @arguments; /* Opera */
}
...
- это действительный меньше синтаксиса, а не что-то, что нужно заменить.
Ответ 5
Примечание.. Этот ответ не добавляется с намерением сказать, что существующие ответы неверны или устарели. Все ответы действительны и будут работать. Этот метод просто предлагает другой метод, который, на мой взгляд, несколько более сложный, но также более гибкий с точки зрения того, как каждый аргумент может упоминаться как пары ключ-значение.
Преимущества использования этого метода: Этот метод станет более полезным, когда необходимо выполнить любую дополнительную операцию над значениями (например, добавив unit
как deg
, px
или выполнение каких-либо дополнительных математических операций и т.д.) или динамическое добавление префиксов поставщиков для @property
. Например, есть моменты, когда вы захотите передать только transform
в качестве свойства ввода в mixin, но хотите добавить -webkit-transform
для -webkit-transition
и -moz-transform
для -moz-transition
и т.д.
В этом методе мы используем функцию ...
, которая позволяет нам передавать переменное количество аргументов в mixin, цикл по каждому передаваемому аргументу, extract
имя свойства вместе с дополнительными параметрами (например, длительность, степень поворота и т.д.), а затем используйте функция слияния, которая предоставляется Менее, чтобы объединить значения, указанные для свойства.
-
+:
объединяет значения свойств с запятой и вводится в Less v1.5.0
-
+_:
объединяет значения свойств с пробелом и вводится в Less v1.7.0.
.transition(@args...){
.loop-args(@argCount) when (@argCount > 0) {
.loop-args(@argCount - 1);
@arg: extract(@args, @argCount);
@property: extract(@arg,1);
@duration: extract(@arg,2);
-webkit-transition+: @property @duration;
-moz-transition+: @property @duration;
-o-transition+: @property @duration;
transition+: @property @duration;
}
.loop-args(length(@args));
}
div{
.transition(background, 1s; border-color, 2s; color, 2s);
}
.transform(@args...){
.loop-args(@argCount) when (@argCount > 0) {
.loop-args(@argCount - 1);
@arg: extract(@args, @argCount);
@property: extract(@arg,1);
@param: extract(@arg,2);
-webkit-transform+_: ~"@{property}(@{param})";
-moz-transform+_: ~"@{property}(@{param})";
-o-transform+_: ~"@{property}(@{param})";
transform+_: ~"@{property}(@{param})";
}
.loop-args(length(@args));
}
div#div2{
.transform(rotate, 20deg; scale, 1.5; translateX, 10px);
}
Вышеприведенный код при компиляции даст следующий результат:
div {
-webkit-transition: background 1s, border-color 2s, color 2s;
-moz-transition: background 1s, border-color 2s, color 2s;
-o-transition: background 1s, border-color 2s, color 2s;
transition: background 1s, border-color 2s, color 2s;
}
div#div2 {
-webkit-transform: rotate(20deg) scale(1.5) translateX(10px);
-moz-transform: rotate(20deg) scale(1.5) translateX(10px);
-o-transform: rotate(20deg) scale(1.5) translateX(10px);
transform: rotate(20deg) scale(1.5) translateX(10px);
}
Похожие ответы:
- Здесь - ответ от seven-phases-max, в котором объясняется, как этот метод можно использовать для auto добавьте префиксы поставщиков, как я упомянул в параграфе преимуществ.
Ответ 6
Current по состоянию на LESS 1.4, документация (http://lesscss.org/features/#mixins-parametric-feature-mixins-with-multiple-parameters) предлагает правильный способ справиться с этим:
Использование запятой в качестве разделителя миксинов делает невозможным создание запятой разделенные списки в качестве аргумента. С другой стороны, если компилятор видит хотя бы одну точку с запятой внутри вызова или декларации mixin, это предполагает, что аргументы разделяются точкой с запятой, и все запятые принадлежат спискам css:
Конкретно mixin:
.transition(@prop-or-props) {
-webkit-transition: @prop-or-props;
-moz-transition: @prop-or-props;
-o-transition: @prop-or-props;
transition: @prop-or-props;
}
использование:
.transition(opacity .2s, transform .3s, -webkit-transform .3s;);
Обратите внимание, что несколько свойств разделяются запятыми, а конечная полуколонна приводит к тому, что список, разделенный запятыми, рассматривается как один параметр в mixin.
Было бы лучше определить mixin с параметром rest...
и иметь возможность извлекать каждый элемент аргументов произвольной длины для отдельной обработки, но в прецеденте, о котором я думаю, добавляется префикс поставщика для преобразования (так что я мог бы назвать это просто с помощью .transition(opacity .2s, transform .3s)
и автоматически добавить бит -webkit-transform
), и, возможно, в любом случае это лучше обрабатывается другой утилитой (gulp -autoprefixer, например).