The question is published on by Tutorial Guruji team.
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
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> ); }