I'm trying to achieve something similar to the products in this website: https://www.adidas.de/en/women-shoes-outlet
When I hover, I want the row below to stay at the same position and the hovered product overlays the one below.
I am using a combination of Material UI and plain old CSS. So far everything has been achieved except this exact problem. Right now the code is not in its final form but I am trying to get the layout finalized.
This is a codepen of the work so far codpen
Here is the React component:
import React from "react";
import "./ProductCard.css";
import ShareIcon from '@mui/icons-material/Share';
import { Grid, IconButton } from "@mui/material";
const PricePanel = ({ product }) => {
const { price, discount } = product;
let display_price;
if (discount) display_price = price - (price * (discount / 100));
return (
<div className="price-overlay">
{discount ?
<>
<div className="price">
<span style={{ textDecoration: "line-through" }}>€{Math.ceil(price)}</span>
{` `}
<span style={{ color: 'red' }}>€{Math.ceil(display_price)}</span></div>
</>
:
<div className="price">€{Math.ceil(price)}</div>}
</div>
);
};
const ProductCard = ({ product }) => {
const [currentImage, setCurrentImage] = React.useState(product.images[0].image);
const [checked, setChecked] = React.useState(false);
const handleColorHover = (image) => { setCurrentImage(image); };
const { id, title, description, discount } = product;
return (
<Grid item xs={12} md={6} lg={3} id={id}>
<div className="product-card">
<div className="product-image">
<img id="main" src={currentImage} alt="Product" />
{discount && (
<div className="discount-overlay">
-{Math.ceil(discount)}%
</div>
)}
<PricePanel product={product} />
<div className="color-options">
{product.images.map((item) => (
<img
key={item.color}
className="color-thumbnail"
src={item.thumbnail}
alt={item.color}
onMouseEnter={() => handleColorHover(item.image)}
/>
))}
</div>
</div>
<div className="product-details">
<h3 className="product-name">{title}</h3>
<p className="product-category">{description}</p>
<div className="icon-buttons" >
<IconButton aria-label="share">
<ShareIcon />
</IconButton>
<IconButton onClick={() => setChecked(!checked)} aria-label="fav">
<span className={checked ? 'checked' : 'notchecked'} color="#aab8c2">❤</span>
</IconButton>
</div>
</div>
</div>
</Grid >
);
};
export default ProductCard;
And here is the css
.product-card {
width: 100%;
overflow: hidden;
transition: transform 0.3s ease-in-out;
background-color: #fff;
text-align: center;
position: relative;
cursor: pointer;
}
.product-card:hover {
position: relative;
z-index: 10000;
border: 1px solid #ccc;
}
.product-image {
position: relative;
width: 100%;
}
.product-image #main {
width: 100%;
display: block;
transition: transform 0.3s ease-in-out;
}
.color-options {
display: none;
justify-content: left;
background-color: #fff;
}
.product-card:hover .color-options {
display: flex;
}
.color-thumbnail {
height: 50px;
cursor: pointer;
}
.favorite-icon {
position: absolute;
top: 10px;
right: 10px;
color: #fff;
font-size: 24px;
cursor: pointer;
z-index: 100000;
}
.price-overlay {
position: absolute;
top: 85%;
left: 10px;
color: rgba(0, 0, 0, 0.7);
font-size: 0.7rem;
z-index: 1;
background-color: #fff;
padding: 5px 7px;
opacity: 50;
}
.discount-overlay {
position: absolute;
top: 5%;
right: 10px;
color: rgba(0, 0, 0, 0.7);
font-weight: bold;
font-size: 0.7rem;
z-index: 1;
background-color: #fff;
padding: 5px 7px;
opacity: 50;
}
.product-card:hover .price-overlay {
top: 75%;
}
.product-details {
padding: 10px;
background-color: #fff;
}
.product-name {
margin: 0;
font-size: 16px;
text-align: left;
}
.product-category {
margin-top: 5px;
color: #777;
font-size: 14px;
text-align: left;
}
.icon-buttons {
float: right;
}
.strike {
text-decoration: 'line-through';
}
.checked {
color: #e2264d;
}
The ProductCard component is wrapped in a simple Grid
<Grid item container spacing={1} xs={12}></Grid>