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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 02:07:27