Подтвердить что ты не робот

Меньше 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 может вызывать переходы по цвету фона, коробке-тени, текстовому цвету и т.д.

4b9b3361

Ответ 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, например).