Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inject CSS Modules to Per-Component Style Elements (for portability to shadow root)

TL:DR

How can I get CSS of React components to work inside of a shadow root, while keeping the encapsulation benefits of CSS Modules class? I'd like to insert per-component <style> elements instead of inside of <head> or another arbitrary element.

What I have

I'm currently using CSS Modules in React with a custom Webpack script; [style-loader, css-loader, sass-loader] in the traditional way. The resulting compiled CSS is injected as <style> tags in head.


    // MyComponent.jsx
    import React from 'react';
    import styles from './MyComponent.scss';

    export const MyComponent = () => {
      return <div className={styles.container}>Hello!</div>
    }

    // MyComponent.scss
    .container {
      background: purple;
    }

result

    <!-- rendered page -->
    <head>
      ...
      <style>.myComponent__container__hash123 { background: purple }</style>
    </head>
    <body>
      ...
      <div class="myComponent__container__hash123">Hello!</div>
    </body>

What I want

For use inside of a shadow root, I would like to instead inject each component's compiled CSS into a <style> tag on its root.

    <!-- rendered page -->
    <head>
      ...
    </head>
    <body>
      ...
      <div>
        #shadow-root
          <div class="myComponent__container__hash123">Hello!</div>
          <style>.myComponent__container__hash123 { background: purple }</style>
        #end shadow-root
      </div>
    </body>

What I tried

1. insert

This will not work for component libraries which compile themselves, where I cannot know the end consumer in advance.

2. to-string-loader

https://www.npmjs.com/package/css-to-string-loader

When combined with style-loader, the result is classnames aren't resolved (e.g. styles.container === undefined).


Ideally I would have import styles from './MyComponent' contain the compiled CSS string in addition to classname mapping - however this is not supported as per style-loader docs

like image 287
mike-shtil Avatar asked Nov 23 '25 15:11

mike-shtil


1 Answers

Two years too late, but:

I'm not quite sure if this is what you want, but in React you can add style directly into JSX like this:

  <style>
    {`
      body {
        font-family: 'Inter', sans-serif;
        font-size: 14px;
        background-color: #151515;
        color: white;
      }
    `}
  </style>

or using your example:

<style>
    {`
      .myComponent__container__hash123 { 
        background: purple;
      }
    `}
</style>
like image 50
Duke Dougal Avatar answered Nov 26 '25 04:11

Duke Dougal



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!