Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@keyframes xxx is transformating too #141

Closed
NN77 opened this issue Apr 25, 2016 · 25 comments
Closed

@keyframes xxx is transformating too #141

NN77 opened this issue Apr 25, 2016 · 25 comments

Comments

@NN77
Copy link

@NN77 NN77 commented Apr 25, 2016

Hi, have some problem with:

/* input */
@keyframes anim {
    50% {
      left: 56px;
    }
  }
```css
/* output */
...
animation: _anim_ljlgu_1 1s infinite linear;
...
@joshwnj
Copy link
Member

@joshwnj joshwnj commented May 27, 2016

Hi @NN77 , this is expected behaviour from what I understand. Keyframe names are also within global scope, so unless they are given a unique name there is the chance of an unintended collision.

Loading

@ouqinglai
Copy link

@ouqinglai ouqinglai commented Aug 26, 2016

Did you solve it?

Loading

@ouqinglai
Copy link

@ouqinglai ouqinglai commented Aug 29, 2016

works for me!

/* input */
:global {
    .test {
        :local {
            animation: name .6s ease;   
        }
    }
}
@keyframes name {}
/* output */
.test {
  animation: name-2j99k .6s ease;
}
@keyframes name-2j99k {}

Loading

@mnpenner
Copy link

@mnpenner mnpenner commented Feb 1, 2017

Has anyone got this working with LESS?

Input:

:local {
    .spin {
        animation: spin .5s infinite linear;
    }

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

Out:

._1JvaUPKhMxOEcthB0QSfsP {
  animation: _1JvaUPKhMxOEcthB0QSfsP .5s infinite linear;
}
@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

Why doesn't @keyframes spin get translated too?

I can work around this for now by making my animation global:

    .spin {
        :global {
            animation: spin .5s infinite linear;
        }
    }

But I actually do want the keyframes name randomized.

Loading

@lennerd
Copy link

@lennerd lennerd commented Feb 7, 2017

Any progress with this?

Loading

@xingbofeng
Copy link

@xingbofeng xingbofeng commented Mar 17, 2017

like my code, you can solve the problem.

@keyframes :global(slideInFromRight) {
  0% {
    transform: translateX(100%);
  }
  100% {
    transform: translateX(0);
  }
}

@keyframes :global(slideOutToLeft) {
  0% {
    transform: translateX(0);
  }
  100% {
    transform: translateX(-100%);
  }
}
.active {
  position: relative;
  transform: translateX(0);
  :global {
    animation: slideInFromRight 0.35s ease-in-out;
  }
}

.hidden {
  transform: translateX(-100%);
  :global {
    animation: slideOutToLeft 0.35s ease-in-out;
  }
}

Loading

@cansin
Copy link

@cansin cansin commented Mar 22, 2017

@mnpenner did you figure it out? I am having the same problem.

Loading

@mnpenner
Copy link

@mnpenner mnpenner commented Mar 24, 2017

@cansin No. I'm still using the workaround. Looks like a bug in css-modules to me.

Loading

@AlexGalays
Copy link

@AlexGalays AlexGalays commented Apr 10, 2017

Another workaround : Don't use the animation shorthand property, and the name of the animation will be localised, e.g:

.fadein {
  animation-duration: 300ms
  animation-name: fadein
  animation-fill-mode: forwards
}

@keyframes fadein {
  from {
    opacity: 0
  }
}

Loading

@piyushchauhan2011
Copy link

@piyushchauhan2011 piyushchauhan2011 commented May 9, 2017

I think it's best to use composition here. This is for projects where css-modules are enabled with :local as default. This article is nice if you want to enable css-modules in create-react-app project.

.App {
  text-align: center;
}

.logo-animation {
  animation: logo-spin infinite 20s linear;
}
@keyframes logo-spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

.logo {
  composes: logo-animation;
  height: 80px;
}

Loading

@TrySound
Copy link
Member

@TrySound TrySound commented Jun 14, 2017

Loading

@mnpenner
Copy link

@mnpenner mnpenner commented Jun 19, 2017

@TrySound Can this ticket be re-opened? Your plugin is nice, but it doesn't really address the heart of the problem.

We have to exclude both @keyframes and animation: blocks from the local context because one gets transformed, but not the other, which breaks the CSS.

With your new plugin, postcss-icss-keyframes, we still have to exclude both from the local context, but then the animation names can be transformed after-the-fact.

I think most of us would prefer that we could just throw everything including animations in a :local block (or enable local as the default via the CSS module settings), and simply have it work (so that we don't have to flip back and forth between :local and :global).

Loading

@mrchief
Copy link

@mrchief mrchief commented Aug 25, 2017

They both get transformed correctly if enclosed in the same block. E.g., this works:

/* module.css */

.module {
  .logo-animation {
    animation: logo-spin infinite 20s linear;
  }
}

@keyframes logo-spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

Loading

@mnpenner
Copy link

@mnpenner mnpenner commented Aug 26, 2017

@mrchief What do you mean by "the same block"? Do you mean the same file? Because your @keyframes is not inside .logo-animation.

I just tried updating every package I think might be relevant,

├─ autoprefixer@6.5.1
├─ css-loader@0.28.5
├─ icss-utils@2.1.0
├─ less-loader@4.0.5
├─ less-plugin-autoprefix@1.5.1
├─ less@2.7.2
└─ postcss-loader@2.0.6
└─ style-loader@0.18.2

I threw this in one of my .less files:

:local {
    .wrap {
        animation: logo-spin infinite 20s linear;
    }

    @keyframes logo-spin {
        from { transform: rotate(0deg); }
        to { transform: rotate(360deg); }
    }
}

And the output I get is:

.AddStopButton_wrap--FoJr- {
    -webkit-animation: AddStopButton_logo-spin--1tzsL infinite 20s linear;
    animation: AddStopButton_logo-spin--1tzsL infinite 20s linear;
}
@-webkit-keyframes logo-spin {
    from {
        -webkit-transform: rotate(0deg);
        transform: rotate(0deg);
    }
    to {
        -webkit-transform: rotate(360deg);
        transform: rotate(360deg);
    }
}
@keyframes logo-spin {
    from {
        -webkit-transform: rotate(0deg);
        transform: rotate(0deg);
    }
    to {
        -webkit-transform: rotate(360deg);
        transform: rotate(360deg);
    }
}

As you can see, the @keyframes name and animation name still don't match up. Looks broken to me.

Loading

@mrchief
Copy link

@mrchief mrchief commented Aug 26, 2017

Yeah I mean same file. But your setup is different as it uses less. I use postcss with cssnext (cssnext has bunch of plugins bundled up within).

This is what I get (other css props omitted for brevity):

.submitButton {
  .spin-container {
   ...

    .spinner {
      ...
      animation: rotate 0.8s infinite linear;
      ...
    }
  }
}

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

output

...
.styles__submitButton-1TYvP .styles__spin-container-1zk-6 .styles__spinner-1LN5V {
     ... 
      -webkit-animation: styles__rotate-1K2Xu 0.8s infinite linear;
              animation: styles__rotate-1K2Xu 0.8s infinite linear;
     ....
    }

@-webkit-keyframes styles__rotate-1K2Xu {
  0% { -webkit-transform: rotate(0deg); transform: rotate(0deg); }
  100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); }
}

@keyframes styles__rotate-1K2Xu {
  0% { -webkit-transform: rotate(0deg); transform: rotate(0deg); }
  100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); }
}

webpack

{
  test: /\.css$/,
  exclude: /node_modules/,
  loader: ExtractTextPlugin.extract({
    fallback: 'style',
    use: [
      {
        loader: 'css',
        options: {
          importLoaders: 1,
          sourceMap: true,
          modules: true,
          context: path.join(process.cwd(), './src'),
          localIdentName: isDev ? '[name]__[local].[hash:base64:5]' : '[hash:base64:5]',
          minimize: !isDev
        }
      },
      {
        loader: 'postcss'
      }
    ]
  })
}

postcss.config.js

module.exports = (ctx) => ({
    sourceMap: true,
    plugins: [
      require('postcss-import')(),
      require('postcss-url')(),
      require('postcss-nested')(),
      require('postcss-cssnext')({
        browsers: ['ie >= 10', 'last 2 versions'],
        warnForDuplicates: false
      }),
      require('postcss-browser-reporter')(),
      require('postcss-reporter')()
    ],
  }
);

Also, remember that your plugin order matters! Using cssnext saves me from most of that headache. But since you're using less and a bunch of others, make sure everything is in the right order.

One other thing, postcss-nested is required for processing global blocks (everything is local by default).

Loading

@wilsonpage
Copy link

@wilsonpage wilsonpage commented Apr 6, 2018

Using longhand animation syntax (eg. animation-name, etc) fixed my particular issue.

Loading

@Download
Copy link

@Download Download commented Jun 1, 2018

Seen a bunch of issues related to this and the longhand trick has been recommended elsewhere too. It really seems to work. It works for my scenario as well.

Loading

@westtrade
Copy link

@westtrade westtrade commented Aug 2, 2018

Using longhand animation syntax (eg. animation-name, etc) fixed my particular issue.

Doesn't work, maybe with stylus-loader

Loading

@sergeyshmakov
Copy link

@sergeyshmakov sergeyshmakov commented Feb 13, 2019

Its normal behavior to apply localIdentName to @keyframes and animation inside because @keyframes may be overrriden by some other module.

For some reasons developers of css-loader dont want to fix link between @keyframes and animation inside one module styles when :local { ... } not being writen by you.

I my case the app is depends from vendor package with style that I cant change and I fix this issue by using postcss-modules-local-by-default plugin.

Loading

@allan852
Copy link

@allan852 allan852 commented Mar 28, 2019

    @keyframes name {
        0% {
            transform: rotate(0deg);
        }
        100% {
            transform: rotate(360deg);
        }
    }
    .spin {
        animation: name .5s infinite linear;
    }

animation: name .5s infinite linear; // ok
animation: .5s infinite linear name; // can't work

The name must be the first property.

Loading

@brendanfalkowski
Copy link

@brendanfalkowski brendanfalkowski commented Jul 12, 2019

For reference, I found this issue while debugging and documented several approaches here: https://gravitydept.com/blog/keyframe-animations-in-css-modules

Loading

@dmwin72015
Copy link

@dmwin72015 dmwin72015 commented Oct 20, 2019

like my code, you can solve the problem.

@keyframes :global(slideInFromRight) {
  0% {
    transform: translateX(100%);
  }
  100% {
    transform: translateX(0);
  }
}

@keyframes :global(slideOutToLeft) {
  0% {
    transform: translateX(0);
  }
  100% {
    transform: translateX(-100%);
  }
}
.active {
  position: relative;
  transform: translateX(0);
  :global {
    animation: slideInFromRight 0.35s ease-in-out;
  }
}

.hidden {
  transform: translateX(-100%);
  :global {
    animation: slideOutToLeft 0.35s ease-in-out;
  }
}

not work, Expected @Keyframes identifier

Loading

@rustho
Copy link

@rustho rustho commented Nov 15, 2019

+1

Loading

@nixolas1
Copy link

@nixolas1 nixolas1 commented Jan 3, 2020

.myClass {
  color: black;
  & :global { animation: scrollAnim 3s infinite ease-in-out }
}

worked for me, in a css module file, with

@keyframes :global(scrollAnim) {
  0% { transform: scaleX(0) }
  100% { transform: scaleX(1) }
}

in a separate, non-module css file

Loading

t--takai added a commit to t--takai/NuxtStarter that referenced this issue Apr 14, 2020
@matiasperz
Copy link

@matiasperz matiasperz commented Dec 12, 2020

For those using pure css, you have to do something like this:

/* styles.module.css */
.myClass {
  /* some other local css */
}

.myClass:global {
  animation-duration: .3s;
  animation-fill-mode: forwards;
  animation-name: fadeInUp;
}
/* styles.global.css */
@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(35px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

Loading

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet