@ знак и переменные в ключевых кадрах CSS с использованием LESS CSS - PullRequest
10 голосов
/ 06 февраля 2012

Мне нужны 8 различных CSS3-анимаций, которые слишком похожи, поэтому я использовал LESS для этого.Ниже приведен код, который отлично работает, с одним небольшим затруднением - переменной @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.Есть ли способ, как избежать ключевого кадра @ sign ИЛИ заставить LESS каким-либо образом правильно отобразить @name?

Ответы [ 3 ]

13 голосов
/ 14 июня 2012

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

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

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

Ожидаемый синтаксис:(префикс поставщика) (~"@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 версии 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, - /**/.Пример: (~"..") {/**/} -> .. {/**/}.
7 голосов
/ 28 февраля 2014

Меньше версия 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);
        }
    }
}
0 голосов
/ 07 февраля 2012

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

@-moz-keyframes @{name} {
...
...
}
...