使用LESS CSS在CSS关键帧中使用@符号和变量

时间:2012-02-06 19:40:13

标签: css escaping less mixins css-animations

我需要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的变量。有没有办法如何逃脱关键帧@符号或迫使LESS以某种方式正确渲染@name?

3 个答案:

答案 0 :(得分:13)

  

修改
  在LESS 1.4.0中将删除对(~"@{varname}")选择器的支持   要使原始解决方案起作用,只需引入一个临时变量并使用selector interpolation(LESS 1.3.1中的新增内容)。
  对于前面的示例,这将是:

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

下面的解释仍然使用旧的选择器,因为它是简洁的。如前所示,用新方法替换旧方法是微不足道的   我确实更新了代码示例,因为我们很多人盲目地复制粘贴代码。

预期语法为(vendorprefixed)(~"@keyframes @{name}") { ... }。但是,输出不正确(选择器合并到@keyframes name 0% { ... } @keyframes name 100% {}),因为@keyframes的树语法被定义为less Source code中的例外。

我狡猾的mixin背后的想法是通过选择器添加花括号。

  • 初始选择器为(~"@keyframes @{name}{") { ... } 这呈现为:@keyframes name {{ ... }
  • 由于{{看起来不太好,我添加换行符。我无法直接转义换行符,所以我决定创建一个变量@newline: `"\n"`;。减去parses anything between backticks as JavaScript,因此结果值是换行符。由于{ ... }要求“选择器”有效,我们选择动画的第一步0%
  • 花括号不匹配。要解决这个问题,我们最后可以添加一个虚拟选择器,它以(~"} dummy") { .. }开头。这很难看,因为添加了一个无用的选择器 但是等等,我们已经知道将按顺序添加特定于供应商的前缀。所以,让最后的第一个选择器为(~"@{pre}@@{vendor}keyframes @{name} {@{newline}0%") }对于之后的每个关键帧阻止 @{pre}
  • 现在我们已经处理了除最后一个块之外的每个块的结束花括号。我们不必使用无用的虚拟选择器,因为我们显然定义了关键帧以便使用它们。 animation-name是这样做的财产。我正在使用guarded mixin来实现此目的。

解决方案起初可能看起来有点尴尬,但它非常简洁。

"}@{newline}"

呈现为(注意关键帧内的缩进是一个。这是预期的,因为Less不知道我们在另一个块中,由于手动添加了大括号)。

使用LESS版本1.3.3和1.4.0-b1确认以下结果。

@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);

最后的说明:

  • 产生有效CSS的最短假人是$ 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; } 。示例:/**/ - &gt; (~"..") {/**/}

答案 1 :(得分:7)

更少版本1.7现在支持更好的方法:

MIXIN

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

INPUT

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

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

答案 2 :(得分:0)

也许这就是你想要的? 如果您定义@name: "ANIM_NAME";,那么我认为这就是:

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