-
-
Save Danilo-Araujo-Silva/2ce11fd0540dcc7eb3ad3e67fd75d02a to your computer and use it in GitHub Desktop.
| For example, to override the AppBar (https://material-ui-next.com/api/app-bar/) root class we can do the following: | |
| First method (override Material UI classnames): | |
| 1 - Add the property classes in the AppBar component: | |
| <AppBar classes={{root: 'my-root-class'}} | |
| 2 - Override the styles with the styled components: | |
| styled(AppBar)` | |
| &.my-root-class { | |
| z-index: 1500; | |
| } | |
| ` | |
| Second method (force specificity): | |
| styled(AppBar)` | |
| && { | |
| z-index: 1500; | |
| } | |
| ` | |
| Third method (use a custom classname): | |
| 1 - Add the classname in the classname property: | |
| <AppBar className={`my-class ${this.props.otherClassesFromPropertiesWithNeeded}`} | |
| 2 - Override the styles with the styled components: | |
| styled(AppBar)` | |
| &.my-class { | |
| z-index: 1500; | |
| } | |
| ` |
In material-ui v4, you can simply do:
import { StylesProvider } from '@material-ui/styles';
// [other imports]
// [code]
function App() {
return (
<StylesProvider injectFirst> // this
<MuiThemeProvider theme={theme}
<Routes />
</MuiThemeProvider>
</StylesProvider>
);
}Took me a bit to find it, because it's not in the migration guide. The original technique as described above doesn't work anymore in v4. Hope this helps somebody else.
What if you need to pass the class name down deeper, like to InputProps.className, from TextField?
@mikew Did you figure it out? I'm also looking for the solution to the same answer.
@JimVanEeden you saved my life, first time seeing this solution. Where did you find that? Its the simplest yet not in the docs
@shilangyu I can't remember honestly :'). I think I just looked through the source or something.
@JimVanEeden Thanks a ton for that solution! It makes things a lot easier.
@shilangyu It's in the docs, in the Advanced section under Styles.
@JimVanEeden Thanks, thats exactly what I've been looking for, just wish I found it an hour or two ago!
In material-ui v4, you can simply do:
import { StylesProvider } from '@material-ui/styles'; // [other imports] // [code] function App() { return ( <StylesProvider injectFirst> // this <MuiThemeProvider theme={theme} <Routes /> </MuiThemeProvider> </StylesProvider> ); }Took me a bit to find it, because it's not in the migration guide. The original technique as described above doesn't work anymore in v4. Hope this helps somebody else.
Thx! It worked!
import { StylesProvider } from '@material-ui/styles';
import App from 'next/app';
import React from 'react';
import { ThemeProvider } from 'styled-components';
const theme = {
colors: {
primary: '#037Ef3',
textLight: '#F3F4F7',
},
};
class MyApp extends App {
render() {
const { Component, pageProps } = this.props;
return (
<StylesProvider injectFirst>
<ThemeProvider theme={theme}>
<Component {...pageProps} />
</ThemeProvider>
</StylesProvider>
);
}
}
export default MyApp;
@mikew @panuavakul
You can use the typical sass-like nested selectors. Selector as keys and value as object with css properties.
Only thing you need to know is the class names you want to target. If you render the input you can inspect and see the class names of the element you want to target. There may also be some info in the docs, but I haven't noticed it.
For the MUI within TextField I can see these class names on the input.
.MuiInputBase-input
.MuiInput-inputHere's an example.
Notice the empty space between the
&and the class name.
const Search = styled(TextInput)({
width: '100%',
marginBottom: '15px',
background: '#fff',
'& .MuiInputBase-input': {
background: '#ff00ff',
color: '#fff',
fontWeight: '900',
},
})If you need more specificity it's best to simply chain more class names.
const Search = styled(TextInput)({
width: '100%',
'& input.MuiInputBase-input.MuiInput-input': {
background: '#ff00ff',
},
})Easiest way https://material-ui.com/ru/guides/interoperability/#styled-components
To provide injectFirst property to StylesProvider component
import { StylesProvider } from '@material-ui/core/styles';
<StylesProvider injectFirst>
{/* Your component tree.
Now, you can override Material-UI's styles. */}
</StylesProvider>
All the above mentioned methods are ugly, if you want to pass classes object, just do it this way:
const ModifiedAppBar = styled(({...rest}) => (
<AppBar classes={{root: 'my-root-class'}} {...rest}/>
))`
.my-root-class {
z-index: 1500;
}
`
All the above mentioned methods are ugly, if you want to pass
classesobject, just do it this way:const ModifiedAppBar = styled(({...rest}) => ( <AppBar classes={{root: 'my-root-class'}} {...rest}/> ))` .my-root-class { z-index: 1500; } `
this is literally what the gist is proposing as a solution
@JimVanEeden Thank you, it worked.
In material-ui v4, you can simply do:
import { StylesProvider } from '@material-ui/styles'; // [other imports] // [code] function App() { return ( <StylesProvider injectFirst> // this <MuiThemeProvider theme={theme} <Routes /> </MuiThemeProvider> </StylesProvider> ); }Took me a bit to find it, because it's not in the migration guide. The original technique as described above doesn't work anymore in v4. Hope this helps somebody else.
When I use this "solution", I see a flickering of styles in the browser. I'm guessing styles are moved in the DOM client-side (not server-side). For me this is a deal-breaker. Would anyone know if I'm missing something else?
Just want to post a thanks here man. Thank you.
Man i just take a Minute to say you thanks and god bless you since months i was trying to find a clever solution to this problem.
Although a bit dirty, here is my version to enforce the specificity at the very first place (logic can be wrapped in a component so React can pick it up):
This ensure CSS injected by the
styled-componentswill always win, and it only need to be exercise once and before browser start to paint the next frame.