Using Createmuitheme to Override Default Styles on Div'S, P'S, Body

Using createMuiTheme to override default styles on div's, p's, body

Here is an example of overriding this aspect of CssBaseline:

import PropTypes from "prop-types";
import { withStyles } from "@material-ui/core/styles";

const styles = theme => ({
"@global": {
body: {
...theme.typography.body1
}
}
});

function MyCssBaseline() {
return null;
}

MyCssBaseline.propTypes = {
classes: PropTypes.object.isRequired
};

export default withStyles(styles)(MyCssBaseline);

import React from "react";
import ReactDOM from "react-dom";
import CssBaseline from "@material-ui/core/CssBaseline";
import MyCssBaseline from "./MyCssBaseline";

function App() {
return (
<>
<CssBaseline />
<MyCssBaseline />
<span>
Here is some text in the body that is getting the body1 styling due to
MyCssBaseline.
</span>
</>
);
}
ReactDOM.render(<App />, document.querySelector("#root"));

Edit CssBaseline overrides

Reference: https://material-ui.com/styles/advanced/#global-css

Does createMuiTheme provide default values for missing properties?

Take a look at createMuiTheme options signature

(Object): Takes an incomplete theme object and adds the missing parts.

So yes, your custom theme will be merged with MUI's default theme. See the docs here

const options = {palette:{/*such empty*/}}

export const theme = createMuiTheme(options)

Use theme.spacing function in override in createMuiTheme

This is resolved in the new Mui v5 by using a function passed to a style name

export default createTheme({
components: {
MuiAppBar: {
styleOverrides: {
root: ({ theme }) => ({
margin: theme.spacing(2)
})
}
}
}
})

How to style body element in MUI

Material-UI v5

You can change the body styles by overriding MuiCssBaseline styles in createTheme():

import CssBaseline from "@mui/material/CssBaseline";
import darkScrollbar from "@mui/material/darkScrollbar";
import { createTheme, ThemeProvider } from "@mui/material/styles";

const theme = createTheme({
components: {
MuiCssBaseline: {
styleOverrides: {
body: {
...darkScrollbar(),
color: "darkred",
backgroundColor: "grey",
"& h1": {
color: "black"
}
}
}
}
}
});

export default function GlobalCssOverride() {
return (
<ThemeProvider theme={theme}>
<CssBaseline />
<Content />
</ThemeProvider>
);
}

Edit GlobalCssOverride Material Demo (forked)

Material-UI v4

You can apply the styles to the body using @global class like this:

const useGlobalStyles = makeStyles({
"@global": {
body: {
backgroundColor: "tomato"
}
}
});
const theme = createMuiTheme({});

function MyThemeProvider({ children }) {
useGlobalStyles();
return <ThemeProvider theme={theme}>{children}</ThemeProvider>;
}

function App() {
return (
<MyThemeProvider>
<Button variant="contained" color="primary">
Button
</Button>
</MyThemeProvider>
);
}

If you create the project by create-react-app, you can also use css/scss module to style any element globally:

/* styles.css */
body {
color: white;
font-size: 15px;
}
import React from "react";
import Button from "@material-ui/core/Button";
import "./styles.css";

function App() {
return (
<Button variant="contained" color="primary">
Hello World
</Button>
);
}

Live Demo

Edit 64705335/how-to-style-body-element-in-materialui

How can I customize the padding in a Material-UI autocomplete control?

This is a matter of getting the appropriate CSS specificity for your override. One easy way to increase the specificity is to repeat a class.

In the example below, I use &&& $input which is equivalent to having .MuiOutlinedInput-root.MuiOutlinedInput-root.MuiOutlinedInput-root .MuiOutlinedInput-input:

const theme = createTheme({
overrides: {
MuiInputLabel: {
outlined: {
transform: "translate(14px, 12.5px) scale(1)"
}
},
MuiOutlinedInput: {
root: {
"& $notchedOutline": {
borderColor: "green"
},
"&:hover $notchedOutline": {
borderColor: "red"
},
"&$focused $notchedOutline": {
borderColor: "purple"
},
"&&& $input": {
padding: "1px"
}
}
}
}
});

Edit Increase override specificity

Another option which is a bit uglier, but makes it more obvious which default styling you are overriding is the following:

const theme = createTheme({
overrides: {
MuiInputLabel: {
outlined: {
".MuiAutocomplete-root &:not(.MuiInputLabel-shrink)": {
transform: "translate(14px, 12.5px) scale(1)"
}
}
},
MuiOutlinedInput: {
root: {
"& $notchedOutline": {
borderColor: "green"
},
"&:hover $notchedOutline": {
borderColor: "red"
},
"&$focused $notchedOutline": {
borderColor: "purple"
}
}
},
MuiAutocomplete: {
inputRoot: {
'&&[class*="MuiOutlinedInput-root"] $input': {
padding: 1
}
}
}
}
});

Edit Increase override specificity (forked)

Notice that you still need to double the & in order to get specificity that wins over the default styles. This version is specific to auto complete rather than impacting all outlined inputs.

If you don't want to apply this override to the whole application in your theme, you can just customize the Autocomplete component using withStyles like the following:

import React from "react";
import TextField from "@material-ui/core/TextField";
import Autocomplete from "@material-ui/lab/Autocomplete";
import { withStyles } from "@material-ui/core/styles";

const NoPaddingAutocomplete = withStyles({
inputRoot: {
'&&[class*="MuiOutlinedInput-root"] $input': {
padding: 1
},
"& .MuiOutlinedInput-notchedOutline": {
borderColor: "green"
},
"&:hover .MuiOutlinedInput-notchedOutline": {
borderColor: "red"
},
"&.Mui-focused .MuiOutlinedInput-notchedOutline": {
borderColor: "purple"
}
},
input: {}
})(Autocomplete);
export default function CountrySelect() {
return (
<NoPaddingAutocomplete
id="country-select-demo"
style={{ width: 300 }}
options={countries}
getOptionLabel={option => option.label}
renderInput={params => (
<TextField {...params} label={"Countries"} variant="outlined" />
)}
/>
);
}

Edit Increase override specificity

Related answer:

  • Setting text color, outline, and padding on Material-ui Autocomplete component

Related documentation:

  • JSS documentation for &
  • Explanation of how CSS Specificity works

how to add more variant in matrial ui typography

Overwrite style of <Typography> component, and then use h1 variant:

import React from "react";

import Typography from "@material-ui/core/Typography";
import { withStyles } from "@material-ui/core/styles";

const SerifTypography = withStyles({ root: { fontFamily: "serif" } })(
Typography
);
const SansSerifTypography = withStyles({ root: { fontFamily: "sans-serif" } })(
Typography
);

export default function App() {
return (
<>
<SerifTypography variant="h1">Serif</SerifTypography>
<SansSerifTypography variant="h1">Sans Serif</SansSerifTypography>
</>
);
}

Live demo:

Edit mutable-dawn-c2bqz

How do I get typography theme defaults to apply to regular tags with Material-UI?

  1. Is the idea of Material-UI that I'm going to replace all regular html tags with custom React elements?

No. The idea of typography in Material UI (and Material Design in general) is to provide a consistent scale of variants accross you application theme : https://material.io/design/typography/the-type-system.html#

You may then use this typography styles in different ways, like explained in 2. and 3. below


  1. Is there any way to apply the styles from the theme typography to regular html tags like h1-6, p, etc easily?

Like @Chimera.Zen answered, you may apply theme styles and font variants to any react component or html tags with the withStyles HOC. But here is another way of doing so that i find more useful, by reusing theme typography definitions in your JSS styles :

const styles = theme => ({
paragraph: {
...theme.typography.body1
}
});

const MyComponent = props => (
<p className={props.classes.paragraph}>
My styles text
</p>
);

  1. Am I expected to style all the regular html elements myself using withStyles on some top level component?

You are not. You may style individual component if you like, but you will likely more use inheritance and use default styles of container components like Paper, Drawer, etc. or your own container components.

You can implement a global container component (eg "Root" or "App"...) applying default "body1" style to your whole application.

Another approach is to use the 'jss-global' plugin like explained here by MUI author https://github.com/mui-org/material-ui/issues/9988#issuecomment-426631645 :

import { withStyles } from '@material-ui/core/styles';

export default withStyles({
'@global': {
body: {
...theme.typography.body1
},
},
})(() => null);


Related Topics



Leave a reply



Submit