How do you change a style of a child when hovering over a parent using material-ui jss styles How do you change a style of a child when hovering over a parent using material-ui jss styles reactjs reactjs

How do you change a style of a child when hovering over a parent using material-ui jss styles


Below is an example of the correct syntax for v4 ("& $addIcon" nested within &:hover). Further down are some v5 examples.

import * as React from "react";import { render } from "react-dom";import { Grid, makeStyles } from "@material-ui/core";import AddIcon from "@material-ui/icons/Add";const useStyles = makeStyles(theme => ({  outerDiv: {    backgroundColor: theme.palette.grey[200],    padding: theme.spacing(4),    '&:hover': {      cursor: 'pointer',      backgroundColor: theme.palette.grey[100],      "& $addIcon": {        color: "purple"      }   }  },  addIcon: (props: { dragActive: boolean }) => ({    height: 50,    width: 50,    color: theme.palette.grey[400],    marginBottom: theme.spacing(2)  })}));function App() {  const classes = useStyles();  return (    <Grid container>      <Grid item className={classes.outerDiv}>        <AddIcon className={classes.addIcon} />      </Grid>    </Grid>  );}const rootElement = document.getElementById("root");render(<App />, rootElement);

Edit eager-tesla-xw2cg

Related documentation and answers:


For those who have started using Material-UI v5, the example below implements the same styles but leveraging the new sx prop.

import Grid from "@mui/material/Grid";import { useTheme } from "@mui/material/styles";import AddIcon from "@mui/icons-material/Add";export default function App() {  const theme = useTheme();  return (    <Grid container>      <Grid        item        sx={{          p: 4,          backgroundColor: theme.palette.grey[200],          "&:hover": {            backgroundColor: theme.palette.grey[100],            cursor: "pointer",            "& .addIcon": {              color: "purple"            }          }        }}      >        <AddIcon          className="addIcon"          sx={{            height: "50px",            width: "50px",            color: theme.palette.grey[400],            mb: 2          }}        />      </Grid>    </Grid>  );}

Edit hover over parent


Here's another v5 example, but using Emotion's styled function rather than Material-UI's sx prop:

import Grid from "@mui/material/Grid";import { createTheme, ThemeProvider } from "@mui/material/styles";import AddIcon from "@mui/icons-material/Add";import styled from "@emotion/styled/macro";const StyledAddIcon = styled(AddIcon)(({ theme }) => ({  height: "50px",  width: "50px",  color: theme.palette.grey[400],  marginBottom: theme.spacing(2)}));const StyledGrid = styled(Grid)(({ theme }) => ({  padding: theme.spacing(4),  backgroundColor: theme.palette.grey[200],  "&:hover": {    backgroundColor: theme.palette.grey[100],    cursor: "pointer",    [`${StyledAddIcon}`]: {      color: "purple"    }  }}));const theme = createTheme();export default function App() {  return (    <ThemeProvider theme={theme}>      <Grid container>        <StyledGrid item>          <StyledAddIcon />        </StyledGrid>      </Grid>    </ThemeProvider>  );}

Edit hover over parent


And one more v5 example using Emotion's css prop:

/** @jsxImportSource @emotion/react */import Grid from "@mui/material/Grid";import { createTheme, ThemeProvider } from "@mui/material/styles";import AddIcon from "@mui/icons-material/Add";const theme = createTheme();export default function App() {  return (    <ThemeProvider theme={theme}>      <Grid container>        <Grid          item          css={(theme) => ({            padding: theme.spacing(4),            backgroundColor: theme.palette.grey[200],            "&:hover": {              backgroundColor: theme.palette.grey[100],              cursor: "pointer",              "& .addIcon": {                color: "purple"              }            }          })}        >          <AddIcon            className="addIcon"            css={(theme) => ({              height: "50px",              width: "50px",              color: theme.palette.grey[400],              marginBottom: theme.spacing(2)            })}          />        </Grid>      </Grid>    </ThemeProvider>  );}

Edit hover over parent


Possibly an obvious point, but just to add to the answer above: if you are referencing a separate className, don't forget that you also need to create it in the makeStyles hook or else it won't work. For instance:

const useStyles = makeStyles({  parent: {    color: "red",    "&:hover": {      "& $child": {        color: "blue" // will only apply if the class below is declared (can be declared empty)      }    }  },  // child: {} // THIS must be created / uncommented in order for the code above to work; assigning the className to the component alone won't work.})const Example = () => {  const classes = useStyles()  return (    <Box className={classes.parent}>      <Box className={classes.child}>        I am red unless you create the child class in the hook      </Box>    </Box>  )}