Article
0 comment

CSS Keyframe Animations in SharePoint Framework

Using a @keyframes animation in SPFx might not work for you. The reason is the built-in CSS Modules that needs a special treatment defining the animation and how you have to call them.
First, let’s take a look at the issue.

Base Key Frame animation

The following code defines a new keyframe animation:

@keyframes colorcycle {

  0% {
    background-color: #ee9105;
  }

  50% {
    background-color: #cc2741;
  }

  100% {
    background-color: #ee9105;
  }
}

This animation allows you to cycle the background colour from orange to red and back to orange. You could also see it more like key states of the animation. It only defines the keyframes at 0%, 50% and 100% animation completion.

To apply this animation, you have to define it in the following way.

.helloWorld {

  animation: 3s ease-in-out 1s infinite alternate colorcycle;

}

So all elements with the class name ‘.helloWorld’ would now cycle the background colour from orange to red to orange.

See the Pen
Untitled
by Stefan Bauer (@StfBauer)
on CodePen.0

CSS animations in SPFx

What should work on the browser should also work in the SharePoint Framework. Right? Well, yes and no. When you move this example over in a web part, you will encounter an error.

Webpack does not like keyframe animation, but the problem originates somewhere else. Like I mentioned in the beginning, CSS Modules here is the problem. This will become clear when we take a look at the compiled CSS.

Show the SPFx compiled code

There is a space missing between alternate and ‘:local’ on line 17. ‘:local’ is a keyword of CSS modules that indicates that the name should be replaced with the real compiled name. Normally something you would use in your code but not in the compiled code. Also, to note here, there cannot be a CSS pseudo-class in a property value.

The correct compilation should look like so:

@keyframes colorcycle_08eb0a76 {
   /* ... */
}

.helloWorld_08eb0a76 {
    /* irrelevant code go removed */
    animation: 3s ease-in-out 1s infinite alternate colorcycle_08eb0a76;
}

Browsing the forums on CSS Modules indicates that this is a well-known issue, and it seems like it was never fixed.

Fixing Keyframe animation

To fix the keyframe animations, we have two options.

Fix 1: Using local animations

To make the CSS keyframe animation work, we need to fix it ourselves in the code. Sadly we cannot use the short-handed code for keyframe animations, and we have to bloat our code a bit. Instead of using:

.helloWorld{
  animation: 3s ease-in-out 1s infinite alternate colorcycle;
}

We have to use the following code:

.helloWorld{

  // animation: 3s ease-in-out 1s infinite alternate colorcycle;
  animation-duration: 3s;
  animation-timing-function: ease-in-out;
  animation-delay: 1s;
  animation-iteration-count: infinite;
  animation-play-state: alternate;

    // make sure local animation name was used
  :local {
    animation-name: colorcycle;
  }

}

To ensure the local animation name is used, we have to wrap the ‘animation-name’ property in a CSS Modules specific ‘:local’ pseudo-class.

@keyframes colorcycle_02461852 {
  /** Removed animation to simplify **/
}

.helloWorld_02461852 {
    /** removed all non animation content **/
    animation-duration: 3s;
    animation-timing-function: ease-in-out;
    animation-delay: 1s;
    animation-iteration-count: infinite;
    animation-play-state: alternate
}

.helloWorld_02461852 {
    animation-name: colorcycle_02461852
}

So you end up with two times a class definition in the resulting CSS file. Not a big issue because the definitions cascade through and take all available properties. You don’t win a beauty contest, but it works, which matters.

Fix 2: Global animations

Another way to fix this issue is to make the animation global available on the page. Here we need to fix the code in two places:

@keyframes :global(colorcycle) {
  /** Removed animation to simplify **/
}

.helloWorld {
  /** Removed animation to simplify **/
  :global {
    animation: 3s ease-in-out 1s infinite alternate colorcycle;
  }\

}

So first, we need to make the @keyframes global available. This can be done by surrounding the animation’s name in this way – ‘:global(colorcycle)’.
The second thing is to wrap the animation definition in a global pseudo-class. This time we can use the shorthand definition.

Now everything compiles correctly again.

@keyframes colorcycle {
  /** Removed animation to simplify **/
}

.helloWorld_f060c990 {
  /** Removed animation to simplify **/}

.helloWorld_f060c990 {
    animation: 3s ease-in-out 1s infinite alternate colorcycle
}

How does it look in SharePoint

Initial detection of this issue

Initially I was able to identify this issue with animation coming from a 3rd party tool like the Fluent UI implementation hTWOo. It is currently there in testing and should be fixed in an upcoming release.

Leave a Reply

Required fields are marked *.


This site uses Akismet to reduce spam. Learn how your comment data is processed.