Search code examples
cssreactjsemotion

Limit emotion global styles to a narrower selector


Is there a way to limit the styles that emotion injects into the global scope to a narrower scope?

I've seen this method of using a stylis plugin to add more narrowly-scoped styles, but that only adds scoped styles. What I'd like to do is limit all styles added by emotion to a particular selector.

The SCSS equivalent of what I'm looking for is something like this, where the styles would only apply to elements where div#my-styled-div is an ancestor:

div#my-styled-div {
  h1, h2, h3, h4, h5, h6 {
    // emotion header styles
  }

  button {
    // emotion button styles
  }
}

My use case is a Docusaurus site with a demo page that uses Chakra UI (specifically the Chakra UI demo page for react-querybuilder) and I don't want the emotion global styles to affect the Docusaurus theme styles.

(This question is similar, but it was never answered and I don't think it's exactly the same issue anyway.)


Solution

  • Emotion supports SCSS-like nesting, so you can define styles which only apply inside of a specific element like this:

    import { css } from "@emotion/react";
    
    const myCss = css`
      h1,
      h2,
      h3,
      h4,
      h5,
      h6 {
        color: red;
      }
    
      button {
        /* ... */
      }
    `;
    
    export default function App() {
      return (
        <div>
          <h2>Emotion styles don't apply to this h2</h2>
          <div css={myCss}>
            <h2>Emotion styles apply to this h2</h2>
            {/* Put the stuff you want to style with Emotion here */}
          </div>
        </div>
      );
    }
    

    CodeSandbox