如何在Material-UI中实现卡片自适应等高(非固定高度)
在Material-UI中实现等高动态卡片并添加按钮间距的方案
要实现所有卡片高度动态匹配最高卡片,同时给按钮和内容添加间距,核心是利用Flexbox的拉伸和自动间距特性,无需设置固定高度。以下是具体修改步骤和代码:
关键修改点
- 外层Grid对齐调整:将卡片所在Grid容器的
alignItems="center"改为alignItems="stretch",让每个卡片容器自动拉伸到同一高度。 - 卡片Flex布局优化:卡片根容器使用
flexDirection: 'column',内容区域通过flexGrow: 1自动填充剩余空间,按钮区域用marginTop: 'auto'固定在底部,同时生成内容与按钮的间距。 - 按钮区域内边距:给按钮容器添加上下内边距,让按钮与卡片边缘、上方内容都保持合适间距。
修改后的完整代码
function ItemRow({ page_block }) { return page_block.map((page_block_item, index) => ( <Grid justifyContent="space-between" alignItems="stretch" // 改为stretch使卡片容器等高 align="center" xs={12} sm={6} md={4} lg={4} key={index} // 给外层Grid添加key避免React警告 > <Grid justifyContent="center" xs={10.5} sm={12} md={11} lg={12} > <Card page_block_item={page_block_item} /> </Grid> </Grid> )); } const Card = ({ page_block_item: block_detail }) => { const [open, setOpen] = useState(false); const router = useRouter(); const [cart, setCart] = useAtom(cartAtom); return ( <Grid key={block_detail.id} justifyContent="center" display={'flex'} flexGrow={1} alignItems="stretch" > <Box sx={{ position: 'relative', display: 'flex', flexDirection: 'column', height: '100%', // 确保卡片填满父容器高度 boxShadow: '0px 6px 12px -6px rgba(24, 39, 75, 0.12)', }} border="1px solid #E3E3E3" borderRadius="8px" overflow="hidden" margin={2} flexGrow={1} > {/* 图片区域 */} <Grid sx={{ position: 'relative' }}> <Grid item position="relative" sx={{ aspectRatio: '3/2', height: '100%' }} > <NextImage className="image-cover" media={block_detail.media} /> </Grid> <Box sx={{ position: 'absolute', right: 0, bottom: 20, }} > <ShareIcon sx={{ background: '#FC916A', marginRight: '15px', padding: '5px', height: '30px', width: '30px', borderRadius: '50%', color: '#FFFFFF', cursor: 'pointer', '&:hover': { background: '#FFFFFF', color: '#FC916A', }, }} /> <BookmarkBorderIcon sx={{ background: '#FC916A', marginRight: '15px', padding: '5px', height: '30px', width: '30px', borderRadius: '50%', color: '#FFFFFF', cursor: 'pointer', '&:hover': { background: '#FFFFFF', color: '#FC916A', }, }} /> </Box> </Grid> {/* 内容区域:自动填充剩余空间 */} <Box sx={{ flexGrow: 1, display: 'flex', flexDirection: 'column', padding: 2, }} > <Grid item sx={{ textAlign: 'left' }}> <StyledText my={1} variant="H_Regular_Tagline" color="primary.main" content={block_detail.info_title} /> </Grid> <Grid item sx={{ textAlign: 'left' }}> <StyledText my={1} variant="H_Regular_Body" color="secondary.dark" content={block_detail.info_description} /> </Grid> </Box> {/* 按钮区域:固定在底部并添加间距 */} <Grid item sx={{ position: 'relative', marginTop: 'auto', // 自动推至底部,生成内容与按钮的间距 padding: '16px 24px', // 添加内边距,优化按钮与卡片边缘的距离 textAlign: 'center' }} > <Link href={`/${router.query.centerName}/post/donation/${block_detail?.slug}`} > <StyledButton variant="H_Regular_H4" sx={{ width: '90%' }} > {block_detail.info_action_button?.text} </StyledButton> </Link> </Grid> </Box> </Grid> ); };
效果说明
修改后,同一行的所有卡片会自动匹配最高卡片的高度,内容区域根据文本长度自适应扩展,按钮始终固定在卡片底部,同时按钮与上方内容、卡片边缘都保持合理间距,完全满足动态等高的需求。
内容的提问来源于stack exchange,提问作者Jackson Kasi
相关产品推荐
相关产品推荐

