LESS ошибка рекурсии миксина для преобразования пикселей в rems

Я пытаюсь сделать миксин для правильного преобразования пикселей в относительные ems. Я хотел бы, чтобы он был достаточно гибким, чтобы любое свойство можно было использовать с любым количеством значений пикселей.

Любые идеи о том, как добавить несколько значений к одному свойству без ошибки рекурсии, которую я создаю внутри цикла for?

желаемый пример использования 1:

.pixels-to-rems(font-size; 10);

желаемый результат:

font-size: 10px;
font-size: 1rem;

желаемый пример использования 2:

.pixels-to-rems(padding; 10,0,20,10);

желаемый результат:

padding: 10px, 0px, 20px, 10px;
padding: 1rem, 0px, 2rem, 1rem;

Вот миксин как есть.

@baseFontSize: 10px;
.pixels-to-rems(@property, @pxvals) {
    @pxValue: null;
    @remValue: null;

    .for(@pxvals); .-each(@pxval) {
        @pxValue: @pxValue @pxval;
        @remValue: @remValue (@pxval / @baseFontSize);
    }

    @{property}: ~"@{pxValue}px";
    @{property}: ~"@{remValue}rem";
}

Миксин .for() найден здесь


person lynnwashere    schedule 06.02.2016    source источник
comment
См. Объединение. Очевидно, что поскольку merge будет объединять значения в одно и то же свойство, вам придется изолировать px и rem с помощью некоторого взлома (например, это).   -  person seven-phases-max    schedule 06.02.2016
comment
Что касается конкатенации переменных - нет, вы не можете конкатенировать значение переменной с собой (менее семантика переменных отличается - это не язык сценариев ). По-прежнему можно создать список измененных значений с помощью цикла, но для этого конкретного случая реализация на основе merge просто более проста.   -  person seven-phases-max    schedule 06.02.2016
comment
@ Гарри, я думаю, да (я просто подумал, что для такого случая использования я бы предпочел, чтобы кто-то написал плагин Less или CSS, чтобы справиться с этим без каких-либо миксинов, поскольку это не сильно отличается от автопрефиксов) .   -  person seven-phases-max    schedule 07.02.2016
comment
@seven-phases-max Большое спасибо за помощь! Ваш пример отлично подходит для использования заполнения. Однако по какой-то причине использование «размера шрифта» повторялось слишком много раз. Вот пример codepen и скомпилированный вывод с использованием вашего кода. Есть идеи, почему?   -  person lynnwashere    schedule 09.02.2016
comment
Это потому, что вызов .for(number) приводит к вызову .-each со значением индекса, считая от 1 до number (т.е. это). В вашем случае самый простой способ исправить это — просто удалить числовую часть кода .for (т.е. все, что до // .for-each). Например. как это.   -  person seven-phases-max    schedule 09.02.2016


Ответы (1)


См. раздел Объединить. Единственная хитрость заключается в том, что оператор слияния объединяет значения в одно и то же правило свойства, поэтому вам придется изолировать правила px и rem с помощью некоторого хака. Например вот так:

usage {
    .pixels-to-rems(padding, 10 0 20 10);
    .pixels-to-rems(font-size, 50);
}

// impl.:

@base-font-size: 10px;

.pixels-to-rems(@p, @vs) {
    .for(@vs); .-each(@v) {
        @{p}+_:     1px  * @v;
        @{p}@{-}+_: 1rem * @v / @base-font-size;
    }
    @-: ~" ";
}

// .for-each impl. (stripped from the snipped linked in the question)

.for(@array)                 {.for-impl_(length(@array))}
.for-impl_(@i) when (@i > 1) {.for-impl_((@i - 1))}
.for-impl_(@i) when (@i > 0) {.-each(extract(@array, @i))}

Демо.

person seven-phases-max    schedule 19.02.2016
comment
Это мило :) По крайней мере, мы можем использовать эту ветку для закрытия дубликатов, даже если мы на самом деле не рекомендуем это делать. - person Harry; 19.02.2016
comment
Большое спасибо @seven-phases-max! Работал идеально. - person lynnwashere; 22.02.2016