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