7

I'm doing an animation with CSS variables, where a CSS variable value changes based on the page scroll. That variable is then used on animation with keyframes.

Originally it's updating correctly only on Firefox. Meanwhile, I found a way to make it work on Chrome too, by forcing a repaint, in this case, animate the color from #000 to #001.

/* --scale is dynamic changed by JS */

@keyframes move {
    0% {
        transform: translateX(0) scale(var(--scale));
        color: #000;
    }
    100% {
        transform: translateX(33vw) scale(1.5);
        color: #001;
    }
}

You can see a demo at codepen

sandrina-p
  • 3,794
  • 8
  • 32
  • 60
  • Any updates on this issue? – Dimitar Spassov Apr 29 '20 at 13:08
  • @DimitarSpassov, my workaround was to create 2 animations: The original one a an `moveExpensive` where I used `left` instead of `translateX`, forcing the repaint. Then with JS detect the browser. If it's FF use `move`, otherwise use `moveExpensive`. – sandrina-p Apr 29 '20 at 13:23
  • Maybe I'm doing something wrong, but on Safari the issue remains, even if I replace the `translateX` transformation with `left`. – Dimitar Spassov Apr 29 '20 at 13:40
  • Oh sorry, @DimitarSpassov, forgot to mention, I didn't use variables on the fallback version. In my case, I used hardcoded values (%) and did some other workarounds. In summary: I didn't find a way to make it work with CSS variables. – sandrina-p Apr 29 '20 at 17:58
  • Oh, alright. Thanks for the update. – Dimitar Spassov Apr 29 '20 at 19:44
  • Does this answer your question? [CSS animate custom properties/variables](https://stackoverflow.com/questions/50661638/css-animate-custom-properties-variables) – Mahozad Oct 20 '21 at 09:21

3 Answers3

6

I also ran into this issue and solved it by setting the element.style.animation attribute in JavaScript after calling setProperty(). It seems like @keyframes doesn't update after setting the animation in CSS.

Lorenzo
  • 1,605
  • 14
  • 18
3

This is a WebKit bug. I discovered this issue today by reading Safari Technology Preview 149 changelog, which means it should be fixed in Safari 16, to be released later this year.

Added support for custom properties in @keyframes rules (251733@main)

meduz'
  • 555
  • 4
  • 12
0

An alternative for those (like myself) who are using Styled Component's keyframes`` function, you can exchange the css variable for a prop by defining a function much like the following:

import styled, { Keyframes, keyframes } from 'styled-components';

const move = (scale: number): Keyframes => keyframes`
  0% {
      transform: translateX(0) scale(${scale});
      color: #000;
  }
  100% {
      transform: translateX(33vw) scale(1.5);
      color: #001;
  }
`

const AnimatedElement = styled.div<{ scale: number }>`
  animation: ${(props) => move(props.scale)} 2s linear infinite;
`
pklepa
  • 21
  • 4