There are two things you'll want to setup within your App.jsx
file to get started using Material UI.
The first is the ThemeProvider
component to allow your app to have access to the global theme (uses the React Context API underneath the hood).
The second is the CssBaseline
component to perform a global reset of CSS styles (with useful defaults) to prevent browser-specific wonkiness as much as possible.
import { ThemeProvider } from '@material-ui/core/styles';
import CssBaseline from '@material-ui/core/CssBaseline';
const App = () => (
<ThemeProvider>
<CssBaseline/>
{ /* ...the rest of your app */}
</ThemeProvider>
);
One of the most powerful ways to change styles throughout your app is by providing your own options to extend/override the default theme. Any updates to the theme will be applied globally throughout your application, so your app can have a uniform look and feel.
At the bare minimum, the color pallette of your app should be set via a theme override. There's a helpful color pallette tool that you can use to see what it will look like.
The first set of options that can be configured are the default theme configuration variables. You can view all of these variable at this page.
import { createMuiTheme, ThemeProvider } from '@material-ui/core/styles';
import { orange } from '@material-ui/core/colors';
const theme = createMuiTheme({
palette: {
secondary: {
main: orange[500],
},
},
});
export default function App() {
return (
<ThemeProvider theme={theme}>
{/* ...the rest of your app */}
</ThemeProvider>
);
}
You can also extend this to include custom theme variables for use when styling your components.
// App.jsx
import { createMuiTheme, ThemeProvider } from '@material-ui/core/styles';
import { orange } from '@material-ui/core/colors';
import CustomCheckbox from './CustomCheckbox';
const theme = createMuiTheme({
status: {
danger: orange[500],
},
});
export default function App() {
return (
<ThemeProvider theme={theme}>
<CustomCheckbox />
</ThemeProvider>
);
}
// CustomCheckbox.jsx
import { makeStyles } from '@material-ui/core/styles';
import Checkbox from '@material-ui/core/Checkbox';
const useStyles = makeStyles((theme) => ({
root: {
color: theme.status.danger,
// syntax to apply styles to :checked psuedo-class
'&$checked': { color: theme.status.danger },
},
// necessary to overwrite :checked psuedo-class styles
checked: {},
}));
const CustomCheckbox = () => {
const classes = useStyles();
return <Checkbox classes={{ root: classes.root, checked: classes.checked }} />;
}
When the configuration variables aren't powerful enough, you can take advantage of the overrides key of the theme to change every single style injected by Material-UI into the DOM. You need to be able to use the style sheet name for the component, which can usually be found at the top of each component's respective Component API page.
const theme = createMuiTheme({
overrides: {
// Style sheet name ⚛️
MuiButton: {
// Name of the rule
text: {
// Some CSS
color: 'white',
},
},
},
});
Previously we would use a withStyles
HOC to set styles in Material UI, but now it's recommended that you use the makeStyles
method to return a useStyles
hook that can be used within your component.
makeStyles
can take a style object or a function that provides the theme
config object as its first argument.
import { makeStyles } from '@material-ui/core/styles';
// using a style object
const useStyles = makeStyles({
button: {
fontSize: 16,
},
});
// using a function
const useStyles = makeStyles((theme) => ({
button: {
fontSize: theme.typography.subtitle1.fontSize,
},
}));
The useStyles
hook will return a classes
object, which contains the unique strings associated with each style class. You use the className
prop to apply these styles to a JSX element.
const classes = useStyles();
return <div className={classes.button} />;
When using the useStyles
hook, you also have the option to pass in props to style dynamically, which can be accessed by using a function as the value for a specific CSS style when calling makeStyles
.
import { makeStyles } from '@material-ui/core/styles';
const useStyles = makeStyles({
wrapper: {
backgroundColor: 'red',
color: props => props.color,
},
});
export default function MyComponent(props) {
const classes = useStyles(props);
return <div className={classes.wrapper} />;
}
Sometimes you want to adjust the styling for an instance of a Material UI component and you aren't able to access the specifc CSS properties via the useStyles
hook.
Many Material UI components are actually made up of several components underneath the hood. Each of these components has their own page in the Componet API section of Material UI's website (example).
At the bottom of each Component API page, you'll find a list of props you can use with that component as well as a list of CSS rules that can be overwritten. Each CSS rule has the rule name, global class, and description of where/when the styles are applied. Sometimes its easiest to use Chrome DevTools to figure out what element you need to apply your styles to find its class first.
Once you know what class needs to be overwritten, you can use its rule name to override its style via the classes
prop on the component.
const useStyles = makeStyles({
root: { borderRadius: 3 },
label: { textTransform: 'capitalize' },
});
const SpecialButton = () => {
const classes = useStyles();
return (
<Button
classes={{
root: classes.root,
label: classes.label,
}}
>
special button
</Button>
);
}