In my project I use Material-ui components along with react-emotion.
Let me give you an example that is problematic. I have this element:
<CardHeader title={stat} classes={{ root: statNumber }}/>
where
const statNumber = css`padding: 0;`
this way I get to override the default padding (16px) of CardHeader with 0 that is my intention.
In development mode everything works as expected but in production the padding: 0 rule gets overridden by the default padding 16px.
The reason this happens is that in development mode the styles are added in header dynamically. First come the Material-UI styles and then the emotion styles. Like this:
But in production the styles are laid out the other way around
This is the reason styles are overridden in production mode.
Material ui provides an explanation on this https://material-ui.com/styles/advanced/#css-injection-order
but with the solution proposed I cannot change the order of emotion and material-ui styles are ordered. I can only change material ui and move it further down
Anyone has an idea how to fix this??
The issue was resolved by changing the order of rendering the style rules. I created a wrapper that needs to wrap the entire app.
import React from 'react'
import { create } from 'jss'
import JssProvider from 'react-jss/lib/JssProvider'
import { createGenerateClassName, jssPreset } from 'material-ui/styles'
const styleNode = document.createElement('style')
styleNode.id = 'insertion-point-jss'
document.head.insertBefore(styleNode, document.head.firstChild)
// Configure JSS
const jss = create(jssPreset())
jss.options.createGenerateClassName = createGenerateClassName
jss.options.insertionPoint = document.getElementById('insertion-point-jss')
function Provider (props) {
return <JssProvider jss={jss}>{props.children}</JssProvider>
}
export default Provider
The wrapper creates an element as the first child inside head. All material ui styles are instructed to be placed there thus they are first in order and can be overridden by emotion rules that come next.