1

I am new to using Material-UI. In my project I was unable to override the root Material-UI root class for Avatar more specifically MuiAvatar-root.

Material-Ui Version: 4.11.3

I followed material-ui's examples as shown here to override but to no good effect.

In the Avatar below

1st

<Grid item>
    <Avatar alt="avatar" src={avatar} classes={{root: classes.root }} />
</Grid>

since the one below didn't work and almost no other methods did either.

root: {
    width: "128px",
    height: "128px",
    margin: "8px",
},

However, I was able to override this using the overrides key as below in my global theme styles

const theme = createMuiTheme({
  // Not Required
  overrides: {
    MuiAvatar: {
      root: {
        width: "128px",
        height: "128px",
        margin: "8px",
      },
    }
  },
  palette: {
    primary: { 
      light:'#fff', 
      main: '#158ade', //Curious Blue
      contrastText: '#f1de39', //golden dream
      dark: '#cd4315', //tia maria
     },
    secondary: {
      light: '#DAE9F1', //Black Squeeze
      main: '#D1D100',  //Corn
      dark: '#2D344D', //Martinique 
      contrastText: '#000',
    },
  },
});

But this also messed all the Avatars that I was using in my project which I didn't want. An example below:
2nd

<Container className={classes.center}>
    <Avatar className={ classes.avatar }>
        <ContactMailIcon />
    </Avatar>
</Container>
const useStyles = makeStyles((theme) => ({
  paper: {
    marginTop: theme.spacing(8),
    display: 'flex',
    flexDirection: 'column',
    alignItems: 'center',
  },
  heading: {
    color: theme.palette.primary.dark,
  },
  avatar: {
    margin: theme.spacing(1),
    backgroundColor: "#ff4838",
    alignItems: 'center',
  },
  form: {
    width: '100%', // Fix IE 11 issue.
    marginTop: theme.spacing(1),
  },
  submit: {
    margin: theme.spacing(3, 0, 2),
  },
  center: {
    display: 'flex',
    alignItems: 'center',
    flexDirection: 'column'
    }
}));

However, I somehow solved the issue using '&&' (came across '&' when searching about override and just worked during hit and trial) in both cases as below:

In reference to 1st

root: {
        '&&': {
            width: "128px",
            height: "128px",
            margin: "8px",
        }
    },

and 2nd with below

export const useContactStyles = makeStyles((theme) => ({
    paper: {
        marginTop: theme.spacing(8),
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'center',
    },
    heading: {
        color: theme.palette.primary.dark,
    },
    avatar: {
        "&&": {
            margin: theme.spacing(1),
            backgroundColor: "#ff4838",
            alignItems: 'center',
        }
    },
    form: {
        width: '100%', // Fix IE 11 issue.
        marginTop: theme.spacing(1),
    },
    submit: {
        margin: theme.spacing(3, 0, 2),
    },

    center: {
        "&&": {
            display: 'flex',
            alignItems: 'center',
            flexDirection: 'column'
        }
    }
}));

This did override the default MuiAvatar-root class and I was able to individually change styles, however, I'm not sure what the '&&' or even '&' does, I understand it has something to do with SASS, but I've never worked with that and how it's working here.

I just want to understand how using the double ampersands overrides the root classes. i.e. MuiAvatar-root in this case. I just made it work during hit & trial, And don't know if this is even the right way or not.

EDIT

**As explained by @Bassem and this article the '&&' is used to increase the specificity/priority.

For me, the '&&' solved my problem, and I don't think it messed up anything.

However, I am still wondering why or why not is this a good practice to use this method? Are there any downsides to using the '&&'?**

Shady7447
  • 89
  • 11

1 Answers1

1

In order to make the classes work, you have to use the makeStyles utility like this:

import { Avatar } from "@material-ui/core";
import { makeStyles } from "@material-ui/core/styles";

const useStyles = makeStyles((theme) => ({
  root: {
    width: "128px",
    height: "128px",
    margin: theme.spacing(1),
  }
}));

export default function App() {
  const classes = useStyles();
  return (
      <Avatar classes={{ root: classes.root }} />
  );
}

Here is a working example: https://codesandbox.io/s/friendly-chatterjee-w507i


Normally, you're not supposed to use the double ampersand syntax to customize Material UI's components. But to answer your question, it's used to increase/double up the specificity. There is a great article that explains this: https://dev.to/magischerzwerg/double-ampersand-trick-in-sass-with-react-4khe

Bassem
  • 3,582
  • 2
  • 24
  • 47
  • Thanks for the response, I already had tried the makeStyles utility the way you have suggested above, but I couldn't override the root class with that method. Therefore I was looking for other ways. Also, I think the issue raised with me wrapping my app with the ThemeProvider using a global theme. However, I now understand what the '&&' does here. So, thank you for sharing the article. – Shady7447 May 06 '21 at 14:25
  • Something might be wrong in your project then, because that's the way you should be overriding MUI component styles. Also having a ThemeProvider shouldn't mess up this functionality – Bassem May 06 '21 at 14:39
  • It is just a guess that the ThemeProvider messed things up because before that I was able to override the Avatar, However, I'll have to do checks to see if that is really what caused the issue. I'll try removing the ThemeProvider and see if that is actually causing it. – Shady7447 May 06 '21 at 14:44
  • So, removing ThemeProvider didn't fix the issue, but the issue arises when I import my style from another file. I have a separate file (Styles.js) that stores all my styles. If I write my styles in the same file i.e. where the component where I'm using Avatar or other Material-UI components, the style does override the root but if I move my style to another file and import it's unable to override. I'm not sure why this is though, any idea? What am I missing? – Shady7447 May 06 '21 at 15:30
  • Importing styles from other files should work as well, I updated the codesandbox example where you can see it's working fine. Not sure why you're having this issue – Bassem May 06 '21 at 16:37
  • I found an explanation [here](https://stackoverflow.com/questions/56929702/material-ui-v4-makestyles-exported-from-a-single-file-doesnt-retain-the-styles) I've also added my solution there, and I'm still trying to understand why the '&&' is or isn't a good way. As it did solve my problem that I've noticed. – Shady7447 May 07 '21 at 09:15