how place a button at the center of the image on hover with Material UI (MUI) and reacts?

Viewed 47

I have tried looking online and there are some examples of hovering using material ui and more specifically there are some examples using the CardMedia from MUI but I am having trouble adapting it to my case.

I want to add transparency to the existing picture and add a button in the center when the user hovers over the image.

But so far this is the code I have:

const [Hover, setHover] = useState(false);

    const handleMouseEnter = () => {
        setHover(true);
    }

    const handleMouseLeave = () => {
        setHover(false);
    }

    const Butt = <Button variant="contained">Get a Free Quote</Button>


    return (
        <Box p={5}>
            <Grid container spacing={5} justify="center">
                {images.map((product, i) => {
                    return (
                        <Grid key={i} item xs={12} sm={6} md={4}>

                            <Card sx={{ minWidth: 200 }}>
                                <CardMedia
                                    component="img"
                                    height="200"
                                    image={product.img}
                                    alt="work portfolio" 
                                    onMouseOver={handleMouseEnter}
                                    onMouseOut={handleMouseLeave}/>

                            </Card>

                            {Hover && (
                                <div>
                                    <Butt/>
                                </div>
                            )}





                        </Grid>
                    );
                })}
            </Grid>
        </Box>
    )

2 Answers

You can achieve the same with just css. Have a look at the code below and this working codesandbox

What it does is just creating a Container that has the image and the Button. Then I styled the button to be hidden initially and is shown when hovering on the container (which is your Card).

import * as React from "react";
import { styled } from "@mui/material/styles";
import Card from "@mui/material/Card";
import CardMedia from "@mui/material/CardMedia";
import Grid from "@mui/material/Grid";
import Button from "@mui/material/Button";

const ButtonStyled = styled(Button)`
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  margin: auto;
  width: fit-content;
  height: 40px;
  display: none;
`;

const ContainerStyled = styled("div")`
  position: absolute;
  &:hover {
    .test-button {
      display: block;
    }
  }  
}`;

export default function RecipeReviewCard() {
  return (
    <Grid container spacing={5} justify="center">
      <Grid item xs={12} sm={6} md={4}>
        <ContainerStyled>
          <Card sx={{ minWidth: 200 }}>
            <CardMedia
              component="img"
              height="200"
              image="https://mui.com/static/images/cards/paella.jpg"
              alt="work portfolio"
            />
          </Card>
          <ButtonStyled variant="contained" className="test-button">
            Test button
          </ButtonStyled>
        </ContainerStyled>
      </Grid>
      <Grid item xs={12} sm={6} md={4}>
        <ContainerStyled>
          <Card sx={{ minWidth: 200 }}>
            <CardMedia
              component="img"
              height="200"
              image="https://mui.com/static/images/cards/paella.jpg"
              alt="work portfolio"
            />
          </Card>
          <ButtonStyled variant="contained" className="test-button">
            Test button 2
          </ButtonStyled>
        </ContainerStyled>
      </Grid>
    </Grid>
  );
}

Let me know if it helps.

using useState you can toggle between display=none to not display the button on onMouseLeave and display=block to display the button onMouseEnter

this is an example using your code :

import React, { useState } from "react";
import "./style.css";
import Grid from "@material-ui/core/Grid";
import Button from "@material-ui/core/Button";
import Box from "@material-ui/core/Box";
import Card from "@material-ui/core/Card";
import CardMedia from "@material-ui/core/CardMedia";

const Butt = ({ display }) => {
  return (
    <div className={display}>
      <Button
        style={{
          position: "absolute",
          top: "80%",
          left: "50%",
          transform: "translate(-50%, -50%)",
        }}
        variant="contained"
      >
        Get a Free Quote
      </Button>
    </div>
  );
};

export default function App() {
  const [display, setDisplay] = useState("notdisplayed");
  const showButton = (e) => {
    e.preventDefault();
    setDisplay("displayed");
  };

  const hideButton = (e) => {
    e.preventDefault();
    setDisplay("notdisplayed");
  };
  return (
    <Box p={5}>
      <Grid container spacing={5} justifyContent="center">
        <Grid item xs={12} md={4} sm={6}>
          <Card
            sx={{ minWidth: 200 }}
            style={{ position: "relative", width: "100%" }}
          >
            <div
              onMouseEnter={(e) => showButton(e)}
              onMouseLeave={(e) => hideButton(e)}
            >
              <CardMedia
                style={{
                  marginLeft: "auto",
                  marginRight: "auto",
                  width: "100%",
                  height: "auto",
                  zIndex: "1",
                }}
                component="img"
                height="200"
                image="https://st.depositphotos.com/1001894/3115/i/600/depositphotos_31157709-stock-photo-hassan-ii-mosque-in-casablanca.jpg"
                alt="work portfolio"
              />
              <Butt display={display} />
            </div>
          </Card>
        </Grid>
      </Grid>
    </Box>
  );
}

add style.css to make these styling in it :

.notdisplayed {
  display: none;
}

.displayed {
  display: block;  
}
  

this is a demo in codesandbox .

Related