Emotion: nest a class selector using the class generated with `css` in Emotion 10

Created on 8 Feb 2019  路  4Comments  路  Source: emotion-js/emotion

In Emotion@9 the below code makes the anchor underlined:

import React from "react";
import { css } from "emotion";

const link = css`
  color: hotpink;
`;

const paragraph = css`
  color: gray;

  .${link} {
    border-bottom: 1px solid currentColor;
  }
`;

export default class App extends React.Component {
  render() {
    return (
      <div>
        <p className={paragraph}>
          Some text with a<a className={link}> link</a>.
        </p>
      </div>
    );
  }
}

I appreciate this would work without any code your side because css returns a class string. However in Emotion@10 it seems the css function does not handle this:

/** @jsx jsx */
import React from "react";
import { css, jsx } from "@emotion/core";

const link = css`
  color: hotpink;
`;

const paragraph = css`
  color: gray;

  .${link} {
    border-bottom: 1px solid currentColor;
  }
`;

export default class App extends React.Component {
  render() {
    return (
      <div>
        <p css={paragraph}>
          Some text with a<a css={link}> link</a>.
        </p>
      </div>
    );
  }
}

In Emotion@10 I'd have to walk into the object returned by css and assume the css- prefix.

const paragraph = css`
  color: gray;

  .css-${link.name} {
    border-bottom: 1px solid currentColor;
  }
`;

I appreciate you are encouraging users not to do this sort of thing in Emotion 9, but would I be right in thinking there would be nothing to lose in supporting this in Emotion 10's tagged template function?

This problem arose for me because I'm working on a sass-to-emotion codemod, and because it's something that is supported in Sass there exits prod CSS that operates like above.

question

Most helpful comment

If I'm not mistaken SerializedStyles.name is not dependable because as soon as it gets combined with an additional style on a lower level you'll end up with a new className.

All 4 comments

Just to clarify something, I appreciate the selectors are unique in emotion due to the hash and don't need to be nested for specificity reasons. A use case would be that we have conditional classes higher up the DOM tree that change styles of nested elements. For example:

.is-small-agent {
   .agent-photo {
     height: 30px;
   }
}

.agent-photo {
   height: 50px;
 }

We also had this problem because we use nesting to change inner nodes styles in complicated components. This is very strange that SerializedStyles.name return only name without css- prefix

If I'm not mistaken SerializedStyles.name is not dependable because as soon as it gets combined with an additional style on a lower level you'll end up with a new className.

I'm going to close this as dupe of #1217, please continue there.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Zn4rK picture Zn4rK  路  3Comments

tkh44 picture tkh44  路  3Comments

mattfysh picture mattfysh  路  3Comments

Aaron-Pool picture Aaron-Pool  路  3Comments

mitchellhamilton picture mitchellhamilton  路  3Comments