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

Posted

技术标签:

【中文标题】使用 LESS CSS 的 CSS 关键帧中的 @ 符号和变量【英文标题】:@ sign and variables in CSS keyframes using LESS CSS 【发布时间】:2012-02-28 06:49:43 【问题描述】:

我需要 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?

【问题讨论】:

【参考方案1】:

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

 @tmp: ~"@varname"
 @tmp  ... 

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

预期的语法是(供应商前缀)(~"@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@@vendorkeyframes @name @newline0%")@pre 必须是"@newline" 对于每个关键帧块第一个。 现在我们已经处理了除了最后一个块之外的每个块的右花括号。我们不必使用无用的虚拟选择器,因为我们显然定义了关键帧以便使用它们。 animation-name 是这样做的属性。我正在使用guarded mixin 来实现这一点。

这个解决方案一开始可能看起来有些别扭,但非常简洁。

@newline: `"\n"`; // Newline
.animation_top(@selector, @name, @pxFrom, @pxTo) 
    .Keyframe(@pre, @post, @vendor) 
        @keyframe: ~"@pre@@vendorkeyframes @name @newline0%";
        @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 的最短虚拟对象是 /**/。示例:(~"..") /**/ -> .. /**/

【讨论】:

【参考方案2】:

Less version 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);
        
    

【讨论】:

【参考方案3】:

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

@-moz-keyframes @name 
...
...

【讨论】:

恐怕这不会解析。我使用 CodeKit 进行 LESS 解析。 奇怪,这是有效的 LESS 语法。我尝试使用 LessApp,但它确实无法解析...... LessApp 我认为应该是一样的,所以我们正在处理同样的问题。我试图更新到最新版本,但没有运气,它不会解析。现在有什么想法吗?

以上是关于使用 LESS CSS 的 CSS 关键帧中的 @ 符号和变量的主要内容,如果未能解决你的问题,请参考以下文章

将less文件转换成css文件

如何停止css animation动画

在开发环境中,使用scss或less代替css值得吗

让less本地生成css应该怎么做

Hbuilder中的less不能自动编译为css怎么办

less样式如何使用cssmodule