为什么我不能动画自定义属性(又名CSS变量)?

mbjcgjjk  于 2023-02-06  发布在  其他
关注(0)|答案(5)|浏览(147)

请参见此动画:

  • 金色div具有一个动画,其中自定义属性是动画

@keyframes roll-o-1动画--o)。
这将按步骤设置动画。

  • 银div有一个动画,其中的 normal 属性是动画

@keyframes roll-o-2动画化left)。
这将连续设置动画。

为什么金色的div动画不流畅
是否有也使用变量的解决方案?

#one {
  width: 50px;
  height: 50px;
  background-color: gold;
  --o: 0;
  animation: roll-o-1 2s infinite alternate ease-in-out both;
  position: relative;
  left: calc(var(--o) * 1px);
}

@keyframes roll-o-1 {
  0% {
    --o: 0;
  }
  50% {
    --o: 50;
  }
  100% {
    --o: 100;
  }
}

#two {
  width: 50px;
  height: 50px;
  background-color: silver;
  --o: 0;
  animation: roll-o-2 2s infinite alternate ease-in-out both;
  position: relative;
}

@keyframes roll-o-2 {
  0% {
    left: 0px;
  }
  50% {
    left: 50px;
  }
  100% {
    left: 100px;
  }
}
<div id="one"></div>
<br>
<div id="two"></div>
dohp0rv5

dohp0rv51#

当这个问题被问到的时候,自定义属性是不可能动画的,正如@temani afif正确指出的那样--
因为UA无法解释它们的内容
从那时起,CSS胡迪尼把CSS Properties and Values API specification
本规范扩展了[css-variables],允许通过两种方法注册具有值类型、初始值和定义的继承行为的属性:
一个JS API,registerProperty()方法
CSS at规则,即@property规则
现在,您可以注册自己的自定义属性(包括自定义属性的类型),从而可以为自定义属性设置动画。
要通过CSS注册自定义属性,请使用@property规则

@property --o {
  syntax: "<number>";
  inherits: false;
  initial-value: 0;
}

x一个一个一个一个x一个一个二个x
要通过javascript注册属性,请使用CSS.registerProperty()方法:

CSS.registerProperty({
      name: "--o",
      syntax: "<number>",
      initialValue: 0,
      inherits: "false"
   });
CSS.registerProperty({
  name: "--o",
  syntax: "<number>",
  initialValue: 0,
  inherits: "false"
});
#one {
  width: 50px;
  height: 50px;
  background-color: gold;
  --o: 0;
  animation: roll-o-1 2s infinite alternate ease-in-out both;
  position: relative;
  left: calc(var(--o) * 1px);
}

@keyframes roll-o-1 {
  0% {
    --o: 0;
  }
  50% {
    --o: 50;
  }
  100% {
    --o: 100;
  }
}

#two {
  width: 50px;
  height: 50px;
  background-color: silver;
  animation: roll-o-2 2s infinite alternate ease-in-out both;
  position: relative;
}

@keyframes roll-o-2 {
  0% {
    left: 0px;
  }
  50% {
    left: 50px;
  }
  100% {
    left: 100px;
  }
}
<div id="one"></div>
<br>
<div id="two"></div>

注意

浏览器支持目前仅限于chrome(v78+适用于registerProperty(),v85+适用于@property)edge和opera

qlckcl4x

qlckcl4x2#

根据质量标准:
可设置动画:否
然后
值得注意的是,它们甚至可以被转换或动画化,但由于UA无法解释它们的内容,它们总是使用"50%翻转"行为,该行为用于任何其他无法智能插值的值对。这会影响在通过animation属性中的var()函数引用时如何处理它。
因此,基本上,您可以在属性上使用过渡和动画,其中它们的值是使用自定义属性定义的,但您不能为自定义属性执行此操作。
请注意下面例子中的区别,我们可能认为两个动画是相同的,但实际上不是。浏览器知道如何动画left,但不知道如何动画left使用的自定义属性(也可以在任何地方使用)

#one {
  width: 50px;
  height: 50px;
  background-color: gold;
  animation: roll-o-1 2s infinite alternate ease-in-out both;
  position: relative;
  left: calc(var(--o) * 1px);
}

@keyframes roll-o-1 {
  0% {
    --o: 0;
  }
  50% {
    --o: 50;
  }
  100% {
    --o: 100;
  }
}

#two {
  width: 50px;
  height: 50px;
  background-color: silver;
  --o: 1;
  animation: roll-o-2 2s infinite alternate ease-in-out both;
  position: relative;
}

@keyframes roll-o-2 {
  0% {
    left: calc(var(--o) * 1px);
  }
  50% {
    left: calc(var(--o) * 50px);
  }
  100% {
    left: calc(var(--o) * 100px);
  }
}
<div id="one"></div>
<br>
<div id="two"></div>

使用过渡的另一个示例:
一个二个一个一个
我们有一个转换,但不是针对自定义属性的。它是针对背景的,因为在:hover状态下,我们将再次计算该值,因此背景将发生变化,转换将发生。
对于动画,即使在关键帧中定义了left属性,也不会有动画:

#one {
  width: 50px;
  height: 50px;
  background-color: gold;
  animation: roll-o-1 2s infinite alternate ease-in-out both;
  position: relative;
  left: calc(var(--o) * 1px);
}

@keyframes roll-o-1 {
  0% {
    --o: 0;
     left: calc(var(--o) * 1px);
  }
  50% {
    --o: 50;
     left: calc(var(--o) * 1px);
  }
  100% {
    --o: 100;
    left: calc(var(--o) * 1px);
  }
}

#two {
  width: 50px;
  height: 50px;
  background-color: silver;
  --o: 1;
  animation: roll-o-2 2s infinite alternate ease-in-out both;
  position: relative;
}

@keyframes roll-o-2 {
  0% {
    left: calc(var(--o) * 1px);
  }
  50% {
    left: calc(var(--o) * 50px);
  }
  100% {
    left: calc(var(--o) * 100px);
  }
}
<div id="one"></div>
<br>
<div id="two"></div>
xtupzzrd

xtupzzrd3#

不是所有的CSS属性都是可以动画的,你不能动画css变量。这是你可以动画https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties的属性列表

fiei3ece

fiei3ece4#

我可以使用新的CSS Properties and Values API Level 1实现这一点
(part胡迪尼俱乐部的成员W3C工作草案,截至2020年10月13日)
我只需要使用@property规则注册我的自定义属性

@property --o {
      syntax: "<number>";
      inherits: true;
      initial-value: 0;
    }

通过syntax属性,我声明这个自定义属性为 * type * <number>,它提示浏览器应该以什么方式进行这个属性的转换或动画计算。
此处列出了syntax属性支持的值
"""
"""
"""
"""
"""
"""
"""
"""
"""
"""
"""
"""
浏览器兼容性出奇的强,因为这是一个实验性的功能,还处于草案状态(另见caniuse). Chrome和Edge支持它,Firefox和Safari不支持.
x一个一个一个一个x一个一个二个x

bfnvny8b

bfnvny8b5#

也许这不是你想要的答案,但是我用javascript动画实现了这个(fx和gsap)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body,html {
            height: 100%;
            display: flex;
        }

        .wrapper {
            margin: auto 0;
        }

        .box {
            --animate:0;
            background-color: tomato;
            height: 70px;
            width: 70px;
            transform: translateX(calc(var(--animate) * 1px)) rotate(calc(var(--animate) * 1deg));
        }
    </style>
</head>
<body>
    
    <div class="wrapper">
        <div class="box"></div>
        <button onclick="play()">Play</button>
    </div>
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.1/gsap.min.js" integrity="sha512-H6cPm97FAsgIKmlBA4s774vqoN24V5gSQL4yBTDOY2su2DeXZVhQPxFK4P6GPdnZqM9fg1G3cMv5wD7e6cFLZQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    <script>
        const tween = gsap.to(".box",{
            "--animate":900,   
            duration:10
        })

        tween.pause();

        function play() {
            tween.progress(0);
            tween.play();
        }
    </script>
</body>
</html>

相关问题