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 · 21 comments

Comments

@NN77
Copy link

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

This comment has been minimized.

Copy link
Member

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.

@ouqinglai

This comment has been minimized.

Copy link

commented Aug 26, 2016

Did you solve it?

@ouqinglai

This comment has been minimized.

Copy link

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 {}
@mnpenner

This comment has been minimized.

Copy link

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.

@lennerd

This comment has been minimized.

Copy link

commented Feb 7, 2017

Any progress with this?

@xingbofeng

This comment has been minimized.

Copy link

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;
  }
}
@cansin

This comment has been minimized.

Copy link

commented Mar 22, 2017

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

@mnpenner

This comment has been minimized.

Copy link

commented Mar 24, 2017

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

@AlexGalays

This comment has been minimized.

Copy link

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
  }
}
@piyushchauhan2011

This comment has been minimized.

Copy link

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;
}
@TrySound

This comment has been minimized.

Copy link
Member

commented Jun 14, 2017

@mnpenner

This comment has been minimized.

Copy link

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).

@mrchief

This comment has been minimized.

Copy link

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); }
}
@mnpenner

This comment has been minimized.

Copy link

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.

@mrchief

This comment has been minimized.

Copy link

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).

@wilsonpage

This comment has been minimized.

Copy link

commented Apr 6, 2018

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

@Download

This comment has been minimized.

Copy link

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.

@westtrade

This comment has been minimized.

Copy link

commented Aug 2, 2018

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

Doesn't work, maybe with stylus-loader

@sergeyshmakov

This comment has been minimized.

Copy link

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.

@allan852

This comment has been minimized.

Copy link

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.

@brendanfalkowski

This comment has been minimized.

Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
You can’t perform that action at this time.