kriasoft / isomorphic-style-loader

CSS style loader for Webpack that is optimized for isomorphic (universal) web apps.

Home Page:https://reactstarter.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

CSS passed to a child component won't be applied for properties that clash with the child component

denno020 opened this issue · comments

commented

When we have the following component structure:

import Child from './Child';
import classes from './MyComponent.css';
const MyComponent = () => {
  return (
    <div><Child className={classes.childModifier} /></div>
  )
}
// MyComponent.css
.chlidModifier {
  background-color: green;
}
import classes from './Child.css';
const Child = (props) => {
  const { className = '' } = props;
  return (
    <div className={`${classes.child} ${className}`}>Child</div>
  )
}
// Child.css
.child {
  background-color: purple;
}

The default settings for isomorphic-style-loader means that the background colour of the Child component will be purple, we can never overwrite, unless we make our parent selector more specific (i.e. compound selectors or !important).

The initial "fix" is to set prepend to true, which will result in the Child component being green, but only if Child isn't imported elsewhere, before MyComponent..

The reason for this is that once styles have been injected into the DOM, they stay exactly there, regardless of the relationship to other components.

My proposal is to use prepend and a new property, bubble, to move styles when the component associated with those styles is imported in another component. This effectively "bubbles up" the styles for a given component, so it will always be higher in the DOM than a component that imports it, meaning it's higher in the CSS cascade, such that CSS properties passed into a child component can easily overwrite the "default" properties that are set on the Child component..

I have created a CodeSandbox that demonstrates the changes.
https://codesandbox.io/p/sandbox/interesting-booth-k9fl84

The changes are as follows:
src/app/index.js - This is where the projects insertCss function lives. Set bubble (on line 17) to false to see the issue in the preview.
src/insertCss.js - This is the isomorphic-style-loader-react18 source file, with a new param, bubble added to the options object, and lines 58 to 60 added, making use of that new property.

I tried to explore the replace property, but I couldn't tell what effect that was having, and it didn't fix this issue.

Would love to discuss this approach, especially regarding where I've made the code change, whether that's the right place or not