When to use 'classes' vs 'className' with Material UI?

Viewed 16583

I'm a little confused with the two properties. If I have,

const useStyles = makeStyles(() => ({
  style: {
    width: 600,
    height: 400,
  },
}));

Then, I can do,

const classes = useStyles();

<SomeComponent className={classes.style} />

But I can also do,

const classes = useStyles();

<SomeComponent classes={classes} />

What is the difference between these two?

4 Answers

This is a very confusing aspect of MUI, but once you get it - it's super easy.

Consider that YOU are writing a component, and style it using JSS:

const useStyles = makeStyles(theme => ({
  root: {
    margin: theme.spacing(1)
  },
  in: {
    padding: 8
  }
}));

function MyComponent(){
  const classes = useStyles();
  return (
    <Outside className={classes.root}>
      <Inside className={classes.in} />
    </Outside>
  )
}

Notice that the component is essentially a composition (or a hierarchy) of components - Outside and Inside in this minimal example, but MUI components often have more than two (styled) nested components.

Now you want to export this component as part of a library and allow developers to style all the components involved (both Outside and Inside). How would you do it?

What MUI does, is it allows you to provide a classes property (you'll see in the docs each component's rule names - root and in in our example) that will be merged into MUI's own rules, or stylesheet if you wish (in the MUI code this is done using the withStyles HOC).

For convenience, every component also accepts className property that is merged into the className of the root element (Outside in our case).

className is always applied to the root element of the component whereas classes gives you deeper access to style child elements of the component via the object key of the style object. It's explained in the documentation here:

https://material-ui.com/customization/components/

both are for apply styles with some differences:
className property:

  • it is for classes that you defined and wrote.
  • it is always applied to the root element.

but

classes property:

  • uses for overrides global classes name that defined in Material UI.
  • just uses for Material UI components and it has no effect on the components you created.
  • it uses for access to deeper and nested elements. (unlike the className that applied to the root element)
    for example, override MuiButton-label in the global classes material UI
.
.
.

const useStyles = makeStyles(theme => ({
    label: {
        color: "#fff"
    }
}));

.
.
.

const classes = useStyles()

.
.
.

<Button classes={{ label: 'my-class-name' }} />

source: documentation for more information

dev tools

Related