Знак @ и переменные в ключевых кадрах CSS с использованием LESS CSS

Мне нужно 8 различных анимаций CSS3, которые слишком похожи, поэтому я использовал для этого МЕНЬШЕ. Ниже приведен код, который отлично работает, но с одной маленькой ошибкой — переменной @name.

.animation_top (@name, @pxFrom, @pxTo) {
    @-moz-keyframes @name {
        0% {
            top: @pxFrom;
            opacity: 0;
        }
        100% {
            top: @pxTo;
            opacity: 1;
        }
    }

    @-webkit-keyframes @name {
        0% {
            top: @pxFrom;
            opacity: 0;
        }
        100% {
            top: @pxTo;
            opacity: 1;
        }
    }

    @-ms-keyframes @name {
        0% {
            top: @pxFrom;
            opacity: 0;
        }
        100% {
            top: @pxTo;
            opacity: 1;
        }
    }
}

Поскольку ключевые кадры css запускаются знаком @, LESS просто игнорирует переменную @name. Есть ли способ избежать знака ключевого кадра @ ИЛИ заставить LESS как-то правильно отображать @name?


person dck    schedule 06.02.2012    source источник


Ответы (3)


EDIT
Поддержка селектора (~"@{varname}") будет удалена в LESS 1.4.0.
Чтобы заставить исходное решение работать, просто введите временную переменную и используйте интерполяция селекторов (новое в LESS 1.3.1).
Для предыдущего примера это будет:

 @tmp: ~"@{varname}"
 @{tmp} { ... }

В приведенном ниже объяснении по-прежнему используется старый селектор, потому что он короче. И, как было показано ранее, заменить старый метод новым методом очень просто.
Тем не менее, я обновил пример кода, потому что многие из нас копируют и вставляют код вслепую.

Ожидаемый синтаксис (vendorprefixed) (~"@keyframes @{name}") { ... }. Однако вывод неверен (селекторы объединены в @keyframes name 0% { ... } @keyframes name 100% {}), поскольку синтаксис дерева @keyframes определен как исключение в less Исходный код.

Идея моего хитроумного миксина состоит в том, чтобы добавить фигурные скобки через селекторы.

  • Начальный селектор будет (~"@keyframes @{name}{") { ... }.
    Это выглядит так: @keyframes name {{ ... }
  • Поскольку {{ выглядит не очень хорошо, я добавляю новую строку. Мне не удалось избежать новой строки напрямую, поэтому я решил создать переменную @newline: `"\n"`;. Less разбирает что-либо между обратными кавычками как JavaScript, поэтому результирующее значение является символом новой строки. Поскольку { ... } требует, чтобы селектор был действительным, мы выбираем первый шаг анимации, 0%.
  • Фигурные скобки не совпадают. Чтобы исправить это, мы можем добавить в конец фиктивный селектор, который начинается с (~"} dummy") { .. }. Это некрасиво, потому что добавляется бесполезный селектор.
    Но подождите, мы уже знаем, что префиксы, зависящие от производителя, будут добавляться последовательно. Итак, пусть окончательный первый селектор будет (~"@{pre}@@{vendor}keyframes @{name} {@{newline}0%").
    @{pre} должен быть "}@{newline}" для каждого блока ключевых кадров после первого.
  • Теперь мы разобрались с закрывающей фигурной скобкой для каждого блока, кроме последнего. Нам не нужно использовать бесполезный фиктивный селектор, поскольку мы явно определяем ключевые кадры, чтобы их использовать. animation-name — это свойство для этого. Для реализации этого я использую защищенный миксин.

Решение может показаться несколько неуклюжим на первый взгляд, но оно достаточно лаконичное.

@newline: `"\n"`; // Newline
.animation_top(@selector, @name, @pxFrom, @pxTo) {
    .Keyframe(@pre, @post, @vendor) {
        @keyframe: ~"@{pre}@@{vendor}keyframes @{name} {@{newline}0%";
        @{keyframe} {
            top: @pxFrom;  
            opacity: 0;  
        }    
        100%  { 
            top: @pxTo;
            opacity: 1;
        }    
        .Local(){}
        .Local() when (@post=1) {
            @local: ~"}@{newline}@{selector}";
            @{local} {
                -moz-animation: @name;
                -webkit-animation: @name;
                -o-animation: @name;
                -ms-animation: @name;
                animation: @name;
            } 
        }    
        .Local;
    } 
    .Keyframe(""            , 0,    "-moz-");
    .Keyframe(~"}@{newline}", 0, "-webkit-");
    .Keyframe(~"}@{newline}", 0,      "-o-");
    .Keyframe(~"}@{newline}", 0,     "-ms-");
    .Keyframe(~"}@{newline}", 1,         ""); // <-- Vendorless w3
} 
.animation_top("#test", hey, 10px, 100px);

Отрисовывается как (обратите внимание, что отступ внутри ключевых кадров смещен на единицу. Это ожидаемо, потому что Less не знает, что мы находимся внутри другого блока из-за фигурных скобок, добавленных вручную).

Следующий результат подтверждается с использованием LESS версии 1.3.3 и 1.4.0-b1.

$ lessc --version
lessc 1.3.3 (LESS Compiler) [JavaScript]
$ lessc so
@-moz-keyframes hey {
0% {
  top: 10px;
  opacity: 0;
}
100% {
  top: 100px;
  opacity: 1;
}
}
@-webkit-keyframes hey {
0% {
  top: 10px;
  opacity: 0;
}
100% {
  top: 100px;
  opacity: 1;
}
}
@-o-keyframes hey {
0% {
  top: 10px;
  opacity: 0;
}
100% {
  top: 100px;
  opacity: 1;
}
}
@-ms-keyframes hey {
0% {
  top: 10px;
  opacity: 0;
}
100% {
  top: 100px;
  opacity: 1;
}
}
@keyframes hey {
0% {
  top: 10px;
  opacity: 0;
}
100% {
  top: 100px;
  opacity: 1;
}
}
#test {
  -moz-animation: hey;
  -webkit-animation: hey;
  -o-animation: hey;
  -ms-animation: hey;
  animation: hey;
}

Заключительные примечания:

  • Самый короткий манекен, который производит корректный CSS, это /**/. Пример: (~"..") {/**/} -> .. {/**/}.
person Rob W    schedule 14.06.2012

Меньшая версия 1.7 теперь поддерживает более приятный метод:

МИКСИН

.keyframes(@name) { 
    @-webkit-keyframes @name {
        .-frames(-webkit-);
    }
    @-moz-keyframes @name {
        .-frames(-moz-);
    }
    @keyframes @name {
        .-frames();
    }
}

ВХОД

& {
    .keyframes(testanimation);.-frames(@-...){
        0% {
            left: 0;
            @{-}transform: translate(10px, 20px);
        }

        100% {
            left: 100%;
            @{-}transform: translate(100px, 200px);
        }
    }
}
person Community    schedule 28.02.2014

Возможно, это то, что вы хотите? Если вы определяете @name: "ANIM_NAME";, то я предполагаю, что это так:

@-moz-keyframes @{name} {
...
...
}
person bzx    schedule 06.02.2012
comment
Боюсь, это не разберется. Я использую CodeKit для разбора LESS. - person dck; 07.02.2012
comment
странно, это допустимый синтаксис LESS. я пробовал с LessApp, и он действительно не анализируется... - person bzx; 07.02.2012
comment
Я думаю, LessApp должен быть таким же, поэтому мы имеем дело с одной и той же проблемой. Я пытался обновиться до последней версии, но мне не повезло, она не анализируется. Есть идеи сейчас? - person dck; 07.02.2012