I'm trying something very simple: building two themes for a website using Material-UI themes:
A light
theme and dark
one, but it does not work well: the theme is on every Material-UI react element, but the root element on the html document keeps having the same default white background.
Of course it can be changed by attacking the body with pure .css:
body { background-color: #222; }
But I was looking to change it dynamically with React, I though this would work, but it does not:
import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; import { ThemeProvider } from '@material-ui/styles'; import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles'; const themeLight = createMuiTheme({ palette: { background: { default: "#e4f0e2" } }, }); const themeDark = createMuiTheme({ palette: { background: { default: "#222222", } }, }); ReactDOM.render( <MuiThemeProvider theme = { themeDark }> <App /> </MuiThemeProvider>, document.getElementById('root'));
and I'm lost here, there is no way to make this with Material-UI theme?
To set a background color on Material UI's Paper, you simply need to apply the background-color CSS property to the root element of the Paper. Setting the styles on the root element of any Material UI component can be done in multiple ways, but the most common is to use the useStyles hook.
CssBaseline is the component that controls this aspect. If you aren't using CssBaseline
, then you are just seeing the default provided by the browser.
Here is a working v4 example (v5 example further down):
import React from "react"; import ReactDOM from "react-dom"; import CssBaseline from "@material-ui/core/CssBaseline"; import { MuiThemeProvider, createMuiTheme } from "@material-ui/core/styles"; import Button from "@material-ui/core/Button"; const themeLight = createMuiTheme({ palette: { background: { default: "#e4f0e2" } } }); const themeDark = createMuiTheme({ palette: { background: { default: "#222222" }, text: { primary: "#ffffff" } } }); const App = () => { const [light, setLight] = React.useState(true); return ( <MuiThemeProvider theme={light ? themeLight : themeDark}> <CssBaseline /> <Button onClick={() => setLight(prev => !prev)}>Toggle Theme</Button> </MuiThemeProvider> ); }; const rootElement = document.getElementById("root"); ReactDOM.render(<App />, rootElement);
Below is a Material-UI v5 example. The only difference from v4 is the name change for ThemeProvider
(though this name is also available in v4 in addition to MuiThemeProvider
) and createTheme
(instead of createMuiTheme
) and using the new @mui/material
package name instead of @material-ui/core
.
import React from "react"; import ReactDOM from "react-dom"; import CssBaseline from "@mui/material/CssBaseline"; import { ThemeProvider, createTheme } from "@mui/material/styles"; import Button from "@mui/material/Button"; const themeLight = createTheme({ palette: { background: { default: "#e4f0e2" } } }); const themeDark = createTheme({ palette: { background: { default: "#222222" }, text: { primary: "#ffffff" } } }); const App = () => { const [light, setLight] = React.useState(true); return ( <ThemeProvider theme={light ? themeLight : themeDark}> <CssBaseline /> <Button onClick={() => setLight((prev) => !prev)}>Toggle Theme</Button> </ThemeProvider> ); }; const rootElement = document.getElementById("root"); ReactDOM.render(<App />, rootElement);
On top of @NearHuscarl 's answer, importing the GlobalStyles after the CSSBaseLine, will retain the page defaults (like margin: 0, etc.,) still able to customize root-level / global styles. For eg,
import { Component } from "react"; import { Button, CssBaseline, GlobalStyles } from "@mui/material"; import { ThemeProvider, createTheme } from "@mui/material/styles"; export class App extends Component { render() { const theme = createTheme({ palette: { mode: "dark", primary: { main: "#ff0000", contrastText: "#fff", }, secondary: { main: green[500], }, }, }); return ( <ThemeProvider theme={theme}> <CssBaseline /> <GlobalStyles styles={{ body: { backgroundColor: "cyan" }, }} /> <Button color="primary" variant="contained"> Button </Button> </ThemeProvider> ); } } export default App;
(I'm just using class component out of habit 😅)
Full example with nested themes MUI Theme toggle
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With