isomorphic-style-loader
isomorphic-style-loader copied to clipboard
CSS passed to a child component won't be applied for properties that clash with the child component
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