如何在React+Material UI中实现图片hover时居中显示按钮并加透明度
解决Material UI CardMedia悬停时的透明度与中央按钮显示问题
你的代码存在三个核心问题,导致无法实现需求:
- 全局共用悬停状态:所有卡片共享同一个
Hover状态,鼠标悬停任意一张卡片,所有按钮都会显示 - 按钮位置错误:按钮渲染在卡片下方,而非图片中央
- 缺少图片透明度样式:未添加悬停时图片的透明度变化效果
以下是修改后的完整代码,完全适配你的需求:
import { useState } from 'react'; import { Box, Grid, Card, CardMedia, Button } from '@mui/material'; // 假设images是你的图片数组 const images = [/* 你的图片数据 */]; export default function PortfolioCards() { // 用对象存储每个卡片的悬停状态,key为卡片索引 const [hoverStates, setHoverStates] = useState({}); const handleMouseEnter = (index) => { setHoverStates(prev => ({ ...prev, [index]: true })); }; const handleMouseLeave = (index) => { setHoverStates(prev => ({ ...prev, [index]: false })); }; return ( <Box p={5}> <Grid container spacing={5} justifyContent="center"> {images.map((product, i) => { const isHovered = hoverStates[i] || false; return ( <Grid key={i} item xs={12} sm={6} md={4}> {/* 用相对定位容器包裹卡片和按钮,实现按钮层叠在图片上 */} <Box sx={{ position: 'relative', width: '100%' }}> <Card sx={{ minWidth: 200 }}> <CardMedia component="img" height="200" image={product.img} alt="work portfolio" onMouseEnter={() => handleMouseEnter(i)} onMouseLeave={() => handleMouseLeave(i)} {/* 添加悬停时的透明度过渡效果 */} sx={{ transition: 'opacity 0.3s ease', opacity: isHovered ? 0.7 : 1, }} /> </Card> {/* 按钮绝对定位在图片中央,仅悬停时显示 */} {isHovered && ( <Box sx={{ position: 'absolute', top: '50%', left: '50%', transform: 'translate(-50%, -50%)', zIndex: 10, }} > <Button variant="contained">Get a Free Quote</Button> </Box> )} </Box> </Grid> ); })} </Grid> </Box> ); }
关键修改说明:
- 独立维护每个卡片的悬停状态:改用对象
hoverStates存储每个卡片索引对应的悬停状态,确保悬停事件只作用于当前卡片 - 按钮层叠定位:用
position: relative的Box包裹卡片和按钮,按钮设置position: absolute并通过transform: translate(-50%, -50%)实现居中,同时设置zIndex确保按钮显示在图片上层 - 图片透明度过渡:给CardMedia添加
transition实现平滑过渡,根据isHovered状态动态切换opacity值 - 修复按钮组件错误:直接在渲染时使用Button组件,避免了原代码中把JSX元素当作组件调用的错误
内容的提问来源于stack exchange,提问作者aSphereInAManifold
相关产品推荐
相关产品推荐

