EDIT
对(~"@{varname}")
选择器的支持将在 LESS 1.4.0 中删除。
要使原始解决方案起作用,只需引入一个临时变量并使用选择器插值(LESS 1.3.1 中的新功能)。
对于前面的示例,这将是:
@tmp: ~"@{varname}"
@{tmp} { ... }
下面的解释仍然使用旧的选择器,因为它更简洁。如前所示,用新方法替换旧方法是微不足道的。
不过,我确实更新了代码示例,因为我们很多人都盲目地复制粘贴代码。
预期的语法是 (vendorprefixed) (~"@keyframes @{name}") { ... }
。但是,输出不正确(选择器合并到),因为在less源代码@keyframes name 0% { ... } @keyframes name 100% {}
中将树语法@keyframes
定义为异常。
我巧妙的 mixin 背后的想法是通过选择器添加花括号。
- 初始选择器将是
(~"@keyframes @{name}{") { ... }
.
这呈现为:@keyframes name {{ ... }
- 由于
{{
看起来不太好,我添加了一个换行符。我无法直接转义换行符,所以我决定创建一个 variable @newline: `"\n"`;
。Less将反引号之间的任何内容解析为 JavaScript,因此结果值是换行符。由于{ ... }
需要“选择器”有效,我们选择动画的第一步,0%
.
- 花括号不匹配。为了解决这个问题,我们可以在最后添加一个虚拟选择器,它以
(~"} dummy") { .. }
. 这很难看,因为添加了一个无用的选择器。
但是等等,我们已经知道供应商特定的前缀将按顺序添加。所以,让最后的第一个选择器是(~"@{pre}@@{vendor}keyframes @{name} {@{newline}0%")
。
@{pre}
必须针对第一个关键帧块之后"}@{newline}"
的每个关键帧块。
- 现在我们已经处理了除了最后一个块之外的每个块的右花括号。我们不必使用无用的虚拟选择器,因为我们显然定义了关键帧以便使用它们。
animation-name
是这样做的财产。我正在使用受保护的 mixin来实现这一点。
该解决方案一开始可能看起来有些尴尬,但它非常简洁。
@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 的最短虚拟对象是
/**/
. 示例:(~"..") {/**/}
-> .. {/**/}
。