Css-loader: Keyframe and Animation Names are Not Applied

Created on 19 Apr 2016  路  11Comments  路  Source: webpack-contrib/css-loader

css-loader seems to take @keyframes animation names and cacheify them in a way where they are no longer appropriately applied. Per example:

I pulled a CSS loader with code like so

.cssload-loader {
        animation-name: cssload-loader;
}
@keyframes cssload-loader {
        from { transform: scale(0); opacity: 1; }
        to   { transform: scale(1); opacity: 0; }
}

and then in my React component

import LoaderStyles from 'styles/components/Loader';

//...

render () {
  return (
        <div className={LoaderStyles['wrapper']}>
          <div className={LoaderStyles['cssload-loader']}></div>
        </div>
  );
}

But the animation is never applied. The CSS that PostCSS/css-loader generates contains an animation name with cacheable values added, but apparently that animation does not exist?

.Loader__cssload-loader___2MBLL {
    animation-name: Loader__cssload-loader___2MBLL;
}

I cannot find anything in the issues here, on the googles, or on StackOverflow that explains how animations are supposed to be handled by PostCSS & css-loader. Am I missing something?

Bug

Most helpful comment

This worked for me

@-webkit-keyframes :local(animatetop) {
  from {top:-300px; opacity:0}
  to {top:0; opacity:1}
}
@keyframes :local(animatetop) {
  from {top:-300px; opacity:0}
  to {top:0; opacity:1}
}
:local(.modalContent) :local{
    position: relative;
    background-color: white;
    margin: auto;
    padding: 0;
    border: 1px solid #888;
    width: 500px;
    min-height:300px;
    box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19);
    -webkit-animation-name: animatetop;
    -webkit-animation-duration: 0.4s;
    animation-name: animatetop;
    animation-duration: 0.4s
}

The output was: (if that's what you were trying to accomplish)

@-webkit-keyframes _31eoHIHwv5wTOt_wePBEKx {
  from {top:-300px; opacity:0}
  to {top:0; opacity:1}
}
@keyframes _31eoHIHwv5wTOt_wePBEKx {
  from {top:-300px; opacity:0}
  to {top:0; opacity:1}
}
._3X1GGZ3CQqrjQ7gOsJ1Vev{
    position: relative;
    background-color: white;
    margin: auto;
    padding: 0;
    border: 1px solid #888;
    width: 500px;
    min-height:300px;
    box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19);
    -webkit-animation-name: _31eoHIHwv5wTOt_wePBEKx;
    -webkit-animation-duration: 0.4s;
    animation-name: _31eoHIHwv5wTOt_wePBEKx;
    animation-duration: 0.4s
}

All 11 comments

+1 same trouble

:local .a {
  animation: someAnimation
}

@keyframes :local(someAnimation) {

}

The animation's name in .a has been transformed into hash, but keyframe's name hasn't (still 'someAnimation')

update

Use an animation in pseudo classes caused this problem.

@gucheen In regards to your update, are you saying this works for you if you don't use :local ?

@netpoetica
My problem was that I used animation in :local .a:before { }.
Finally I moved animation property to :local .a {}

@gucheen It's not working even with plain selectors without pseudo classes.

:local {
    @keyframes fadeOut {
        0% {
            opacity: 1;
            visibility: visible;
        }
        100% {
            opacity: 0;
            visibility: hidden;
        }
    }

    .test {
        animation: fadeOut 1000ms ease-in;
    }
}

output:

.src-plugins-test__test {
    animation: src-plugins-test__fadeOut 1000ms ease-in;
}

@keyframes fadeOut {
    0% {
        opacity: 1;
        visibility: visible;
    }
    100% {
        opacity: 0;
        visibility: hidden;
    }
}

Guys, do you have any update on this? I believe this is a major bug.

Is there a way to specify that pseudo classes shouldn't be hashed? This would help me to use cq-prolyfill which adds the pseudo class :container and allows you to carry out container queries.

Less working example:

@keyframes ~":local(button-preload)" {
    0% {
        background-position: 0 0;
    }
    100% {
        background-position: 20px 0;
    }
}

:local {
    // less mixin
    .button-preload() {
        background-position: 0 0;
        animation: button-preload 750ms linear infinite;
    }

    .button {
        &__preload {
            .button-preload();
            color: #fff;
        }
    }
}

This worked for me

@-webkit-keyframes :local(animatetop) {
  from {top:-300px; opacity:0}
  to {top:0; opacity:1}
}
@keyframes :local(animatetop) {
  from {top:-300px; opacity:0}
  to {top:0; opacity:1}
}
:local(.modalContent) :local{
    position: relative;
    background-color: white;
    margin: auto;
    padding: 0;
    border: 1px solid #888;
    width: 500px;
    min-height:300px;
    box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19);
    -webkit-animation-name: animatetop;
    -webkit-animation-duration: 0.4s;
    animation-name: animatetop;
    animation-duration: 0.4s
}

The output was: (if that's what you were trying to accomplish)

@-webkit-keyframes _31eoHIHwv5wTOt_wePBEKx {
  from {top:-300px; opacity:0}
  to {top:0; opacity:1}
}
@keyframes _31eoHIHwv5wTOt_wePBEKx {
  from {top:-300px; opacity:0}
  to {top:0; opacity:1}
}
._3X1GGZ3CQqrjQ7gOsJ1Vev{
    position: relative;
    background-color: white;
    margin: auto;
    padding: 0;
    border: 1px solid #888;
    width: 500px;
    min-height:300px;
    box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19);
    -webkit-animation-name: _31eoHIHwv5wTOt_wePBEKx;
    -webkit-animation-duration: 0.4s;
    animation-name: _31eoHIHwv5wTOt_wePBEKx;
    animation-duration: 0.4s
}

This one works with SASS

:local(.spinnerIcon) :local {
  animation: spin 4s infinite linear;
}

@keyframes :local(spin) {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

I tried all your suggestions but no one works for me,
I found this article, it works for me when I used pseudo attributes:
https://gist.github.com/DavidWells/1f977cc310feb1264b41

:global {
  .loader,
  .loader:before,
  .loader:after {
    border-radius: 50%;
  }
}

:global {
  .loader:before {
    border: 4px solid #7cbac0;
    border-bottom-color: transparent;
    width: 44px;
    border-radius: 50%;
    height: 22px;
    border-radius: 46px 46px 0 0;
    top: -3px;
    left: -3px;
    transform-origin: 22px 22px;
    animation: load 2s infinite ease-in-out;
  }
}

@keyframes :global(load) {
  0% {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  100% {
    -webkit-transform: rotate(360deg);
    transform: rotate(360deg);
  }
}

/cc @michael-ciniawsky based on first message of issue
input:

.cssload-loader {
        animation-name: cssload-loader;
}
@keyframes cssload-loader {
        from { transform: scale(0); opacity: 1; }
        to   { transform: scale(1); opacity: 0; }
}

output:

.B7Ioe77FD3_4ggivnGrwa {
    animation-name: B7Ioe77FD3_4ggivnGrwa;
}
@keyframes B7Ioe77FD3_4ggivnGrwa {
    from { transform: scale(0); opacity: 1; }
    to   { transform: scale(1); opacity: 0; }
}

it is related to css-modules, in theory in css we can use same name for class and keyframes, it is valid, also example for me works as expected and good.

/cc @netpoetica @gucheen @raveclassic @QuietOmen @isnifer @AlejandroEsquivel @desero @ErickVoodoo who can create minimal reproduce test repo with error, it is allow resolve problems, if error not present now please write about this, no error - no issue :smile:

Was this page helpful?
0 / 5 - 0 ratings