You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Grid中上方行元素高度变化时下方行位置保持不变?

需求

实现商品卡片悬停交互效果:鼠标悬停在商品卡片上时,下方的行保持原有位置不动,被悬停的卡片能够覆盖下方的卡片(参考阿迪达斯官网商品布局逻辑)。

目前使用Material UI结合原生CSS开发,除该布局问题外其余功能均已实现,以下是当前的开发代码示例:

React组件

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;

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;
}

外层Grid容器说明

ProductCard组件被包裹在如下Grid组件中:

<Grid item container spacing={1} xs={12}></Grid>

内容的提问来源于stack exchange,提问作者momal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 06:32:14