如何实现Material UI中卡片的横向排列与自动换行?
如何让Material UI卡片横向排列并自动换行
问题描述
我在项目中使用Material UI,现有一组卡片,希望它们先横向依次排列,超出容器宽度后自动换行到下一行,但当前卡片是垂直堆叠显示的。尝试添加自定义CSS但未生效,以下是我的代码:
function Blogs() { const [expanded, setExpanded] = React.useState(false); const handleExpandClick = () => { setExpanded(!expanded); }; return ( <> <Box m={6}> <Card sx={{ maxWidth: 345 }}> <CardHeader title="It’s a cocktail o’clock." subheader="May 14, 2021" /> <CardMedia component="img" height="194" image="https://img.freepik.com/free-photo/selection-various-cocktails-table_140725-2909.jpg?w=2000" alt="Paella dish" /> <CardContent> <Typography variant="body2" color="text.secondary"> Beat The Heat With Chilled Cocktails At The Best Bars In New York. </Typography> </CardContent> <CardActions disableSpacing> <ExpandMore expand={expanded} onClick={handleExpandClick} aria-expanded={expanded} aria-label="show more" > <ExpandMoreIcon /> </ExpandMore> </CardActions> <Collapse in={expanded} timeout="auto" unmountOnExit> <CardContent> <Typography paragraph>To a foodie, summer means one thing and one thing only – DRINKS!</Typography> <Typography paragraph> Yes people, we know it’s hot out there and the only way to quench your thirst is by guzzling down a bunch of ice-cold cocktails </Typography> <Typography paragraph> <h4>1.The Bar Room at The Beekman</h4> Visit the beautiful Bar Room in the historic Beekman Hotel for high-key romance that really wows. Do try the whiskey sour.One of the best drinks available. <h4>2.Dublin House</h4> You can never go wrong with Sláinte! Margarita,Pot O'Gold, & Irish Old Fashioned <h4>3.Russian Samovar</h4> Alpensahne,Amarula Cream Liqueur, Caribou,Feni </Typography> </CardContent> </Collapse> </Card> </Box> <Box m={6}> <Card sx={{ maxWidth: 345 }}> <CardHeader title="Winner Winner Pizza Dinner" subheader="May 14, 2021" /> <CardMedia component="img" height="194" image="https://cdn.shopify.com/s/files/1/0624/9853/articles/20220211142645-margherita-9920.jpg?crop=center&height=800&v=1660843558&width=800" alt="Paella dish" /> <CardContent> <Typography variant="body2" color="text.secondary"> Beat The Heat With Chilled Cocktails At The Best Bars In New York. </Typography> </CardContent> <CardActions disableSpacing> <ExpandMore expand={expanded} onClick={handleExpandClick} aria-expanded={expanded} aria-label="show more" > <ExpandMoreIcon /> </ExpandMore> </CardActions> <Collapse in={expanded} timeout="auto" unmountOnExit> <CardContent> <Typography paragraph>To a foodie, summer means one thing and one thing only – DRINKS!</Typography> <Typography paragraph> Yes people, we know it’s hot out there and the only way to quench your thirst is by guzzling down a bunch of ice-cold cocktails </Typography> <Typography paragraph> <h4>1.The Bar Room at The Beekman</h4> Visit the beautiful Bar Room in the historic Beekman Hotel for high-key romance that really wows. Do try the whiskey sour.One of the best drinks available. <h4>2.Dublin House</h4> You can never go wrong with Sláinte! Margarita,Pot O'Gold, & Irish Old Fashioned <h4>3.Russian Samovar</h4> Alpensahne,Amarula Cream Liqueur, Caribou,Feni </Typography> </CardContent> </Collapse> </Card> </Box> </> ); } export default Blogs;
解决方案
方法一:使用Flex布局(Box组件)
将所有卡片外层的Box包裹在一个父级Box中,通过Flex布局实现横向排列和自动换行:
- 新增父级
Box,设置display: 'flex'、flexWrap: 'wrap'实现换行,用gap控制卡片间距(替代原有的m={6}避免重复间距) - 调整每个卡片外层
Box的margin,避免间距叠加
修改后的核心代码:
return ( <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 6, p: 6 }}> <Box> <Card sx={{ maxWidth: 345 }}> {/* 卡片内容不变 */} </Card> </Box> <Box> <Card sx={{ maxWidth: 345 }}> {/* 卡片内容不变 */} </Card> </Box> </Box> );
方法二:使用Material UI Grid组件(推荐响应式场景)
Grid组件是Material UI专门用于布局的组件,支持响应式设计,能自动根据屏幕宽度调整列数:
- 导入
Grid组件:import Grid from '@mui/material/Grid'; - 使用
Grid container作为父容器,设置spacing控制间距 - 每个卡片放在
Grid item中,通过xs、sm、md等属性设置不同屏幕下的宽度(比如xs={12}手机端占满一行,sm={6}平板端一行2列,md={4}桌面端一行3列)
修改后的核心代码:
return ( <Grid container spacing={6} sx={{ p: 6 }}> <Grid item xs={12} sm={6} md={4}> <Card sx={{ maxWidth: 345 }}> {/* 卡片内容不变 */} </Card> </Grid> <Grid item xs={12} sm={6} md={4}> <Card sx={{ maxWidth: 345 }}> {/* 卡片内容不变 */} </Card> </Grid> </Grid> );
额外提示
当前代码中所有卡片共用同一个expanded状态,点击任意一个卡片的展开按钮会同时展开所有卡片。如果需要单独控制每个卡片的展开状态,可以将卡片封装成独立组件,每个组件维护自己的expanded状态。
内容的提问来源于stack exchange,提问作者codertraveller
相关产品推荐
相关产品推荐

