How to add multiple classes in Material UI using the classes props?

171.6k Views Asked by At

Using the css-in-js method to add classes to a react component, how do I add multiple components?

Here is the classes variable:

const styles = theme => ({
  container: {
    display: 'flex',
    flexWrap: 'wrap'
  },
  spacious: {
    padding: 10
  },
});

Here is how I used it:

return (<div className={ this.props.classes.container }>)

The above works, but is there a way to add both classes, without using the classNames npm package? Something like:

<div className={ this.props.classes.container + this.props.classes.spacious}>
13

There are 13 best solutions below

5
On BEST ANSWER

you can use string interpolation:

<div className={`${this.props.classes.container} ${this.props.classes.spacious}`}>
4
On

you can install this package

https://github.com/JedWatson/classnames

and then use it like this

classNames('foo', 'bar'); // => 'foo bar'
classNames('foo', { bar: true }); // => 'foo bar'
classNames({ 'foo-bar': true }); // => 'foo-bar'
classNames({ 'foo-bar': false }); // => ''
classNames({ foo: true }, { bar: true }); // => 'foo bar'
classNames({ foo: true, bar: true }); // => 'foo bar'

// lots of arguments of various types
classNames('foo', { bar: true, duck: false }, 'baz', { quux: true }); // => 'foo bar baz quux'

// other falsy values are just ignored
classNames(null, false, 'bar', undefined, 0, 1, { baz: null }, ''); // => 'bar 1'
1
On

Yes, jss-composes provides you this:

const styles = theme => ({
 container: {
  display: 'flex',
  flexWrap: 'wrap'
},
 spacious: {
  composes: '$container',
  padding: 10
},
});

And then you just use classes.spacious.

2
On

If you want to assign multiple class names to your element, you can use arrays.

So in your code above, if this.props.classes resolves to something like ['container', 'spacious'], i.e. if

this.props.classes = ['container', 'spacious'];

you can simply assign it to div as

<div className = { this.props.classes.join(' ') }></div>

and result will be

<div class='container spacious'></div>
0
On

It can be done painlessly with descructuring, after all, these are JavaScript objects:

const truncate = {
  width: '100px',
  whiteSpace: 'nowrap',
  overflow: 'hidden',
  textOverflow: 'ellipsis',
};
email: {
    color: '#747474',
    ...truncate,
  },
0
On

You can add multiple string classes and variable classes or props classes at same time in this way

className={`${classes.myClass}  ${this.props.classes.myClass2} MyStringClass`}

three classes at same time

0
On

You can use this method below:

import clsx from 'clsx';
    
return <div className={clsx(classes.container, 'spacious')} />

This link helps.

1
On

classNames package can also be used as advanced as:

import classNames from 'classnames';

var arr = ['b', { c: true, d: false }];
classNames('a', arr); // => 'a b c'

let buttonType = 'primary';
classNames({ [`btn-${buttonType}`]: true }); // => 'btn-primary'
0
On

To have multiple classes applied to a component, wrap the classes you would like to apply within classNames.

For example, in your situation, your code should look like this,

import classNames from 'classnames';

const styles = theme => ({
  container: {
    display: "flex",
    flexWrap: "wrap"
  },
  spacious: {
    padding: 10
  }
});

<div className={classNames(classes.container, classes.spacious)} />

Make sure that you import classNames!!!

Have a look at material ui documentation where they use multiple classes in one component to create a customized button

0
On

I think this will solve your problem:

const styles = theme => ({
 container: {
  display: 'flex',
  flexWrap: 'wrap'
},
 spacious: {
  padding: 10
},
});

and in react component:

<div className={`${classes.container} ${classes.spacious}`}>
0
On

You can apply two classes in material UI like that

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

const useStyles = makeStyles({
  container: {
    display: 'flex',
    flexWrap: 'wrap',
  },
  spacious: {
    padding: 10,
  },
});

some code


 <div className={classNames(classes.container, classes.spacious)}>
      Try this one!
 </div>

How to add two classes using the comparison operator in Material UI.

If you want to use the comparison operator to define one or two classes, you need to apply


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

const useStyles = makeStyles({
  maineButton: {
   borderRadius: "10px",
   minWidth: "80px",
   border: "1x solid #dcdcdc",
  },
  selectedButton: {
    border: "1x solid #3f51b5",
  },
});

some code

const [selected, setSelected] = useState(0);

some code

{data?.map((el, index) => (
   <ButtonBase 
     className={classNames(
        classes.maineButton, 
        index === selected && classes.selectedButton
        )}
     onClick{()=> setSelected(index)}
   >
     {el.text}
   </ButtonBase>
))}

if selected it will give you two classes

className={classNames(classes.maineButton, classes.selectedButton)}

if not, it will be only one

className={classNames(classes.maineButton)}
5
On

You could use clsx. I noticed it used in the MUI buttons examples

First install it:

npm install --save clsx

Then import it in your component file:

import clsx from 'clsx';

Then use the imported function in your component:

<div className={ clsx(classes.container, classes.spacious)}>

1
On

You can also use the extend property (the jss-extend plugin is enabled by default):

const styles = theme => ({
  container: {
    display: 'flex',
    flexWrap: 'wrap'
  },
  spaciousContainer: {
    extend: 'container',
    padding: 10
  },
});

// ...
<div className={ this.props.classes.spaciousContainer }>