How to maintain the hover effect of the sibling in Material-UI

Card Component

import image from "../../Assets/pic.jpg";
import React, { useState } from "react";
import { makeStyles } from "@material-ui/core/styles";
import Card from "@material-ui/core/Card";
import CardActionArea from "@material-ui/core/CardActionArea";
import FavoriteBorderIcon from "@material-ui/icons/FavoriteBorder";
import CardContent from "@material-ui/core/CardContent";
import CardMedia from "@material-ui/core/CardMedia";
import Typography from "@material-ui/core/Typography";
import styles from "./Cards.module.css";
import Stars from "../Stars/Stars";

const useStyles = makeStyles({
  root: {
    maxWidth: 345,
  },
});

const Cards = () => {
  const [showComponent, setShowComponent] = useState(false);
  const classes = useStyles();

  const handleToggleHoverIn = (event) => {
    event.preventDefault();
    setShowComponent(true);
  };

  const handleToggleHoverOut = (event) => {
    event.preventDefault();
    setShowComponent(false);
  };

  console.log("The state showComponent value is ", showComponent);

  return (
    <div className={styles.container}>
      <Card
        onMouseEnter={handleToggleHoverIn}
        onMouseLeave={handleToggleHoverOut}
        className={classes.root}
      >
        <CardActionArea>
          <div id={styles.imageCentre}>
            <CardMedia
              component="img"
              alt=""
              className={styles.image}
              image={image}
              title="Contemplative Reptile"
            />

            {/*
            here when I hover over my <Stars/> and  <FavoriteBorderIcon/>, the hover effect of opacity that I have on
            my Card's image, vanishes
             */}
            {showComponent ? (
              <>
                <div id={styles.stars}>
                  <Stars />
                </div>
                <FavoriteBorderIcon fontSize="large" id={styles.heart} />
              </>
            ) : null}
          </div>
          <CardContent>
            <Typography
              gutterBottom
              variant="h5"
              component="h2"
              id={styles.textCentre}
            >
              Printed round Neck
            </Typography>
            <Typography variant="body2" color="textSecondary" component="p">
              <div class="text">
                <p id={styles.price}>
                  <b>Rs. 454</b>
                  <strike>Rs. 699</strike>
                  <span style={{ color: "#FF7F7F" }}> (35 % off) </span>
                </p>
              </div>
            </Typography>
          </CardContent>
        </CardActionArea>
      </Card>
    </div>
  );
};

export default Cards;

Card’s CSS styling

.image {
  width: 300px;
  justify-content: center;
}

.image:hover {
  opacity: 0.5;
}

#imageCentre {
  align-items: center !important;
  position: relative;
}

/* #imageCentre:hover {
  opacity: 0.5;
} */

#textCentre {
  text-align: center;
}

.container {
  display: flex;
  justify-content: center;
  padding: 2em;
}

#price,
.text h3 {
  text-align: center;
}

#price b {
  padding-right: 0.5em;
  font-size: 1.3em;
}

#heart {
  position: absolute;
  top: 0;
  right: 0;
  padding: 20px 20px 0 0;
  color: aliceblue;
}

#stars {
  position: absolute;
  top: 50%;
  left: 50%;
  margin-right: -50%;
  transform: translate(-50%, -50%);
  margin-top: 50%;
}

when I hover over my card, the opacity hover-effect comes in but when I move to the heart or star component, the opacity-hover vanishes. I want the hover-effect to remain even when I hover over my star and heart component. Is there any way that I can make the opacity-hover-effect to remain there, when I hover over the stars and heart component

Live Link

Answer

Below is an example of one way to do this. The key aspect of the solution is to use the :hover pseudo-class on a common parent of the img, stars, and icon elements. In my example, this is done via the action class applied to the CardActionArea element. My example is using makeStyles, but you could achieve the same effect in your CSS with the following:

#imageCentre:hover .image {
  opacity: 0.5;
}

It looks like you tried something similar (the commented out #imageCenter:hover styles), but since you weren’t targeting the descendant .image class for the opacity, the opacity would have impacted the stars and favorite icon as well which you probably don’t want.

Here’s a full working example:

import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Card from "@material-ui/core/Card";
import CardActionArea from "@material-ui/core/CardActionArea";
import CardActions from "@material-ui/core/CardActions";
import CardContent from "@material-ui/core/CardContent";
import CardMedia from "@material-ui/core/CardMedia";
import Button from "@material-ui/core/Button";
import Typography from "@material-ui/core/Typography";
import FavoriteBorderIcon from "@material-ui/icons/FavoriteBorder";
import Rating from "@material-ui/lab/Rating";

const useStyles = makeStyles({
  root: {
    maxWidth: 345
  },
  media: {
    height: 140
  },
  action: {
    position: "relative",
    "&:hover $media": {
      opacity: 0.5
    }
  },
  favorite: {
    position: "absolute",
    top: 10,
    left: 10,
    color: "white"
  },
  rating: {
    position: "absolute",
    top: 100,
    left: 100
  }
});

export default function MediaCard() {
  const classes = useStyles();

  return (
    <Card className={classes.root}>
      <CardActionArea className={classes.action}>
        <CardMedia
          component="img"
          className={classes.media}
          image="https://material-ui.com/static/images/cards/contemplative-reptile.jpg"
          title="Contemplative Reptile"
        />
        <CardContent>
          <Typography gutterBottom variant="h5" component="h2">
            Lizard
          </Typography>
          <Typography variant="body2" color="textSecondary" component="p">
            Lizards are a widespread group of squamate reptiles, with over 6,000
            species, ranging across all continents except Antarctica
          </Typography>
        </CardContent>
        <FavoriteBorderIcon className={classes.favorite} />
        <Rating className={classes.rating} name="rating" />
      </CardActionArea>
      <CardActions>
        <Button size="small" color="primary">
          Share
        </Button>
        <Button size="small" color="primary">
          Learn More
        </Button>
      </CardActions>
    </Card>
  );
}

Edit image hover