emotion: Invalid CSS output from function based dynamic styles

Current behavior:

Using an array of styles leads to invalid CSS properties in the DOM named label, name, and styles.

On the first style passed, the invalid CSS prop label does not appear in the DOM, but for subsequent styles it does. Additionally the first rule in the CSS in each style passed is nested invalidly like so: styles: color: red;

image

To reproduce:

Can’t reproduce this issue on CodeSandbox - so possibly related to babel or webpack would be my guess. Does the order of babel plugins matter when including the emotion plugin? I get this issue whether I use the plugin or not.

Expected behavior:

No invalid props in the DOM and the first rule is not mangled and ignored.

Environment information:

  • react version: 16.9.0
  • emotion version: 10.0.17

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 24 (21 by maintainers)

Most upvoted comments

Just encountered this problem while migrating from v9 to v11. Removing emotion from babel plugins fixed it for me as I already have @emotion/babel-preset-css-prop in babel presets.

Unfortunately, nothing comes to my mind as to what we could do to warn about smth like this.

Indeed it looks like a styled-components babel plugin was in a nested .babelrc and it was passing props to my style partials. Pretty crazy side effect.

image

So the only real bug here will be addressed by #1553

I don’t suppose there’s any easy way to detect that the styled-components plugin is in use from emotion’s side? It’s not really within the scope of the project, but if it would be possible and easy, perhaps it would be worth it in the interest of preventing future issues like this from gunking up the issue tracker.

Thanks for your patience and assistance @Andarist.

I pulled up the stack trace, but I see styled-components and not emotion in the call stack… is this normal?

Nope, we don’t depend anyhow on styled-components.

If not, I can’t imagine why it would be using styled-components since it’s not imported or referenced anywhere in that file, although it is present in the project as a dependency of a dependency.

Maybe it’s somehow inserted by some babel plugin? Just a wild guess.

I am pretty confused about not being able to access props though, because that’s exactly what I’m able to do. Am I misunderstanding what you mean? I can’t understand why I can’t replicate this behavior in CodeSandbox, regardless of whether this is how the library should be used.

Put a debugger in there and check out the stack trace to see what gives you that props argument.

Regarding keyframes stuff - for now you should wrap it with css. We are going to either allow interpolating keyframes output into plain strings or introduce a dev warning about misusing it. See https://github.com/emotion-js/emotion/pull/1553 .

Interpolating into strings:

const str = `${keyframes()}`

and into tagged template calls

const str = css`${keyframes()}`

is a different thing, although they look pretty much similar. With tagged templates we receive what you actually put in there, but with a plain string the interpolated value gets stringified by JavaScript.

Thanks for the sandbox - gonna investigate this some time later.

I noticed it seems to be the first rule of css that’s ignored in any circumstance. Here’s another scenario:

Input:

const activeStyles = props =>
  props.active  &&
  css`
    border: none; //  Dummy rule to overcome Emotion bug -- https://github.com/emotion-js/emotion/issues/1524

    && {
      color: #3b85a0;
      opacity: 1;
    }
  `;

Output:

.bBHyQG {
    name: 1lffm4s;
    styles: border:none;
}

.bBHyQG.bBHyQG {
    color: #3b85a0;
    opacity: 1;
}

Not sure if this helps… but… i have seen this happen when you don’t close off the css selectors correctly. I have had a few examples of this happen over time and i have to really look deep into the css and see if i have not forgotten to add a semi-colon at the end of the css selectors. Otherwise i get the name issue as you are explaining.

for example:

css`
    ${test && `background:red`}
    color: green;
`

would output the css concatenated. But this would be ok…

css`
    ${test && `background:red;`}
    color: green;
`

can you provide a codesandbox for your last case?

If you can’t repro this on codesandbox a regular repository is acceptable as repro too - we just recommend codesandbox as it’s easier to setup.