Use SCSS (react + material) without !important as much as possible

I am working on a Select component in React using Material UI. The project uses an external SCSS sheet imported in the script file for the component. I am unable to restyle the CSS of the component other than with the generic Material UI classes. When I do so, I need to use !important to overwrite the attributes.

The .js looks like this:

<Select
    value={this.state.age}
    onChange={this.handleChange}
    name="age"
    displayEmpty
    className='select-row-items'
    IconComponent = {ExpandMore}
    MenuProps={{
        anchorOrigin: {
            vertical: "bottom",
            horizontal: "left"
        },
        transformOrigin: {
            vertical: "top",
            horizontal: "left"
        },
        getContentAnchorEl: null
    }}>
    <MenuItem disableGutters={true} value="">123-456-789123456-01</MenuItem>
    <MenuItem disableGutters={true} value={10}>123-000-457889562-00</MenuItem>
    <MenuItem disableGutters={true} value={20}>122-586-888865987-00</MenuItem>
</Select>

I am only able to style components directly within the className ‘select-row-items’ which I assigned myself. For the MenuItems, I have to use generic classes and !important for every value so it will work.

Is there another way to improve the CSS?

My CSS looks like this:

.select-row-items {

  .MuiSelect-select {
    background-color: #D5E4EE; //replace with variables for secondary colors (light blue)
    color: #194581; //replace with variables for secondary colors (dark blue)
    font-size: 12px;
    font-weight: normal;
    padding: 4px 12px;

    &.MuiSelect-select {
      padding-right: 36px;
    }

    &:focus {
      background-color: #D5E4EE; //replace with variables for secondary colors (light blue)
    }

    &::after {
      content: '';
      position: absolute;
      right: 0;
      top: 0;
      bottom: 0;
      width: 25px;
      background-color: rgba(0, 0, 0, 0.1);;
    }
  }

  .MuiSelect-icon {
    font-size: 16px;
    color: #194581; //replace with variables for secondary colors (dark blue)
    font-weight: lighter;
    right: 4.5px;
    top: 50%;
    transform: translateY(-50%);
  }

  &.MuiInput-underline:before,
  &.MuiInput-underline:hover:not(.Mui-disabled):before,
  &.MuiInput-underline:after {
    display: none;
  }
}

.MuiList-root {
  padding: 0 !important;
  background-color: #D5E4EE; //replace with variables for secondary colors (light grey)

}
.MuiPopover-paper {
  left: 0!important;
  border-radius: 0 !important;
  box-shadow: none !important;
}

.MuiMenuItem-root {
  font-size: 12px !important;
  color: #194581 !important; //replace with variables for secondary colors (dark blue)
  font-weight: normal;
  padding: 5px 12px !important;
  border-bottom: 1px solid #fff !important;

  &:first-child {
    border-top: 1px solid #fff !important;
  }
}

.MuiListItem-button:hover, .MuiListItem-root.Mui-selected:hover {
  background-color: #194581 !important; //replace with variables for secondary colors (dark blue)
  color: #ffffff !important;
}

.MuiListItem-root.Mui-selected {
  background-color: rgba(0, 0, 0, 0.1) !important;
}

I am trying to improve the styling of a Select component in React using Material UI. The project uses an external SCSS sheet imported in the script file for the component. I have to use generic Material UI classes and !important to overwrite the attributes.

Are there any alternate ways to improve the styling?

One way to improve the styling of Material UI components is to use the makeStyles hook provided by Material UI. This hook allows you to define styles in a more modular and reusable way, without having to use !important or generic classes.

Here’s an example of how you could use makeStyles to style a Select component:

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

const useStyles = makeStyles(theme => ({
  select: {
    backgroundColor: theme.palette.secondary.light,
    color: theme.palette.secondary.dark,
    fontSize: 12,
    fontWeight: 'normal',
    padding: '4px 12px',
    paddingRight: 36,
    '&:focus': {
      backgroundColor: theme.palette.secondary.light,
    },
    '&::after': {
      content: '',
      position: 'absolute',
      right: 0,
      top: 0,
      bottom: 0,
      width: 25,
      backgroundColor: 'rgba(0, 0, 0, 0.1)',
    },
  },
  icon: {
    fontSize: 16,
    color: theme.palette.secondary.dark,
    fontWeight: 'lighter',
    right: 4.5,
    top: '50%',
    transform: 'translateY(-50%)',
  },
  list: {
    padding: 0,
    backgroundColor: theme.palette.secondary.light,
  },
  paper: {
    left: 0,
    borderRadius: 0,
    boxShadow: 'none',
  },
  menuItem: {
    fontSize: 12,
    fontWeight: 'normal',
    padding: '5px 12px',
    borderBottom: `1px solid ${theme.palette.common.white}`,
    '&:first-child': {
      borderTop: `1px solid ${theme.palette.common.white}`,
    },
    '&:hover': {
      backgroundColor: theme.palette.secondary.dark,
      color: theme.palette.common.white,
    },
    '&$selected': {
      backgroundColor: 'rgba(0, 0, 0, 0.1)',
    },
  },
  selected: {},
}));

function MySelect() {
  const classes = useStyles();

  return (
    <Select
      value={this.state.age}
      onChange={this.handleChange}
      name="age"
      displayEmpty
      classes={{
        select: classes.select,
        icon: classes.icon,
        list: classes.list,
        paper: classes.paper,
        menuItem: classes.menuItem,
        selected: classes.selected,
      }}
      IconComponent={ExpandMore}
      MenuProps={{
        anchorOrigin: {
          vertical: 'bottom',
          horizontal: 'left',
        },
        transformOrigin: {
          vertical: 'top',
          horizontal: 'left',
        },
        getContentAnchorEl: null,
        classes: {
          paper: classes.paper,
        },
      }}
    >
      <MenuItem disableGutters value="">
        123-456-789123456-01
      </MenuItem>
      <MenuItem disableGutters value={10}>
        123-000-457889562-00
      </MenuItem>
      <MenuItem disableGutters value={20}>
        122-586-888865987-00
      </MenuItem>
    </Select>
  );
}

In this example, we define all the styles using makeStyles, and then pass the generated classes to the Select component using the classes prop. This allows us to style the component in a more modular way, without having to use !important or generic classes.

Note that we also pass the classes prop to the MenuProps, which allows us to style the Popover and MenuList components as well.